2
0

ExecutionModule.cpp 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274
  1. #include "ExecutionModule.h"
  2. ExecutionModule::ExecutionModule() : startFrame(_FL_),
  3. endFrame(_FL_),
  4. groups(_FL_)
  5. {
  6. accessor = null;
  7. currentGroup = -1;
  8. currentObject = -1;
  9. }
  10. ExecutionModule::~ExecutionModule()
  11. {
  12. for(long i = 0; i < groups; i++)
  13. {
  14. delete groups[i];
  15. }
  16. startFrame.Empty();
  17. endFrame.Empty();
  18. groups.Empty();
  19. }
  20. void ExecutionModule::SetAccessor(RegistryKeyAccessor * _accessor)
  21. {
  22. accessor = _accessor;
  23. }
  24. //Установить уровень исполнения перед началом кадра
  25. void ExecutionModule::SetStartFrameLevel(Service * s, dword level)
  26. {
  27. SetServiceLevel(startFrame, s, level);
  28. }
  29. //Установить уровень исполнения после кадра
  30. void ExecutionModule::SetEndFrameLevel(Service * s, dword level)
  31. {
  32. SetServiceLevel(endFrame, s, level);
  33. }
  34. //Установить функцию объекта на исполнение
  35. void ExecutionModule::SetObjectExecution(RegObject * obj, const char * group, dword level, ObjectExecution func)
  36. {
  37. if(!obj || !func) return;
  38. //Отметим что объект имел дело с модулем исполнения
  39. accessor->SetExecuteFlag(obj);
  40. //Индекс группы
  41. long i = FindGroup(group);
  42. if(i < 0)
  43. {
  44. SetGroupLevel(group, Core_DefaultExecuteLevel);
  45. i = FindGroup(group);
  46. Assert(i >= 0);
  47. }
  48. //Если есть запись об функции, переместим её
  49. array<GroupElement> & elements = groups[i]->elements;
  50. for(long j = 0; j < elements; j++)
  51. {
  52. GroupElement & ge = elements[j];
  53. if(ge.func == func && ge.object == obj)
  54. {
  55. if(elements[j].level == level)
  56. {
  57. return; //Всё уже так как хочет пользователь...
  58. }
  59. //Удалим запись
  60. elements.Extract(j);
  61. break;
  62. }
  63. }
  64. //Добавляем запись на нужный уровень
  65. GroupElement ge;
  66. ge.object = obj;
  67. ge.level = level;
  68. ge.func = func;
  69. for(long j = 0; j < elements; j++)
  70. {
  71. if(elements[j].level > level)
  72. {
  73. elements.Insert(ge, j);
  74. return;
  75. }
  76. }
  77. elements.Add(ge);
  78. }
  79. //Удалить обработчик
  80. void ExecutionModule::DelObjectExecution(RegObject * obj, ObjectExecution func)
  81. {
  82. if(!obj || !func) return;
  83. Assert(accessor->IsValidate(obj));
  84. if(!accessor->GetExecuteFlag(obj)) return;
  85. //Проходим по всем группам
  86. for(long i = 0; i < groups; i++)
  87. {
  88. array<GroupElement> & elements = groups[i]->elements;
  89. for(long j = 0; j < elements; j++)
  90. {
  91. GroupElement & ge = elements[j];
  92. if(ge.func == func && ge.object == obj)
  93. {
  94. if(currentGroup == i && currentObject == j)
  95. {
  96. currentObject--;
  97. }
  98. elements.Extract(j);
  99. break;
  100. }
  101. }
  102. }
  103. }
  104. //Удалить все обработчики данного объекта из группы
  105. void ExecutionModule::DelObjectExecutions(RegObject * obj, const char * group)
  106. {
  107. if(!obj) return;
  108. Assert(accessor->IsValidate(obj));
  109. if(!accessor->GetExecuteFlag(obj)) return;
  110. long i = FindGroup(group);
  111. if(i < 0) return;
  112. array<GroupElement> & elements = groups[i]->elements;
  113. for(long j = 0; j < elements; j++)
  114. {
  115. if(elements[j].object == obj)
  116. {
  117. elements.Extract(j--);
  118. }
  119. }
  120. }
  121. //Удалить все обработчики данного объекта
  122. void ExecutionModule::DelObjectExecutions(RegObject * obj)
  123. {
  124. if(!obj) return;
  125. Assert(accessor->IsValidate(obj));
  126. if(!accessor->GetExecuteFlag(obj)) return;
  127. for(long i = 0; i < groups; i++)
  128. {
  129. array<GroupElement> & elements = groups[i]->elements;
  130. for(long j = 0; j < elements; j++)
  131. {
  132. if(elements[j].object == obj)
  133. {
  134. elements.Extract(j--);
  135. }
  136. }
  137. }
  138. }
  139. //Установить уровень исполнения группы
  140. void ExecutionModule::SetGroupLevel(const char * group, dword level)
  141. {
  142. Group * grp = null;
  143. long i = FindGroup(group);
  144. if(i >= 0)
  145. {
  146. grp = groups[i];
  147. if(grp->level == level)
  148. {
  149. return;
  150. }
  151. groups.Extract(i);
  152. grp->level = level;
  153. }else{
  154. grp = NEW Group();
  155. grp->name = group;
  156. grp->name.Lower();
  157. grp->level = level;
  158. grp->timeScale = 1.0f;
  159. }
  160. for(long i = 0; i < groups; i++)
  161. {
  162. if(groups[i]->level > level)
  163. {
  164. groups.Insert(grp, i);
  165. return;
  166. }
  167. }
  168. groups.Add(grp);
  169. }
  170. //Получить уровень исполнения группы
  171. dword ExecutionModule::GetGroupLevel(const char * group)
  172. {
  173. long i = FindGroup(group);
  174. if(i < 0) return Core_DefaultExecuteLevel;
  175. return groups[i]->level;
  176. }
  177. //Установить масштаб времени для группы
  178. void ExecutionModule::SetGroupTimeScale(float scale, const char * group)
  179. {
  180. long i = FindGroup(group);
  181. if(i >= 0)
  182. {
  183. groups[i]->timeScale = scale;
  184. }
  185. }
  186. //Получить масштаб времени для группы
  187. float ExecutionModule::GetGroupTimeScale(const char * group)
  188. {
  189. long i = FindGroup(group);
  190. if(i < 0) return 1.0f;
  191. return groups[i]->timeScale;
  192. }
  193. //Исполнить все сервисы и установленные на исполнение объекты
  194. void ExecutionModule::Execute(float dltTime)
  195. {
  196. //Исполняем сервисы перед началом кадра
  197. for(long i = 0; i < startFrame; i++)
  198. {
  199. startFrame[i].s->StartFrame(dltTime);
  200. }
  201. //Исполняем группы
  202. for(currentGroup = 0; currentGroup < groups; currentGroup++)
  203. {
  204. array<GroupElement> & elements = groups[currentGroup]->elements;
  205. float dTime = dltTime*groups[currentGroup]->timeScale;
  206. if(dTime > (float)Core_MaxDltTime) dTime = (float)Core_MaxDltTime;
  207. for(currentObject = 0; currentObject < elements; currentObject++)
  208. {
  209. GroupElement & ge = elements[currentObject];
  210. (ge.object->*ge.func)(dTime);
  211. }
  212. }
  213. //Исполняем сервесы после кадра
  214. for(long i = 0; i < endFrame; i++)
  215. {
  216. endFrame[i].s->EndFrame(dltTime);
  217. }
  218. }
  219. //Найти индекс группы по имени
  220. long ExecutionModule::FindGroup(const char * name)
  221. {
  222. if(!name) name = "";
  223. for(long i = 0; i < groups; i++)
  224. {
  225. if(string::IsEqual(groups[i]->name.GetBuffer(), name)) return i;
  226. }
  227. return -1;
  228. }
  229. //Установить уровень исполнения сервиса
  230. void ExecutionModule::SetServiceLevel(array<ServiceExecute> & list, Service * s, dword level)
  231. {
  232. Assert(accessor->GetRegistryFlag(s));
  233. Assert(accessor->GetServiceFlag(s));
  234. for(long i = 0; i < list; i++)
  235. {
  236. if(list[i].s == s)
  237. {
  238. if(list[i].level == level) return;
  239. list.Extract(i);
  240. }
  241. }
  242. ServiceExecute se;
  243. se.s = s;
  244. se.level = level;
  245. for(long i = 0; i < list; i++)
  246. {
  247. if(list[i].level > level)
  248. {
  249. list.Insert(se, i);
  250. return;
  251. }
  252. }
  253. list.Add(se);
  254. }