34 #include <QMutexLocker>    39                                         ArnScriptWatchdogThread* watchdogThread)
    41     _jobConfig      = jobConfig;
    42     _jobFactory     = jobFactory;
    43     _watchdogThread = watchdogThread;
    47 ArnScriptJobThread::~ArnScriptJobThread()
    55 void  ArnScriptJobThread::run()
    58     ArnScriptJobSingle  jobPreem( _jobConfig, _jobFactory, _watchdogThread);
    68                                         ArnScriptWatchdogThread* watchdogThread)
    70     _jobConfig      = jobConfig;
    71     _jobFactory     = jobFactory;
    72     _watchdogThread = watchdogThread;
    73     _scriptChanged  = 
false;
    79     connect( _jobConfig, SIGNAL(scriptChanged(
int)), 
this, SLOT(doScriptChanged(
int)), Qt::QueuedConnection);
    83 ArnScriptJobSingle::~ArnScriptJobSingle()
    88 void  ArnScriptJobSingle::newScriptJob()
    93         _watchdogThread->removeWatchdog( _job->watchdog());
    98     connect( _job, SIGNAL(errorText(QString)), _jobConfig, SIGNAL(errorText(QString)));
   100     _jobConfig->doSetupJob( _job, _jobFactory);
   101     connect( _job, SIGNAL(scheduleRequest(
int)),
   102              this, SLOT(doScheduleRequest(
int)), Qt::QueuedConnection);
   103     connect( _job, SIGNAL(quitRequest(
int)),
   104              this, SLOT(doQuitRequest(
int)));  
   106     _watchdogThread->addWatchdog( _job->watchdog());
   110 void  ArnScriptJobSingle::doScheduleRequest( 
int callerId)
   112     if ((_runningId != 0) && (callerId != 0) && (_runningId != callerId))  
