* Don't sleep for negative amounts (overflows to very large sleep delays :-)
[matthijs/ABM2.git] / ABM2 / Engine / Kernel.cpp
1 // Kernel.cpp: implementation of the CKernel class.\r
2 //\r
3 //////////////////////////////////////////////////////////////////////\r
4 \r
5 #include "engine.h"\r
6 #include "Kernel.h"\r
7 \r
8 //////////////////////////////////////////////////////////////////////\r
9 // Construction/Destruction\r
10 //////////////////////////////////////////////////////////////////////\r
11 \r
12 CKernel::CKernel()\r
13 {\r
14 //      SDL_Init(0);\r
15         //SDLNet_Init();\r
16 }\r
17 \r
18 CKernel::~CKernel()\r
19 {\r
20         \r
21 \r
22         //SDLNet_Quit();\r
23 //      SDL_Quit();\r
24 }\r
25 \r
26 int CKernel::Execute()\r
27 {\r
28 #ifdef WIN32\r
29     MSG msg;\r
30 #endif // WIN32\r
31 \r
32         while(taskList.size())\r
33         {\r
34                 {\r
35                         PROFILE("Kernel task loop");\r
36 \r
37                         DWORD starting_point = GetTickCount();\r
38 \r
39 #ifdef WIN32\r
40         if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))\r
41         {\r
42             TranslateMessage(&msg);\r
43             DispatchMessage(&msg);\r
44         }\r
45 #endif // WIN32\r
46 \r
47 \r
48                         std::list< CMMPointer<ITask> >::iterator it, thisIt;\r
49                         for(it=taskList.begin();it!=taskList.end();)\r
50                         {\r
51                                 ITask *t=(*it);\r
52                                 it++;\r
53                                 if(!t->canKill)t->Update();\r
54                         }\r
55                         //loop again to remove dead tasks\r
56                         for(it=taskList.begin();it!=taskList.end();)\r
57                         {\r
58                                 ITask *t=(*it);\r
59                                 thisIt=it; it++;\r
60                                 if(t->canKill)\r
61                                 {\r
62                                         t->Stop();\r
63                                         // 25-07-03 - updated this to use erase() rather than remove()\r
64                                         taskList.erase(thisIt);\r
65                                         t=0;\r
66                                 }\r
67                         }\r
68                         IMMObject::CollectGarbage();\r
69                         DWORD end_point = GetTickCount();\r
70                         /* Sleep if we didn't use up too much time already */\r
71                         if (starting_point + 50 > end_point)\r
72                                 Sleep(50 - (end_point-starting_point));\r
73                 }\r
74 #ifdef _DEBUG\r
75                 CProfileSample::Output();\r
76 #endif\r
77         }\r
78 \r
79         return 0;\r
80 }\r
81 \r
82 bool CKernel::AddTask(const CMMPointer<ITask> &t)\r
83 {\r
84         if(!t->Start())return false;\r
85 \r
86         //keep the order of priorities straight\r
87         std::list< CMMPointer<ITask> >::iterator it;\r
88         for(it=taskList.begin();it!=taskList.end();it++)\r
89         {\r
90                 CMMPointer<ITask> &comp=(*it);\r
91                 if(comp->priority>t->priority)break;\r
92         }\r
93         taskList.insert(it,t);\r
94         return true;\r
95 }\r
96 \r
97 void CKernel::SuspendTask(const CMMPointer<ITask> &t)\r
98 {\r
99         //check that this task is in our list - we don't want to suspend a task that isn't running\r
100         if(std::find(taskList.begin(),taskList.end(),t)!=taskList.end())\r
101         {\r
102                 t->OnSuspend();\r
103                 taskList.remove(t);\r
104                 pausedTaskList.push_back(t);\r
105         }\r
106 }\r
107 \r
108 void CKernel::ResumeTask(const CMMPointer<ITask> &t)\r
109 {\r
110         if(std::find(pausedTaskList.begin(),pausedTaskList.end(),t)!=pausedTaskList.end())\r
111         {\r
112                 t->OnResume();\r
113                 pausedTaskList.remove(t);\r
114                 //keep the order of priorities straight\r
115                 std::list< CMMPointer<ITask> >::iterator it;\r
116                 for(it=taskList.begin();it!=taskList.end();it++)\r
117                 {\r
118                         CMMPointer<ITask> &comp=(*it);\r
119                         if(comp->priority>t->priority)break;\r
120                 }\r
121                 taskList.insert(it,t);\r
122         }\r
123 }\r
124 \r
125 void CKernel::RemoveTask(const CMMPointer<ITask> &t)\r
126 {\r
127         if(std::find(taskList.begin(),taskList.end(),t)!=taskList.end())\r
128         {\r
129                 t->canKill=true;\r
130         }\r
131 }\r
132 \r
133 void CKernel::KillAllTasks()\r
134 {\r
135         for(std::list< CMMPointer<ITask> >::iterator it=taskList.begin();it!=taskList.end();it++)\r
136         {\r
137                 (*it)->canKill=true;\r
138         }\r
139 }\r