File indexing completed on 2024-04-28 16:24:34
0001 /* This file is part of the KDE project 0002 Copyright (C) 2009 Dag Andersen <danders@get2net.dk> 0003 0004 This library is free software; you can redistribute it and/or 0005 modify it under the terms of the GNU Library General Public 0006 License as published by the Free Software Foundation; either 0007 version 2 of the License, or (at your option) any later version. 0008 0009 This library is distributed in the hope that it will be useful, 0010 but WITHOUT ANY WARRANTY; without even the implied warranty of 0011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0012 Library General Public License for more details. 0013 0014 You should have received a copy of the GNU Library General Public License 0015 along with this library; see the file COPYING.LIB. If not, write to 0016 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 0017 Boston, MA 02110-1301, USA. 0018 */ 0019 0020 // clazy:excludeall=qstring-arg 0021 #include "kptbuiltinschedulerplugin.h" 0022 0023 #include "kptproject.h" 0024 #include "kptschedule.h" 0025 #include "kptxmlloaderobject.h" 0026 0027 #include <KLocalizedString> 0028 0029 namespace KPlato 0030 { 0031 0032 BuiltinSchedulerPlugin::BuiltinSchedulerPlugin(QObject *parent) 0033 : SchedulerPlugin(parent) 0034 { 0035 setName(i18nc("Network = task dependency network", "Network Scheduler")); 0036 setComment(xi18nc("@info:tooltip", "Built-in network (PERT) based scheduler")); 0037 } 0038 0039 BuiltinSchedulerPlugin::~BuiltinSchedulerPlugin() 0040 { 0041 } 0042 0043 QString BuiltinSchedulerPlugin::description() const 0044 { 0045 return xi18nc("@info:whatsthis", "<title>Network (PERT) Scheduler</title>" 0046 "<para>The network scheduler generally schedules tasks according to their dependencies." 0047 " When a task is scheduled it is scheduled in full, booking the allocated resources if available." 0048 " If overbooking is not allowed, subsequent tasks that requests the same resource" 0049 " will be scheduled later in time.</para>" 0050 "<para>Tasks with time constraints will be scheduled first to minimize the problem" 0051 " with resource conflicts</para>" 0052 "<para><note>This scheduler does not handle resource conflicts well." 0053 "<nl/>You can try a different scheduler if available." 0054 " You may also change resource allocations or add dummy dependencies to avoid the conflicts.</note></para>" 0055 ); 0056 } 0057 0058 void BuiltinSchedulerPlugin::calculate(Project &project, ScheduleManager *sm, bool nothread) 0059 { 0060 KPlatoScheduler *job = new KPlatoScheduler(&project, sm); 0061 m_jobs << job; 0062 connect(job, &SchedulerThread::jobStarted, this, &BuiltinSchedulerPlugin::slotStarted); 0063 connect(job, &SchedulerThread::jobFinished, this, &BuiltinSchedulerPlugin::slotFinished); 0064 0065 connect(this, &BuiltinSchedulerPlugin::sigCalculationStarted, &project, &Project::sigCalculationStarted); 0066 connect(this, &BuiltinSchedulerPlugin::sigCalculationFinished, &project, &Project::sigCalculationFinished); 0067 0068 sm->setScheduling(true); 0069 if (nothread) { 0070 connect(job, &SchedulerThread::maxProgressChanged, sm, &ScheduleManager::setMaxProgress); 0071 connect(job, &SchedulerThread::progressChanged, sm, &ScheduleManager::setProgress); 0072 job->doRun(); 0073 } else { 0074 job->start(); 0075 } 0076 m_synctimer.start(); 0077 } 0078 0079 void BuiltinSchedulerPlugin::slotStarted(SchedulerThread *job) 0080 { 0081 qDebug()<<"BuiltinSchedulerPlugin::slotStarted:"<<job->mainProject()<<job->mainManager(); 0082 0083 emit sigCalculationStarted(job->mainProject(), job->mainManager()); 0084 } 0085 0086 void BuiltinSchedulerPlugin::slotFinished(SchedulerThread *job) 0087 { 0088 ScheduleManager *sm = job->mainManager(); 0089 Project *mp = job->mainProject(); 0090 qDebug()<<"BuiltinSchedulerPlugin::slotFinished:"<<mp<<sm<<job->isStopped(); 0091 if (job->isStopped()) { 0092 sm->setCalculationResult(ScheduleManager::CalculationCanceled); 0093 } else { 0094 updateLog(job); 0095 Project *tp = static_cast<KPlatoScheduler*>(job)->project(); 0096 ScheduleManager *tm = static_cast<KPlatoScheduler*>(job)->manager(); 0097 updateProject(tp, tm, mp, sm); 0098 sm->setCalculationResult(ScheduleManager::CalculationDone); 0099 } 0100 sm->setScheduling(false); 0101 0102 m_jobs.removeAt(m_jobs.indexOf(job)); 0103 if (m_jobs.isEmpty()) { 0104 m_synctimer.stop(); 0105 } 0106 emit sigCalculationFinished(mp, sm); 0107 0108 disconnect(this, &BuiltinSchedulerPlugin::sigCalculationStarted, mp, &Project::sigCalculationStarted); 0109 disconnect(this, &BuiltinSchedulerPlugin::sigCalculationFinished, mp, &Project::sigCalculationFinished); 0110 0111 job->deleteLater(); 0112 qDebug()<<"BuiltinSchedulerPlugin::slotFinished: <<<"; 0113 } 0114 0115 0116 //-------------------- 0117 KPlatoScheduler::KPlatoScheduler(Project *project, ScheduleManager *sm, QObject *parent) 0118 : SchedulerThread(project, sm, parent) 0119 { 0120 qDebug()<<"KPlatoScheduler::KPlatoScheduler:"<<m_mainmanager<<m_mainmanager->name()<<m_mainmanagerId; 0121 } 0122 0123 KPlatoScheduler::~KPlatoScheduler() 0124 { 0125 qDebug()<<"KPlatoScheduler::~KPlatoScheduler:"<<QThread::currentThreadId(); 0126 } 0127 0128 void KPlatoScheduler::stopScheduling() 0129 { 0130 m_stopScheduling = true; 0131 if (m_project) { 0132 m_project->stopcalculation = true; 0133 } 0134 } 0135 0136 void KPlatoScheduler::run() 0137 { 0138 if (m_haltScheduling) { 0139 deleteLater(); 0140 return; 0141 } 0142 if (m_stopScheduling) { 0143 return; 0144 } 0145 { // mutex --> 0146 m_projectMutex.lock(); 0147 m_managerMutex.lock(); 0148 0149 m_project = new Project(); 0150 loadProject(m_project, m_pdoc); 0151 m_project->setName("Schedule: " + m_project->name()); //Debug 0152 0153 m_manager = m_project->scheduleManager(m_mainmanagerId); 0154 Q_ASSERT(m_manager); 0155 Q_ASSERT(m_manager->expected()); 0156 Q_ASSERT(m_manager != m_mainmanager); 0157 Q_ASSERT(m_manager->scheduleId() == m_mainmanager->scheduleId()); 0158 Q_ASSERT(m_manager->expected() != m_mainmanager->expected()); 0159 m_manager->setName("Schedule: " + m_manager->name()); //Debug 0160 0161 m_managerMutex.unlock(); 0162 m_projectMutex.unlock(); 0163 } // <--- mutex 0164 0165 connect(m_project, SIGNAL(maxProgress(int)), this, SLOT(setMaxProgress(int))); 0166 connect(m_project, SIGNAL(sigProgress(int)), this, SLOT(setProgress(int))); 0167 0168 bool x = connect(m_manager, SIGNAL(sigLogAdded(KPlato::Schedule::Log)), this, SLOT(slotAddLog(KPlato::Schedule::Log))); 0169 Q_ASSERT(x); Q_UNUSED(x); 0170 m_project->calculate(*m_manager); 0171 if (m_haltScheduling) { 0172 deleteLater(); 0173 } 0174 } 0175 0176 0177 } //namespace KPlato 0178