return;
   115     if (_runningId != 0) {
   121     if (_job->isRunable()) {
   122         _runningId = _job->id();
   128 void  ArnScriptJobSingle::doQuitRequest( 
int callerId)
   132     if (_scriptChanged) {
   133         _scriptChanged = 
false;
   136         doScheduleRequest(0);
   141 void  ArnScriptJobSingle::doScriptChanged( 
int id)
   145     _scriptChanged = 
true;
   147     QMetaObject::invokeMethod( _job,
   149                                Qt::DirectConnection);
   156 #ifdef ARNUSE_SCRIPTJS   157 ArnScriptWatchdogRun::ArnScriptWatchdogRun( ArnScriptWatchdogThread& watchdogThread)
   159     _watchdogThread = &watchdogThread;
   163 ArnScriptWatchdogRun::~ArnScriptWatchdogRun()
   168 void  ArnScriptWatchdogRun::addWatchdog( ArnScriptWatchdog* watchdog)
   170     watchdog->setParent( 
this);
   175 void  ArnScriptWatchdogRun::removeWatchdog( ArnScriptWatchdog* watchdog)
   181 ArnScriptWatchdogThread::ArnScriptWatchdogThread( QObject* parent)
   187 ArnScriptWatchdogThread::~ArnScriptWatchdogThread()
   194 void  ArnScriptWatchdogThread::addWatchdog( ArnScriptWatchdog* watchdog)
   196     if (!watchdog)  
return;
   198     QMutexLocker mutexLocker( &_mutex);
   200     if (_wdTab.contains( watchdog))  
return;
   203     if (!_isReady)  
return;
   205     mutexLocker.unlock();
   207     addWatchdogNow( watchdog);
   212 void  ArnScriptWatchdogThread::addWatchdogNow( ArnScriptWatchdog* watchdog)
   214     watchdog->setParent( arnNullptr);
   215     watchdog->moveToThread( _watchdogRun->thread());
   217     QMetaObject::invokeMethod( _watchdogRun, [watchdog, 
this]() {
   218         _watchdogRun->addWatchdog( watchdog);
   219     }, Qt::QueuedConnection);
   224 void  ArnScriptWatchdogThread::removeWatchdog( ArnScriptWatchdog* watchdog)
   226     if (!watchdog)  
return;
   228     QMutexLocker mutexLocker( &_mutex);
   230     if (!_wdTab.contains( watchdog))  
return;
   231     _wdTab.removeAll( watchdog);
   233     if (!_isReady)  
return;
   235     mutexLocker.unlock();
   237     watchdog->setJsEngine( arnNullptr);
   238     QMetaObject::invokeMethod( _watchdogRun, [watchdog, 
this]() {
   239         _watchdogRun->removeWatchdog( watchdog);
   240     }, Qt::QueuedConnection);
   244 void  ArnScriptWatchdogThread::run()
   247     _watchdogRun = 
new ArnScriptWatchdogRun( *
this);
   249     QTimer::singleShot( 0, _watchdogRun, [
this]() {
   250         QMetaObject::invokeMethod( 
this, [
this]() {
   252         }, Qt::QueuedConnection);
   257     _watchdogRun = arnNullptr;
   261 void  ArnScriptWatchdogThread::postInit()
   265     foreach( ArnScriptWatchdog* watchdog, _wdTab) {
   266         addWatchdogNow( watchdog);
   277 ArnScriptWatchdogThread::ArnScriptWatchdogThread( QObject* parent)
   280     QTimer::singleShot( 0, 
this, SIGNAL(ready()));
   284 void  ArnScriptWatchdogThread::start()
   289 void  ArnScriptWatchdogThread::addWatchdog( ArnScriptWatchdog* watchdog)
   291     if (!watchdog)  
return;
   297 void  ArnScriptWatchdogThread::removeWatchdog( ArnScriptWatchdog* watchdog)
   313     _jobFactory     = arnNullptr;
   314     _watchdogThread = arnNullptr;
   320     if (!jobConfig)  
return;
   323     jobSlot.startPrio = prio;
   324     jobSlot.jobConfig = jobConfig;
   325     _idToSlot.insert( jobConfig->
id(), _jobSlots.size());
   326     _jobSlots += jobSlot;
   332     _jobFactory = jobFactory;
   338     _watchdogThread = 
new ArnScriptWatchdogThread( 
this);
   339     _watchdogThread->start();
   343         doCooperativeStart();
   353 void  ArnScriptJobs::doCooperativeStart()
   356     for (
int i = 0; i < _jobSlots.size(); ++i) {
   357         JobSlot&  jobSlot = _jobSlots[i];
   358         newScriptJob( jobSlot);
   360         connect( jobSlot.jobConfig, SIGNAL(scriptChanged(
int)), 
this, SLOT(setScriptChanged(
int)));
   362     doScheduleRequest(0);
   366 void  ArnScriptJobs::doPreemtiveStart()
   368     connect( _watchdogThread, SIGNAL(ready()), 
this, SLOT(doPreemtiveStartNow()));
   373 void  ArnScriptJobs::doPreemtiveStartNow()
   375     for (
int i = 0; i < _jobSlots.size(); ++i) {
   376         JobSlot&  jobSlot = _jobSlots[i];
   377         jobSlot.thread = 
new ArnScriptJobThread( jobSlot.jobConfig, _jobFactory, _watchdogThread);
   378         jobSlot.thread->start();  
   384 void  ArnScriptJobs::doScheduleRequest( 
int callerId)
   387     if ((_runningId != 0) && (callerId != 0) && (_runningId != callerId))  
return;
   390     if (_runningId != 0) {
   392         JobSlot&  jobSlot = _jobSlots[ _runningIndex];
   393         jobSlot.job->leaveScript();
   395         for (
int i = 0; i < _jobSlots.size(); ++i) {  
   396             if (_jobSlots.at(i).curPrio > -100)
   397                 _jobSlots[i].curPrio -= 100 / _jobSlots[i].startPrio;  
   400         jobSlot.curPrio = 10000;  
   407     for (
int i = 0; i < _jobSlots.size(); ++i) {
   408         JobSlot&  jobSlot = _jobSlots[i];
   409         if (jobSlot.scriptChanged) {
   410             QMetaObject::invokeMethod( jobSlot.job,
   412                                        Qt::DirectConnection);
   413             jobSlot.scriptChanged = 
false;
   414             newScriptJob( jobSlot);
   420     int  hiPrioIndex = -1;  
   421     for (
int i = 0; i < _jobSlots.size(); ++i) {
   422         JobSlot&  jobSlot = _jobSlots[i];
   423         if ((jobSlot.job->isRunable()) && (jobSlot.curPrio < hiPrio)) {
   424             hiPrio = jobSlot.curPrio;  
   428     if (hiPrioIndex >= 0) {  
   429         _runningIndex = hiPrioIndex;
   430         JobSlot&  jobSlot = _jobSlots[ _runningIndex];
   431         _runningId = jobSlot.job->id();
   434         jobSlot.job->enterScript();
   440 void  ArnScriptJobs::newScriptJob( JobSlot& jobSlot)
   443         _watchdogThread->removeWatchdog( jobSlot.job->watchdog());
   446     jobSlot.job = 
new ArnScriptJob( jobSlot.jobConfig->id(), 
this);
   447     connect( jobSlot.job, SIGNAL(errorText(QString)), jobSlot.jobConfig, SIGNAL(errorText(QString)));
   449     jobSlot.jobConfig->doSetupJob( jobSlot.job, _jobFactory);
   450     connect( jobSlot.job, SIGNAL(scheduleRequest(
int)),
   451              this, SLOT(doScheduleRequest(
int)), Qt::QueuedConnection);
   453     _watchdogThread->addWatchdog( jobSlot.job->watchdog());
   458 void  ArnScriptJobs::setScriptChanged( 
int id)
   460     int i = _idToSlot.value( 
id, -1);
   463     _jobSlots[i].scriptChanged = 
true;
   465     if (_runningId == 0) {  
   466         doScheduleRequest( 0);
 ArnScriptJobs(QObject *parent=arnNullptr)
 
void setFactory(ArnScriptJobFactory *jobFactory)
 
Must be thread-safe as subclassed. 
 
Is thread-safe (except doSetupJob) 
 
Interface class to be normally used, is also Script Job interface. 
 
void setWatchDogTime(int time)
 
void addJob(ArnScriptJobControl *jobConfig, int prio=1)
 
void start(Type type=Type::Cooperative)