Core.cpp 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866
  1. #include "core.h"
  2. #include "MemoryManager.h"
  3. #include <time.h>
  4. extern MemoryManager memoryManager;
  5. extern bool core_isEnableTrace;
  6. Core::Core(const char * coreModuleNameForSkip) : dlls(coreModuleNameForSkip),
  7. messages(_FL_, 4096),
  8. messagesInfo(_FL_),
  9. errors(_FL_)
  10. {
  11. //Идентификатор основного потока
  12. threadId = ::GetCurrentThreadId();
  13. //Определяем режим для поточности
  14. #ifndef _XBOX
  15. DWORD m1 = 0, m2 = 0;
  16. GetProcessAffinityMask(GetCurrentProcess(), &m1, &m2);
  17. for(long m = 1, count = 0; m; m <<= 1)
  18. {
  19. if(m1 & m)
  20. {
  21. count++;
  22. }
  23. }
  24. if(count <= 1)
  25. {
  26. mtmode = mt_none;
  27. }else
  28. if(count < 4)
  29. {
  30. mtmode = mt_core_2;
  31. }else
  32. if(count == 4)
  33. {
  34. mtmode = mt_core_4;
  35. }else{
  36. mtmode = mt_core_more;
  37. }
  38. #else
  39. mtmode = mt_core_more;
  40. // memoryManager.TraceStatistic(CoreCommand_MemStat(cmemstat_onlytotal));
  41. #endif
  42. #ifndef STOP_DEBUG
  43. //Инициализируем флаг watchdog
  44. memset(watchDogBuffer, 0, sizeof(watchDogBuffer));
  45. watchDogPtr = (dword *)AlignPtr(watchDogBuffer, 0xf);
  46. #endif
  47. //Аксессор
  48. decls.SetAccessor(&accsessor);
  49. execution.SetAccessor(&accsessor);
  50. //Начинаем базу декларированных объектов
  51. decls.AddDecls(StormEngine_Declarator::GetFirst());
  52. decls.BuildHashTable();
  53. //Таймер
  54. SetState(corestate_lorestimer, false);
  55. //Флаг выхода
  56. isExit = false;
  57. //Различные переменные, сообщающие о параметрах запуска
  58. #ifdef _XBOX
  59. Storage().SetString("runtime.platform", "X360");
  60. #else
  61. Storage().SetString("runtime.platform", "WIN32");
  62. #endif
  63. Storage().SetString("system.core.id", "Storm engine v3.0");
  64. char tmpbuf[128];
  65. crt_snprintf(tmpbuf, sizeof(tmpbuf), "%s, %s", __DATE__, __TIME__);
  66. Storage().SetString("system.core.build", tmpbuf);
  67. __time64_t ltime;
  68. _time64(&ltime);
  69. struct tm today;
  70. srand(((long)ltime & 0xfffff000) | rand());
  71. crt_localtime64(&today, &ltime);
  72. strftime(tmpbuf, sizeof(tmpbuf), "%d %B %Y, %H:%M:%S", &today);
  73. Storage().SetString("system.core.starttime", tmpbuf);
  74. dlls.PutInfoToStorage(Storage());
  75. dltTime = 0.0f;
  76. fixedDltTime = 0.01f;
  77. scaleDltTime = 0.0f;
  78. timeScale = 1.0f;
  79. fps = 0.0f;
  80. fpsTime = 0.0f;
  81. frames = 0;
  82. isFixedDltTime = false;
  83. fixedFPS = 0;
  84. fixedFPSDltTime = 0.0f;
  85. for(long i = 0; i < ARRSIZE(errorsEntry); i++)
  86. {
  87. errorsEntry[i] = -1;
  88. }
  89. isActive = true;
  90. }
  91. Core::~Core()
  92. {
  93. decls.Release();
  94. statesBase.ForceRelease();
  95. dlls.Unload();
  96. }
  97. //Загрузить модули быстрого старта
  98. bool Core::LoadQuickStartModules(const char * quickModules)
  99. {
  100. if(!dlls.LoadQuickModules(quickModules))
  101. {
  102. return false;
  103. }
  104. for(long i = 0; i < dlls.GetCount(); i++)
  105. {
  106. decls.AddDecls(dlls.GetFirst(i));
  107. }
  108. decls.BuildHashTable();
  109. return true;
  110. }
  111. //Загрузить модули невошедшие в список быстрого старта
  112. void Core::LoadModules()
  113. {
  114. dlls.LoadModules();
  115. for(long i = 0; i < dlls.GetCount(); i++)
  116. {
  117. decls.AddDecls(dlls.GetFirst(i));
  118. }
  119. decls.BuildHashTable();
  120. }
  121. //------------------------------------------------------------------------------------------------
  122. //Main functions
  123. //------------------------------------------------------------------------------------------------
  124. //Создать сервис
  125. Service * Core::GetService(const char * service_name)
  126. {
  127. AssertCoreThread
  128. return (Service *)decls.CreateObject(service_name, false);
  129. }
  130. //Установить уровень исполнения перед началом кадра
  131. void Core::SetStartFrameLevel(Service * s, dword level)
  132. {
  133. AssertCoreThread
  134. execution.SetStartFrameLevel(s, level);
  135. }
  136. //Установить уровень исполнения после кадра
  137. void Core::SetEndFrameLevel(Service * s, dword level)
  138. {
  139. AssertCoreThread
  140. execution.SetEndFrameLevel(s, level);
  141. }
  142. //Создать зарегестрированный объект
  143. RegObject * Core::CreateObject(const char * className)
  144. {
  145. AssertCoreThread
  146. return decls.CreateObject(className, false);
  147. }
  148. //Установить функцию объекта на исполнение
  149. void Core::SetObjectExecutionFunc(RegObject * obj, const char * group, dword level, ObjectExecution func)
  150. {
  151. AssertCoreThread
  152. execution.SetObjectExecution(obj, group, level, func);
  153. }
  154. //Удалить обработчик
  155. void Core::DelObjectExecutionFunc(RegObject * obj, ObjectExecution func)
  156. {
  157. AssertCoreThread
  158. execution.DelObjectExecution(obj, func);
  159. }
  160. //Удалить все обработчики данного объекта из группы
  161. void Core::DelObjectExecutions(RegObject * obj, const char * group)
  162. {
  163. AssertCoreThread
  164. execution.DelObjectExecutions(obj, group);
  165. }
  166. //Удалить все обработчики данного объекта
  167. void Core::DelObjectExecutions(RegObject * obj)
  168. {
  169. AssertCoreThread
  170. execution.DelObjectExecutions(obj);
  171. }
  172. //Установить уровень исполнения группы
  173. void Core::SetGroupLevel(const char * group, dword level)
  174. {
  175. AssertCoreThread
  176. execution.SetGroupLevel(group, level);
  177. }
  178. //Получить уровень исполнения группы
  179. dword Core::GetGroupLevel(const char * group)
  180. {
  181. AssertCoreThread
  182. return execution.GetGroupLevel(group);
  183. }
  184. //Проверить на валидность указатель объекта
  185. bool Core::IsValidateRegObject(RegObject * obj, long * cacheValue)
  186. {
  187. //Будет сделано в случае необходимости
  188. Assert(false);
  189. return true;
  190. }
  191. //Найти первый объект по имени
  192. RegObject * Core::FindObject(const char * className)
  193. {
  194. AssertCoreThread
  195. ObjectsDeclarators::RegList * list = decls.Find(className);
  196. if(!list) return null;
  197. list->ToFirst();
  198. return list->Get();
  199. }
  200. //Найти все объекты по имени
  201. void Core::FindObject(const char * className, array<Object *> & objects)
  202. {
  203. AssertCoreThread
  204. objects.Empty();
  205. ObjectsDeclarators::RegList * list = decls.Find(className);
  206. if(!list) return;
  207. list->ToFirst();
  208. for(RegObject * obj = null; obj = list->Get(); list->Next())
  209. {
  210. objects.Add(obj);
  211. }
  212. }
  213. //Получить список всех зарегестрированных объектов
  214. void Core::GetRegistryObjectsList(array<string> & objects)
  215. {
  216. AssertCoreThread
  217. decls.GetRegistryObjectsList(objects);
  218. }
  219. //Получить доступ к корневой папке переменных ядра
  220. ICoreStorageFolder & Core::Storage()
  221. {
  222. return statesBase.Root();
  223. }
  224. //------------------------------------------------------------------------------------------------
  225. //Time functions
  226. //------------------------------------------------------------------------------------------------
  227. //Получить текущий временной промежуток
  228. float Core::GetDeltaTime()
  229. {
  230. return scaleDltTime;
  231. }
  232. //Получить текущий временной промежуток без учёта скалирования
  233. float Core::GetNoScaleDeltaTime()
  234. {
  235. return dltTime;
  236. }
  237. //Установить масштаб времени для всех
  238. void Core::SetTimeScale(float scale)
  239. {
  240. AssertCoreThread
  241. timeScale = scale;
  242. if(timeScale < 0.0f) timeScale = 0.0f;
  243. if(timeScale > 1000000.0f) timeScale = 1000000.0f;
  244. }
  245. //Получить масштаб времени для всех
  246. float Core::GetTimeScale()
  247. {
  248. return timeScale;
  249. }
  250. //Установить масштаб времени для группы
  251. void Core::SetTimeScale(float scale, const char * group)
  252. {
  253. AssertCoreThread
  254. if(timeScale < 0.0f) timeScale = 0.0f;
  255. if(timeScale > 1000000.0f) timeScale = 1000000.0f;
  256. execution.SetGroupTimeScale(scale, group);
  257. }
  258. //Получить масштаб времени для группы
  259. float Core::GetTimeScale(const char * group)
  260. {
  261. AssertCoreThread
  262. return execution.GetGroupTimeScale(group);
  263. }
  264. //Установить фиксированный временной отрезок
  265. void Core::SetFixedDeltaTime(float dltTime)
  266. {
  267. AssertCoreThread
  268. fixedDltTime = dltTime;
  269. }
  270. //Получить фиксированный временной отрезок
  271. float Core::GetFixedDeltaTime()
  272. {
  273. return fixedDltTime;
  274. }
  275. //Разрешить-запретить фиксированный временной отрезок
  276. void Core::EnableFixedDeltaTime(bool isEnable)
  277. {
  278. AssertCoreThread
  279. isFixedDltTime = isEnable;
  280. }
  281. //Фиксированный временной отрезок установлен или нет
  282. bool Core::IsFixedDeltaTime()
  283. {
  284. return isFixedDltTime;
  285. }
  286. //Получить текущую скорость в кадрах за секунду
  287. float Core::EngineFps()
  288. {
  289. return fps;
  290. }
  291. //------------------------------------------------------------------------------------------------
  292. //System
  293. //------------------------------------------------------------------------------------------------
  294. //Дать ядру команду
  295. void Core::ExecuteCoreCommand(CoreCommand & cmd)
  296. {
  297. static bool isAssertMemCheck = false;
  298. switch(cmd.commandID)
  299. {
  300. case ccid_assert_memcheck:
  301. if(!isAssertMemCheck)
  302. {
  303. {
  304. SingleClassThread
  305. isAssertMemCheck = true;
  306. }
  307. memoryManager.PanicCheckMemory();
  308. {
  309. SingleClassThread
  310. isAssertMemCheck = false;
  311. }
  312. }
  313. return;
  314. case ccid_setstate:
  315. AssertCoreThread
  316. SetState(((CoreCommand_StateOp &)cmd).state, ((CoreCommand_StateOp &)cmd).value);
  317. return;
  318. case ccid_getstate:
  319. AssertCoreThread
  320. ((CoreCommand_StateOp &)cmd).value = GetState(((CoreCommand_StateOp &)cmd).state);
  321. return;
  322. case ccid_memstatistic:
  323. memoryManager.TraceStatistic((CoreCommand_MemStat &)cmd);
  324. return;
  325. case ccid_memcheck:
  326. memoryManager.PanicCheckMemory();
  327. return;
  328. case ccid_getmemstatistic:
  329. memoryManager.GetStatistic((CoreCommand_GetMemStat &)cmd);
  330. return;
  331. case ccid_getmemmanagermemstat:
  332. memoryManager.GetManagerStat((CoreCommand_GetMemManagerStat &)cmd);
  333. return;
  334. }
  335. }
  336. //Вывести сообщение в системном логе
  337. void _cdecl Core::Trace(const char * format,...)
  338. {
  339. SingleClassThread
  340. CoreLogOutData(format, (&format) + 1);
  341. }
  342. //Вывести сообщение в системный лог
  343. void Core::TraceData(const char * format, const void * data)
  344. {
  345. SingleClassThread
  346. CoreLogOutData(format, data);
  347. }
  348. //Вывести сообщение в системный лог 1 раз
  349. void _cdecl Core::Error(const char * format, ...)
  350. {
  351. if(!format) return;
  352. static char buf[256];
  353. crt_vsnprintf(buf, 255, format, (va_list)((&format) + 1));
  354. buf[255] = 0;
  355. dword len = 0;
  356. dword hash = string::Hash(buf, len);
  357. {
  358. SingleClassThread
  359. long index = hash & ARRSIZE(errorsEntry);
  360. for(long i = errorsEntry[index]; i >= 0; )
  361. {
  362. ErrorRecord & err = errors[i];
  363. if(err.hash == hash && err.str.Len() == len)
  364. {
  365. if(err.str == buf)
  366. {
  367. return;
  368. }
  369. }
  370. i = err.next;
  371. }
  372. ErrorRecord & err = errors[i = errors.Add()];
  373. err.next = errorsEntry[index];
  374. errorsEntry[index] = i;
  375. err.hash = hash;
  376. err.str = buf;
  377. }
  378. Trace(buf);
  379. }
  380. //Активно ли приложение
  381. bool Core::IsActive()
  382. {
  383. return isActive;
  384. }
  385. //Завершить работу приложения
  386. void Core::Exit()
  387. {
  388. isExit = true;
  389. }
  390. //Изменить объём выделеной памяти
  391. void * Core::Reallocate(void * ptr, dword size, const char * fileName, long fileLine)
  392. {
  393. SingleClassThread
  394. return memoryManager.Reallocate(ptr, size, fileName, fileLine);
  395. }
  396. //Освободить память
  397. void Core::Free(void * ptr, const char * fileName, long fileLine)
  398. {
  399. SingleClassThread
  400. memoryManager.Free(ptr, fileName, fileLine);
  401. }
  402. //Получить состояние нажатости дебажной кнопки
  403. bool Core::sysDebugKeyState(long id)
  404. {
  405. #ifndef STOP_DEBUG
  406. SingleClassThread
  407. if(!isDebugKeys || !isActive) return false;
  408. #ifndef _XBOX
  409. if(id < __system_start_ex_keys)
  410. {
  411. if(id == VK_PAUSE)
  412. {
  413. return GetAsyncKeyState(id) != 0;
  414. }
  415. return GetAsyncKeyState(id) < 0;
  416. }else
  417. if(id > __system_start_ex_keys)
  418. {
  419. switch(id)
  420. {
  421. case num_lock_flag:
  422. if(GetKeyState(VK_NUMLOCK) & 0x0001) return true;
  423. break;
  424. case caps_lock_flag:
  425. if(GetKeyState(VK_CAPITAL) & 0x0001) return true;
  426. break;
  427. case scroll_lock_flag:
  428. if(GetKeyState(VK_SCROLL) & 0x0001) return true;
  429. break;
  430. }
  431. }
  432. #else
  433. if(id >= xb_dpad_up)
  434. {
  435. dword flags = 0;
  436. bool left = false;
  437. bool right = false;
  438. //Опрашиваем джойстики
  439. for(DWORD i = 0; i < XUSER_MAX_COUNT; i++ )
  440. {
  441. XINPUT_STATE inputState;
  442. if(XInputGetState(i, &inputState) != ERROR_SUCCESS) continue;
  443. flags |= inputState.Gamepad.wButtons;
  444. left |= (inputState.Gamepad.bLeftTrigger > 128);
  445. right |= (inputState.Gamepad.bRightTrigger > 128);
  446. }
  447. switch(id)
  448. {
  449. case xb_dpad_up:
  450. if(flags & XINPUT_GAMEPAD_DPAD_UP) return true;
  451. break;
  452. case xb_dpad_down:
  453. if(flags & XINPUT_GAMEPAD_DPAD_DOWN) return true;
  454. break;
  455. case xb_dpad_left:
  456. if(flags & XINPUT_GAMEPAD_DPAD_LEFT) return true;
  457. break;
  458. case xb_dpad_right:
  459. if(flags & XINPUT_GAMEPAD_DPAD_RIGHT) return true;
  460. break;
  461. case xb_start:
  462. if(flags & XINPUT_GAMEPAD_START) return true;
  463. break;
  464. case xb_back:
  465. if(flags & XINPUT_GAMEPAD_BACK) return true;
  466. break;
  467. case xb_left_thumb:
  468. if(flags & XINPUT_GAMEPAD_LEFT_THUMB) return true;
  469. break;
  470. case xb_right_thumb:
  471. if(flags & XINPUT_GAMEPAD_RIGHT_THUMB) return true;
  472. break;
  473. case xb_left_shoulder:
  474. if(flags & XINPUT_GAMEPAD_LEFT_SHOULDER) return true;
  475. break;
  476. case xb_right_shoulder:
  477. if(flags & XINPUT_GAMEPAD_RIGHT_SHOULDER) return true;
  478. break;
  479. case xb_a:
  480. if(flags & XINPUT_GAMEPAD_A) return true;
  481. break;
  482. case xb_b:
  483. if(flags & XINPUT_GAMEPAD_B) return true;
  484. break;
  485. case xb_x:
  486. if(flags & XINPUT_GAMEPAD_X) return true;
  487. break;
  488. case xb_y:
  489. if(flags & XINPUT_GAMEPAD_Y) return true;
  490. break;
  491. case xb_left_trigger:
  492. if(left) return true;
  493. break;
  494. case xb_right_trigger:
  495. if(right) return true;
  496. break;
  497. }
  498. }
  499. #endif
  500. #endif
  501. return false;
  502. }
  503. //Получить количество системных сообщений, набравшихся за кадр
  504. dword Core::GetSystemMessagesCount()
  505. {
  506. AssertCoreThread
  507. return messagesInfo;
  508. }
  509. //Получить системное сообщение
  510. bool Core::GetSystemMessage(dword index, CoreSystemMessage & msg)
  511. {
  512. AssertCoreThread
  513. if(index >= (dword)messagesInfo) return false;
  514. SysMsgInfo & info = messagesInfo[index];
  515. msg.id = (const char *)&messages[info.name];
  516. msg.data = (const byte *)&messages[info.data];
  517. msg.size = info.size;
  518. return true;
  519. }
  520. //Получить конфигурацию ядер процессора
  521. Core::MultiThreading Core::GetThreadingInfo()
  522. {
  523. AssertCoreThread
  524. return mtmode;
  525. }
  526. //Удалить из списков регистрации объект
  527. void Core::sysUnregistryObject(RegObject * obj)
  528. {
  529. AssertCoreThread
  530. execution.DelObjectExecutions(obj);
  531. decls.RemoveObject(obj);
  532. }
  533. //Добавить значение к счётчику, который сбросится с конце кадра
  534. void Core::sysAddPerformanceCounter(const char * name, float value)
  535. {
  536. #ifndef STOP_PROFILES
  537. AssertCoreThread
  538. pcnts.AddPerformanceCounter(name, value);
  539. #endif
  540. }
  541. //Установить счётчик, который сбросится с конце кадра
  542. void Core::sysSetPerformanceCounter(const char * name, float value)
  543. {
  544. #ifndef STOP_PROFILES
  545. AssertCoreThread
  546. pcnts.SetPerformanceCounter(name, value);
  547. #endif
  548. }
  549. //Получить количество счётчиков
  550. dword Core::sysGetNumberOfPerformanceCounters()
  551. {
  552. #ifndef STOP_PROFILES
  553. AssertCoreThread
  554. return pcnts.GetNumberOfPerformanceCounters();
  555. #else
  556. return 0;
  557. #endif
  558. }
  559. //Получить имя счётчика
  560. const char * Core::sysGetPerformanceName(long index)
  561. {
  562. #ifndef STOP_PROFILES
  563. AssertCoreThread
  564. return pcnts.GetPerformanceName(index);
  565. #else
  566. return null;
  567. #endif
  568. }
  569. //Получить значение счётчика с предыдущего кадра
  570. float Core::sysGetPerformanceCounter(long index)
  571. {
  572. #ifndef STOP_PROFILES
  573. AssertCoreThread
  574. return pcnts.GetPerformanceCounter(index);
  575. #else
  576. return 0.0f;
  577. #endif
  578. }
  579. //Получить значение счётчика с предыдущего кадра
  580. float Core::sysGetPerformanceCounter(const char * name)
  581. {
  582. #ifndef STOP_PROFILES
  583. AssertCoreThread
  584. return pcnts.GetPerformanceCounter(name);
  585. #else
  586. return 0.0f;
  587. #endif
  588. }
  589. //Кадровое обновление
  590. void Core::Update()
  591. {
  592. SetWatchDog();
  593. AssertCoreThread
  594. static const float maxDltTime = (float)Core_MaxDltTime;
  595. //Обновляем состояние мэнеджера памяти
  596. bool numLockActive = DebugKeyState(ICore::num_lock_flag);
  597. bool isEnablePanicCheckMemory = (!fixedFPS && numLockActive);
  598. if(isMemCheck)
  599. {
  600. memoryManager.EnablePanicCheckMemory(isEnablePanicCheckMemory);
  601. }
  602. memoryManager.Update();
  603. //Получаем временной промежуток
  604. if(isHiResTimer)
  605. {
  606. LARGE_INTEGER time;
  607. ::QueryPerformanceCounter(&time);
  608. dltTime = (float)((time.QuadPart - hiResTime.QuadPart)*hiTicksToSeconds);
  609. hiResTime = time;
  610. }else{
  611. dword time = ::GetTickCount();
  612. dltTime = (time - loResTime)*0.001f;
  613. loResTime = time;
  614. }
  615. if(isFixedDltTime)
  616. {
  617. dltTime = fixedDltTime;
  618. }
  619. if(fixedFPS && numLockActive)
  620. {
  621. dltTime = fixedFPSDltTime;
  622. }
  623. if(dltTime < 0.0f)
  624. {
  625. Trace("Detect hight resolution timer problem (delta time < 0)! Switch timer to low resolition...");
  626. isHiResTimer = false;
  627. dltTime = 0.0f;
  628. loResTime = ::GetTickCount();
  629. }
  630. //Считаем FPS
  631. fpsTime += dltTime;
  632. frames++;
  633. if(fpsTime > 1.0f)
  634. {
  635. fps = frames/fpsTime;
  636. fpsTime = 0.0f;
  637. frames = 0;
  638. }
  639. //Если временной промежуток больше допустимого, то ограничиваем его
  640. if(dltTime > maxDltTime) dltTime = maxDltTime;
  641. scaleDltTime = dltTime*timeScale;
  642. if(scaleDltTime > maxDltTime) scaleDltTime = maxDltTime;
  643. if(!isActive)
  644. {
  645. dltTime = 0.0f;
  646. scaleDltTime = 0.0f;
  647. }
  648. //Исполняем сервисы и объекты
  649. execution.Execute(scaleDltTime);
  650. //Очищаем буфер сообщений
  651. messagesInfo.Empty();
  652. messages.Empty();
  653. //Выполняем проверку памяти
  654. if(isMemCheck)
  655. {
  656. memoryManager.CheckMemoryStep();
  657. if(isEnablePanicCheckMemory)
  658. {
  659. SingleClassThread
  660. memoryManager.PanicCheckMemory();
  661. }
  662. }
  663. #ifndef STOP_PROFILES
  664. pcnts.NextFrame();
  665. #endif
  666. }
  667. //Активно ли ядро
  668. void Core::SetActive(bool isActive)
  669. {
  670. this->isActive = isActive;
  671. }
  672. //Функция сообщающая о завершении работы
  673. bool Core::IsExit()
  674. {
  675. #ifdef _XBOX
  676. #ifndef STOP_DEBUG
  677. if(DebugKeyState(ICore::xb_right_shoulder, ICore::xb_left_trigger, ICore::xb_right_trigger))
  678. {
  679. return true;
  680. }
  681. #endif
  682. #endif
  683. return isExit;
  684. }
  685. //Добавить сообщение в буфер сообщений ядра (при количестве параметров == 0 сообщение пропускается)
  686. void Core::AddSystemMessage(const char * id, const unsigned char * data, unsigned long size)
  687. {
  688. AssertCoreThread
  689. //Добавляем описание
  690. SysMsgInfo & mi = messagesInfo[messagesInfo.Add()];
  691. mi.size = size;
  692. //Сохраняем идентификатор
  693. mi.name = messages;
  694. while(*id) messages.Add(*id++);
  695. messages.Add(0);
  696. //Сохраняем данные
  697. mi.data = messages;
  698. while(size--)
  699. {
  700. messages.Add(*data++);
  701. }
  702. }
  703. //Включить-выключить стейт ядра
  704. void Core::SetState(CoreState state, long value)
  705. {
  706. AssertCoreThread
  707. switch(state)
  708. {
  709. case corestate_trace:
  710. core_isEnableTrace = value != 0;
  711. break;
  712. case corestate_debugkeys:
  713. isDebugKeys = value != 0;
  714. break;
  715. case corestate_memcheck:
  716. isMemCheck = value != 0;
  717. break;
  718. case corestate_panicmemcheck:
  719. memoryManager.SetPanicCheckMemoryMode(value != 0);
  720. break;
  721. case corestate_mempools:
  722. if(value != 0) memoryManager.EnableMemPools();
  723. break;
  724. case corestate_mtmanual:
  725. if(value != 0)
  726. {
  727. mtmode = mt_core_more;
  728. }else{
  729. mtmode = mt_none;
  730. }
  731. break;
  732. case corestate_lorestimer:
  733. isHiResTimer = false;
  734. loResTime = ::GetTickCount();
  735. LARGE_INTEGER freq;
  736. if(::QueryPerformanceFrequency(&freq))
  737. {
  738. if(freq.QuadPart != 0)
  739. {
  740. if(::QueryPerformanceCounter(&hiResTime))
  741. {
  742. hiTicksToSeconds = 1.0/double(freq.QuadPart);
  743. isHiResTimer = true;
  744. }
  745. }
  746. }
  747. if(value != 0)
  748. {
  749. isHiResTimer = false;
  750. }
  751. break;
  752. case corestate_fixedfps:
  753. fixedFPS = value;
  754. if(fixedFPS > 0)
  755. {
  756. if(fixedFPS < 10) fixedFPS = 10;
  757. if(fixedFPS > 100) fixedFPS = 100;
  758. fixedFPSDltTime = 1.0f/fixedFPS;
  759. }else{
  760. fixedFPS = 0;
  761. fixedFPSDltTime = 0.0f;
  762. }
  763. break;
  764. }
  765. }
  766. //Получить стейт ядра
  767. long Core::GetState(CoreState state)
  768. {
  769. AssertCoreThread
  770. switch(state)
  771. {
  772. case corestate_trace:
  773. return core_isEnableTrace;
  774. case corestate_debugkeys:
  775. return isDebugKeys;
  776. case corestate_memcheck:
  777. return isMemCheck;
  778. case corestate_panicmemcheck:
  779. return memoryManager.IsPanicCheckMemoryMode();
  780. case corestate_mempools:
  781. return memoryManager.IsEnableMemPools();
  782. case corestate_mtmanual:
  783. return mtmode != mt_none;
  784. case corestate_lorestimer:
  785. return !isHiResTimer;
  786. case corestate_fixedfps:
  787. return fixedFPS;
  788. }
  789. return false;
  790. }
  791. //Создать зарегистрированные сервисы
  792. bool Core::CreateAllServices()
  793. {
  794. AssertCoreThread
  795. return decls.CreateServices();
  796. }