source: nrEngine/src/Kernel.cpp @ 27

Revision 27, 22.0 KB checked in by art, 12 years ago (diff)

nrScript: using of subscripts is now possible

Line 
1/***************************************************************************
2 *                                                                         *
3 *   (c) Art Tevs, MPI Informatik Saarbruecken                             *
4 *       mailto: <tevs@mpi-sb.mpg.de>                                      *
5 *                                                                         *
6 *   This program is free software; you can redistribute it and/or modify  *
7 *   it under the terms of the GNU General Public License as published by  *
8 *   the Free Software Foundation; either version 2 of the License, or     *
9 *   (at your option) any later version.                                   *
10 *                                                                         *
11 ***************************************************************************/
12
13
14#include "Kernel.h"
15#include "Profiler.h"
16#include "events/KernelTaskEvent.h"
17#include "EventManager.h"
18#include "StdHelpers.h"
19#include "Log.h"
20
21namespace nrEngine {
22
23        std::list< SharedPtr<ITask> >::iterator Kernel::_loopIterator;
24
25        //-------------------------------------------------------------------------
26        Kernel::Kernel(){
27                taskList.clear();
28                pausedTaskList.clear();
29                lastTaskID = 0;
30                bTaskStarted = false;
31                bInitializedRoot = false;
32                _bSystemTasksAccessable = false;
33                sendEvents(true);
34        }
35
36        //-------------------------------------------------------------------------
37        Kernel::~Kernel(){
38                StopExecution();
39
40                taskList.clear();
41                pausedTaskList.clear();
42
43                // Log that kernel is down
44                NR_Log(Log::LOG_KERNEL, "Kernel subsystem is down");
45        }
46
47        //-------------------------------------------------------------------------
48        void Kernel::lockSystemTasks()
49        {
50                _bSystemTasksAccessable = true;
51        }
52
53        //-------------------------------------------------------------------------
54        void Kernel::unlockSystemTasks()
55        {
56                _bSystemTasksAccessable = false;
57        }
58
59        //-------------------------------------------------------------------------
60        Result Kernel::OneTick()
61        {
62
63                // Profiling of the engine
64                _nrEngineProfile("Kernel::OneTick");
65
66                // start tasks if their are not started before
67                prepareRootTask();
68
69                // get iterator through our std::list
70                PipelineIterator it;
71
72                // iterate through all tasks and start them
73                for (it = taskList.begin(); it != taskList.end(); it++){
74                        if ((*it)->getTaskState() == TASK_STOPPED)
75                                _taskStart(*it);
76                }
77
78                // resetup to the beginning
79                it = taskList.begin();
80
81                // we go always from teh first element in the list, because it is
82                // the system root task
83                _loopStartCycle();
84                while (_loopGetNextTask(taskList.begin(), it, 0) == OK){
85                        SharedPtr<ITask>& t=(*it);
86
87                        if (t && !t->_taskCanKill){
88
89                                // if the task is running
90                                if (t->getTaskState() == TASK_RUNNING){
91
92                                        // do some profiling
93                                        char name[256];
94                                        sprintf(name, "%s::update", t->getTaskName());
95                                        _nrEngineProfile(name);
96
97                                        t->updateTask();
98
99                                        // check if the task should run only once
100                                        if (t->getTaskProperty() & TASK_RUN_ONCE)
101                                                RemoveTask(t->getTaskID());
102
103                                }
104                        }
105                }
106                _loopEndCycle();
107
108                PipelineIterator thisIt;
109                TaskId tempID;
110
111                //loop again to remove dead tasks
112                for( it = taskList.begin(); it != taskList.end();){
113
114                        SharedPtr<ITask> &t=(*it);
115                        bool killed = false;
116
117                        // kill task if we need this
118                        if(t && t->_taskCanKill){
119
120                                _taskStop(t);
121
122                                // remove the task
123                                tempID = t->getTaskID();
124                                NR_Log(Log::LOG_KERNEL, "Task (id=%d) removed", tempID);
125                                it = taskList.erase(it);
126                                killed = true;
127
128                        // check whenver order of the task was changed by outside
129                        }else if (t->_orderChanged){
130                                ChangeTaskOrder(t->getTaskID(), t->getTaskOrder());
131                        }
132
133                        if (!killed) it++;
134                }
135
136                // Now we yield the running thread, so that we get user friendly
137                // thread behaviour.
138                IThread::yield();
139
140                // return good result
141                return OK;
142        }
143
144
145        //-------------------------------------------------------------------------
146        void Kernel::prepareRootTask()
147        {
148                if (bInitializedRoot) return;
149                bInitializedRoot = true;
150
151                // get iterator through our std::list
152                PipelineIterator it;
153
154                NR_Log(Log::LOG_KERNEL, "Create a system root task in the kernel");
155
156                // firstly we add a dummy system task, which depends on all others.
157                // This task do nothing, but depends on the rest.
158                // This is needed to get all thing worked
159                mRootTask.reset(new EmptyTask());
160                mRootTask->setTaskName("KernelRoot");
161                mRootTask->setTaskType(TASK_SYSTEM);
162
163                // Add the task as system task to the kernel
164                lockSystemTasks();
165                        AddTask(mRootTask, ORDER_SYS_ROOT);
166                unlockSystemTasks();
167
168        }
169
170        //-------------------------------------------------------------------------
171        /*void Kernel::startTasks(){
172
173                NR_Log(Log::LOG_KERNEL, Log::LL_DEBUG, "Start all kernel tasks");
174
175                // start all tasks, which are not running at now
176                for(it = taskList.begin(); it != taskList.end(); it++){
177                        _taskStart(*it);
178                }
179
180                bTaskStarted = true;
181        }
182        */
183
184        //-------------------------------------------------------------------------
185        Result Kernel::_taskStart(SharedPtr<ITask>& task)
186        {
187
188                // no task given, so return error
189                if (!task)
190                        return KERNEL_NO_TASK_FOUND;
191
192                // check if the task is not a thread
193                if (task->getTaskProperty() & TASK_IS_THREAD){
194
195                        SharedPtr<IThread> thread = boost::dynamic_pointer_cast<IThread, ITask>(task);
196                        thread->threadStart();
197                        task->setTaskState(TASK_RUNNING);
198                        task->onStartTask();
199
200                }else{
201
202                        // check for the task states
203                        if (task->getTaskState() == TASK_STOPPED)
204                        {
205                                task->setTaskState(TASK_RUNNING);
206                                task->onStartTask();
207                        }else if (task->getTaskState() == TASK_PAUSED){
208                                return ResumeTask(task->getTaskID());
209                        }
210
211                }
212
213                // send a message about current task state
214                if (bSendEvents){
215                        SharedPtr<Event> msg(new KernelStartTaskEvent(task->getTaskName(), task->getTaskID()));
216                        Engine::sEventManager()->emitSystem(msg);
217                }
218
219                // OK
220                return OK;
221        }
222
223        //-------------------------------------------------------------------------
224        Result Kernel::_taskStop(SharedPtr<ITask>& task)
225        {
226                try{
227                        // no task given, so return error
228                        if (!task)
229                                return KERNEL_NO_TASK_FOUND;
230
231                        // check if the task is not a thread
232                        if (task->getTaskProperty() & TASK_IS_THREAD){
233
234                                SharedPtr<IThread> thread = boost::dynamic_pointer_cast<IThread, ITask>(task);
235                                NR_Log(Log::LOG_KERNEL, "Stop thread/task \"%s\" (id=%d)", task->getTaskName(), task->getTaskID());
236                                thread->threadStop();
237
238                        }else{
239                                // stop the task
240                                NR_Log(Log::LOG_KERNEL, "Stop task \"%s\" (id=%d)",task->getTaskName(), task->getTaskID());
241                                task->stopTask();
242                        }
243
244                } catch (...){
245                        return UNKNOWN_ERROR;
246                }
247
248                // send a message about current task state
249                if (bSendEvents){
250                        SharedPtr<Event> msg(new KernelStopTaskEvent(task->getTaskName(), task->getTaskID()));
251                        Engine::sEventManager()->emitSystem(msg);
252                }
253
254
255                // OK
256                return OK;
257
258        }
259
260        //-------------------------------------------------------------------------
261        /*Result Kernel::StartTask(taskID id){
262
263                SharedPtr<ITask> task = getTaskByID(id);
264
265                if (!task) {
266                        NR_Log(Log::LOG_KERNEL, Log::LL_DEBUG, "Can not start task with id=%d, because such task does not exists", id);
267                        return KERNEL_NO_TASK_FOUND;
268                }
269
270                // check if the task is not a thread
271                return _taskStart(task);
272        }*/
273
274
275        //-------------------------------------------------------------------------
276        Result Kernel::Execute(){
277                try{
278
279                        // Log that kernel is initialized
280                        NR_Log(Log::LOG_KERNEL, "Kernel subsystem is active, start main loop");
281
282                        // loop while we have tasks in our pipeline
283                        while (taskList.size()){
284                                OneTick();
285                        }
286
287                        NR_Log(Log::LOG_KERNEL, "Stop kernel main loop");
288
289                } catch(...){
290                        return UNKNOWN_ERROR;
291                }
292
293                // ok
294                return OK;
295
296        }
297
298
299        //-------------------------------------------------------------------------
300        TaskId Kernel::AddTask (SharedPtr<ITask> t, TaskOrder order, TaskProperty proper){
301
302                prepareRootTask();
303
304                _nrEngineProfile("Kernel::AddTask");
305
306                try {
307
308                        t->_taskOrder = order;
309
310                        // check whenever such task already exists
311                        std::list< SharedPtr<ITask> >::iterator it;
312                        for (it = taskList.begin(); it != taskList.end(); it++){
313                                if ((*it) == t || (*it)->getTaskID() == t->getTaskID() || strcmp((*it)->getTaskName(),t->getTaskName())==0){
314                                        NR_Log(Log::LOG_KERNEL, "Cannot add task \"%s\" because same task was already added!", t->getTaskName());
315                                        return 0;
316                                }
317                        }
318
319                        for (it = pausedTaskList.begin(); it != pausedTaskList.end(); it++){
320                                if ((*it) == t || (*it)->getTaskID() == t->getTaskID() || strcmp((*it)->getTaskName(),t->getTaskName())==0){
321                                        NR_Log(Log::LOG_KERNEL, "Found same task in paused task std::list !");
322                                        return 0;
323                                }
324                        }
325
326                        // check if the given order number is valid
327                        if (t->getTaskOrder() <= ORDER_SYS_LAST && t->getTaskType() == TASK_USER)
328                        {
329                                NR_Log(Log::LOG_KERNEL, "User task are not allowed to work on system order numbers");
330                                return 0;
331                        }
332
333                        // setup some data
334                        t->setTaskProperty(proper);
335                        t->setTaskState(TASK_STOPPED);
336                        t->setTaskID(++lastTaskID);
337
338                        // some debug info
339                        if (proper & TASK_IS_THREAD)
340                                NR_Log(Log::LOG_KERNEL, "Add Task \"%s\" as thread (id = %d)", t->getTaskName(), t->getTaskID());
341                        else
342                                NR_Log(Log::LOG_KERNEL, "Add Task \"%s\" at order = %s (id = %d)", t->getTaskName(), orderToString(int32(t->getTaskOrder())).c_str(), t->getTaskID());
343
344                        // init task and check its return code
345                        if (t->onAddTask() != OK){
346                                NR_Log(Log::LOG_KERNEL, "Cannot initalize Task because of Task internal error");
347                                return 0;
348                        }
349
350                        // find the place for our task according to its order
351                        for( it=taskList.begin(); it != taskList.end(); it++){
352                                SharedPtr<ITask> &comp = (*it);
353                                if (comp->getTaskOrder() >= t->getTaskOrder()) break;
354                        }
355
356                        // add into the list
357                        taskList.insert (it,t);
358
359                } catch(...){
360                        return UNKNOWN_ERROR;
361                }
362
363                // if this is not a root task, then add dependency
364                // also there is no dependency if this is a thread
365                if (t->_taskOrder != ORDER_SYS_ROOT && !(t->getTaskProperty() & TASK_IS_THREAD))
366                        mRootTask->addTaskDependency(t);
367
368                // return the id
369                return t->getTaskID();
370        }
371
372
373        //-------------------------------------------------------------------------
374        Result Kernel::RemoveTask  (TaskId id){
375
376                if (id == 0) return OK;
377
378                try{
379
380                        NR_Log(Log::LOG_KERNEL, "Remove task with id=%d", id);
381
382                        // find the task
383                        PipelineIterator it;
384
385                        // check whenever iterator is valid
386                        if (!_getTaskByID(id, it, TL_RUNNING | TL_SLEEPING)){
387                                NR_Log(Log::LOG_KERNEL, "No such Task (id=%d) found !!!", id);
388                                return KERNEL_NO_TASK_FOUND;
389                        }
390
391                        // check whenever we are allowed to remove the task
392                        if (!areSystemTasksAccessable() && (*it)->getTaskType() == TASK_SYSTEM)
393                        {
394                                NR_Log(Log::LOG_KERNEL, Log::LL_WARNING, "You do not have rights to remove this task!");
395                                return KERNEL_NO_RIGHTS;
396
397                        }else{
398                                // say task want to remove his self
399                                NR_Log(Log::LOG_KERNEL, "Prepare to die: \"%s\" (id=%d)", (*it)->getTaskName(), (*it)->getTaskID());
400                                (*it)->_taskCanKill = true;
401                        }
402
403                } catch(...){
404                        return UNKNOWN_ERROR;
405                }
406
407                // OK
408                return OK;
409        }
410
411
412        //-------------------------------------------------------------------------
413        Result Kernel::SuspendTask  (TaskId id){
414
415                try{
416
417                        NR_Log(Log::LOG_KERNEL, "Suspend task (id=%d)", id);
418
419                        // find the task
420                        PipelineIterator it;
421
422                        // check whenever iterator is valid
423                        if (!_getTaskByID(id, it)){
424                                NR_Log(Log::LOG_KERNEL, "No task with id=%d found", id);
425                                return KERNEL_NO_TASK_FOUND;
426                        }else{
427                                SharedPtr<ITask> &t = (*it);
428
429                                if (!areSystemTasksAccessable() && (*it)->getTaskType() == TASK_SYSTEM){
430                                        NR_Log(Log::LOG_KERNEL, Log::LL_WARNING, "You do not have rights to suspend this task!");
431                                        return KERNEL_NO_RIGHTS;
432                                }else{
433
434                                        // suspend task
435                                        Result res = t->onSuspendTask();
436                                        if (res == OK){
437                                                t->setTaskState(TASK_PAUSED);
438
439                                                // before removing the task from task std::list move it to paused std::list
440                                                // so we can guarantee that task object will be held in memory
441                                                pausedTaskList.push_back(t);
442                                                taskList.erase(it);
443                                                NR_Log(Log::LOG_KERNEL, "Task id=%d is sleeping now", id);
444
445                                                // send a message about current task state
446                                                if (bSendEvents){
447                                                        SharedPtr<Event> msg(new KernelSuspendTaskEvent(t->getTaskName(), t->getTaskID()));
448                                                        Engine::sEventManager()->emitSystem(msg);
449                                                }
450
451                                        }else{
452                                                NR_Log(Log::LOG_KERNEL, Log::LL_WARNING, "Task id=%d can not suspend! Check this!", id);
453                                                return res;
454                                        }
455                                }
456                        }
457
458                } catch(...){
459                        return UNKNOWN_ERROR;
460                }
461
462                // OK
463                return OK;
464        }
465
466        //-------------------------------------------------------------------------
467        Result Kernel::ResumeTask  (TaskId id){
468
469                try{
470
471                        NR_Log(Log::LOG_KERNEL, "Resume task (id=%d)", id);
472
473                        // find the task
474                        PipelineIterator it;
475
476                        // check whenever iterator is valid
477                        if (!_getTaskByID(id, it, TL_SLEEPING)){
478                                NR_Log(Log::LOG_KERNEL, "No task with id=%d found", id);
479                                return KERNEL_NO_TASK_FOUND;
480                        }
481
482                        SharedPtr<ITask> &t = (*it);
483                        if (!areSystemTasksAccessable() && (*it)->getTaskType() == TASK_SYSTEM){
484                                NR_Log(Log::LOG_KERNEL, Log::LL_WARNING, "You do not have rights to resume this task!");
485                                return KERNEL_NO_RIGHTS;
486                        }else{
487
488                                // resume the task
489                                Result res = t->onResumeTask();
490                                if (res == OK){
491                                        t->setTaskState(TASK_RUNNING);
492
493                                        //keep the order of priorities straight
494                                        for( it = taskList.begin(); it != taskList.end(); it++){
495                                                SharedPtr<ITask> &comp=(*it);
496                                                if(comp->getTaskOrder() >= t->getTaskOrder()) break;
497                                        }
498                                        taskList.insert(it,t);
499
500                                        // erase task from paused std::list. Therefor we have to find it in the std::list
501                                        if (_getTaskByID(id, it, TL_SLEEPING)){
502                                                pausedTaskList.erase(it);
503                                        }
504
505                                        // send a message about current task state
506                                        if (bSendEvents){
507                                                SharedPtr<Event> msg(new KernelResumeTaskEvent(t->getTaskName(), t->getTaskID()));
508                                                Engine::sEventManager()->emitSystem(msg);
509                                        }
510
511                                }else{
512                                        NR_Log(Log::LOG_KERNEL, Log::LL_WARNING, "Task id=%d can not resume, so it stay in sleep mode", id);
513                                        return res;
514                                }
515                        }
516
517                } catch(...){
518                        return UNKNOWN_ERROR;
519                }
520
521                // OK
522                return OK;
523        }
524
525        //-------------------------------------------------------------------------
526        Result Kernel::StopExecution(){
527
528                try{
529
530                        NR_Log(Log::LOG_KERNEL, "Stop the kernel subsystem");
531
532                        // iterate through all tasks and kill them
533                        for(PipelineIterator it = taskList.begin(); it != taskList.end(); it++){
534                                NR_Log(Log::LOG_KERNEL, "Prepare to die: \"%s\" (id=%d)", (*it)->getTaskName(), (*it)->getTaskID());
535                                (*it)->_taskCanKill=true;
536                        }
537
538                        // iterate also through all paused tasks and kill them also
539                        for(PipelineIterator it = pausedTaskList.begin(); it != pausedTaskList.end(); it++){
540                                NR_Log(Log::LOG_KERNEL, "Prepare to die: \"%s\" (id=%d)", (*it)->getTaskName(), (*it)->getTaskID());
541                                (*it)->_taskCanKill=true;
542                        }
543
544                        // Info if we do not have any tasks to kill
545                        if (!taskList.size() && !pausedTaskList.size())
546                                NR_Log(Log::LOG_KERNEL, "There is no more tasks to be killed !");
547
548                } catch(...){
549                        return UNKNOWN_ERROR;
550                }
551
552                // OK
553                return OK;
554
555        }
556
557
558        //-------------------------------------------------------------------------
559        Result Kernel::ChangeTaskOrder(TaskId id, TaskOrder order){
560
561                try{
562
563                        NR_Log(Log::LOG_KERNEL, "Change order of task (id=%d) to %d", id, int32(order));
564
565                        // find the task
566                        PipelineIterator it;
567
568                        // check whenever iterator is valid
569                        if (!_getTaskByID(id, it, TL_RUNNING | TL_SLEEPING)){
570                                NR_Log(Log::LOG_KERNEL, "No task with id=%d found", id);
571                                return KERNEL_NO_TASK_FOUND;
572                        }
573
574                        SharedPtr<ITask> &t = (*it);
575
576                        // check if the given order number is valid
577                        if (order <= ORDER_SYS_LAST && t->getTaskType() == TASK_USER)
578                        {
579                                NR_Log(Log::LOG_KERNEL, "User task are not allowed to work on system order numbers!");
580                                return KERNEL_NO_RIGHTS;
581                        }
582
583                        // check for task access rights
584                        if (!areSystemTasksAccessable() && (*it)->getTaskType() == TASK_SYSTEM){
585                                NR_Log(Log::LOG_KERNEL, Log::LL_WARNING, "You do not have rights to change the order of system task!");
586                                return KERNEL_NO_RIGHTS;
587                        }else{
588
589                                // change order of the task
590                                t->setTaskOrder(order);
591                                t->_orderChanged = false;
592
593                                // sort lists
594                                pausedTaskList.sort();
595                                taskList.sort();
596                        }
597
598                } catch(...){
599                        return UNKNOWN_ERROR;
600                }
601
602                // OK
603                return OK;
604        }
605
606        //-------------------------------------------------------------------------
607        bool Kernel::_getTaskByID(TaskId id, PipelineIterator& jt, int32 useList){
608
609                // get std::list we want to search in
610                std::list< SharedPtr<ITask> > *li = NULL;
611
612                // search in normal list
613                if ((useList & TL_RUNNING) == TL_RUNNING){
614                        li = &taskList;
615
616                        // iterate through elements and search for task with same id
617                        PipelineIterator it;
618                        for ( it = li->begin(); it != li->end(); it++){
619                                if ((*it)->getTaskID() == id){
620                                        jt = it;
621                                        return true;
622                                }
623                        }
624                }
625
626                // search in paused list
627                if ((useList & TL_SLEEPING) == TL_SLEEPING){
628                        li = &pausedTaskList;
629
630                        // iterate through elements and search for task with same id
631                        PipelineIterator it;
632                        for ( it = li->begin(); it != li->end(); it++){
633                                if ((*it)->getTaskID() == id){
634                                        jt = it;
635                                        return true;
636                                }
637                        }
638
639                }
640
641                // not found so return an end iterator
642                return false;
643        }
644
645        //-------------------------------------------------------------------------
646        bool Kernel::_getTaskByName(const std::string& name, PipelineIterator& it, int32 useList){
647
648                // get std::list we want to search in
649                std::list< SharedPtr<ITask> > *li = NULL;
650
651                // search in normal list
652                if ((useList & TL_RUNNING) == TL_RUNNING){
653                        li = &taskList;
654
655                        // iterate through elements and search for task with same id
656                        PipelineIterator jt;
657                        for ( jt = li->begin(); jt != li->end(); jt++){
658                                if ((*jt)->getTaskName() == name){
659                                        it = jt;
660                                        return true;
661                                }
662                        }
663                }
664
665                // search in paused list
666                if ((useList & TL_SLEEPING) == TL_SLEEPING){
667                        li = &pausedTaskList;
668
669                        // iterate through elements and search for task with same id
670                        PipelineIterator jt;
671                        for ( jt = li->begin(); jt != li->end(); jt++){
672                                if ((*jt)->getTaskName() == name){
673                                        it = jt;
674                                        return true;
675                                }
676                        }
677                }
678
679                // not found so return end iterator
680                return false;
681        }
682
683        //-------------------------------------------------------------------------
684        SharedPtr<ITask> Kernel::getTaskByID(TaskId id){
685                try{
686
687                        // find the task
688                        PipelineIterator it;
689
690                        // check whenever iterator is valid
691                        if (!_getTaskByID(id, it, TL_RUNNING | TL_SLEEPING)){
692                                NR_Log(Log::LOG_KERNEL, "getTaskByID: No task with id=%d found", id);
693                                return SharedPtr<ITask>();
694                        }
695
696                        // check the rights
697                        if (!areSystemTasksAccessable() && (*it)->getTaskType() == TASK_SYSTEM){
698                                NR_Log(Log::LOG_KERNEL, Log::LL_WARNING, "You do not have rights to access to this task!");
699                                return SharedPtr<ITask>();
700                        }
701
702                        return *it;
703
704                } catch(...){
705                        return SharedPtr<ITask>();
706                }
707
708        }
709
710
711        //-------------------------------------------------------------------------
712        SharedPtr<ITask> Kernel::getTaskByName(const std::string& name){
713                try{
714
715                        // find the task
716                        PipelineIterator it;
717
718                        // check whenever iterator is valid
719                        if (!_getTaskByName(name, it, TL_RUNNING | TL_SLEEPING)){
720                                NR_Log(Log::LOG_KERNEL, "getTaskByName: No task with name=%s found", name.c_str());
721                                return SharedPtr<ITask>();
722                        }
723
724                        // check the rights
725                        if (!areSystemTasksAccessable() && (*it)->getTaskType() == TASK_SYSTEM){
726                                NR_Log(Log::LOG_KERNEL, Log::LL_WARNING, "You do not have rights to access to this task!");
727                                return SharedPtr<ITask>();
728                        }
729
730                        return *it;
731
732                } catch(...){
733                        return SharedPtr<ITask>();
734                }
735        }
736
737        //-------------------------------------------------------------------------
738        Result Kernel::_loopStartCycle()
739        {
740
741                // Profiling of the engine
742                _nrEngineProfile("Kernel::_loopStartCycle");
743
744                // iterate through the tasks and mark them as non visited
745                _loopIterator = taskList.begin();
746                while (_loopIterator != taskList.end())
747                {
748                        (*_loopIterator)->_taskGraphColor = 0;
749                        _loopIterator ++;
750                }
751
752                _loopIterator = pausedTaskList.begin();
753                while (_loopIterator != pausedTaskList.end())
754                {
755                        (*_loopIterator)->_taskGraphColor = 0;
756                        _loopIterator ++;
757                }
758
759
760                _loopIterator = taskList.begin();
761
762                return OK;
763        }
764
765        //-------------------------------------------------------------------------
766        Result Kernel::_loopGetNextTask(PipelineIterator it, PipelineIterator& result, int depth)
767        {
768                // Profiling of the engine
769                _nrEngineProfile("Kernel::_loopGetNextTask");
770
771                // check whenever this is the end
772                if (it == taskList.end()) return KERNEL_END_REACHED;
773
774                // get the task in this iterator
775                const SharedPtr<ITask>& t = *it;
776
777                if (t->_taskGraphColor == 1) return KERNEL_CIRCULAR_DEPENDENCY;
778                if (t->_taskGraphColor == 2) return KERNEL_END_REACHED;
779
780                t->_taskGraphColor = 1;
781
782                // now check if the task has got childrens
783                if (t->_taskDependencies.size() > 0)
784                {
785
786                        // do for each child call this function recursively
787                        /*for (uint32 i = 0; i < t->_taskDependencies.size(); i++)
788                        {
789                                PipelineIterator jt;
790                                if (!_getTaskByID(t->_taskDependencies[i], jt, TL_RUNNING | TL_SLEEPING)) return KERNEL_TASK_MISSING;
791
792                                // check whenever the child was already visited
793                                if ((*jt)->_taskGraphColor != 2){
794                                        Result ret = _loopGetNextTask(jt, result, depth+1);
795
796                                        // we return OK only if we have not found any circularity
797                                        // and we are on the top (root-node)
798                                        if (ret != OK){
799                                                t->_taskGraphColor = 0;
800                                                if (depth == 0 && ret != KERNEL_CIRCULAR_DEPENDENCY) return OK;
801                                                return ret;
802                                        }
803                                }
804                        }*/
805
806                        // iterate through all dependencies and check them
807                        std::list<SharedPtr<ITask> >::iterator jt = t->_taskDependencies.begin();
808                        for (; jt != t->_taskDependencies.end(); jt ++)
809                        {
810                                // check whenever the child was already visited
811                                if ((*jt)->_taskGraphColor != 2){
812                                        Result ret = _loopGetNextTask(jt, result, depth+1);
813
814                                        // we return OK only if we have not found any circularity
815                                        // and we are on the top (root-node)
816                                        if (ret != OK){
817                                                t->_taskGraphColor = 0;
818                                                if (depth == 0 && ret != KERNEL_CIRCULAR_DEPENDENCY) return OK;
819                                                return ret;
820                                        }
821                                }
822
823                        }
824
825                // we do not have childs, so this is a leaf node
826                }
827
828                // all our chlds are visited, so return the node itself
829                t->_taskGraphColor = 2;
830                result = it;
831                return KERNEL_LEAF_TASK;
832
833        }
834
835        //-------------------------------------------------------------------------
836        Result Kernel::_loopEndCycle()
837        {
838                return OK;
839        }
840
841}; //namespace nrEngine
842
Note: See TracBrowser for help on using the repository browser.