containerManager.cpp 38 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423
  1. #include "containerManager.h"
  2. #include <globalAllocator/globalAllocator.h>
  3. #include <unordered_set>
  4. #include <chrono>
  5. #include <thread>
  6. #include <unordered_map>
  7. #include <fileManipulation/fileManipulation.h>
  8. #include <stringManipulation/stringManipulation.h>
  9. #include <filesystem>
  10. #include <imgui.h>
  11. #include <containersWindow/containersWindow.h>
  12. #include <imgui_internal.h>
  13. #include <fstream>
  14. pika::containerId_t pika::ContainerManager::createContainer(std::string containerName,
  15. pika::LoadedDll &loadedDll, pika::LogManager &logManager,
  16. pika::pikaImgui::ImGuiIdsManager &imguiIDsManager, ConsoleWindow *consoleWindow, std::string &cmd, size_t memoryPos)
  17. {
  18. for(auto &i : loadedDll.containerInfo)
  19. {
  20. if (i.containerName == containerName)
  21. {
  22. return createContainer(i, loadedDll, logManager, imguiIDsManager, consoleWindow, cmd, memoryPos);
  23. }
  24. }
  25. logManager.log(("Couldn't create container, couldn't find the name: " + containerName).c_str(), pika::logError);
  26. return 0;
  27. }
  28. bool pika::ContainerManager::setSnapshotToContainer(pika::containerId_t containerId, const char *snapshotName, pika::LogManager &logManager
  29. , pika::pikaImgui::ImGuiIdsManager &imguiIdManager)
  30. {
  31. auto c = runningContainers.find(containerId);
  32. if (c == runningContainers.end())
  33. {
  34. logManager.log((std::string("Couldn't find container for setting snapshot: #")
  35. + std::to_string(containerId)).c_str(),
  36. pika::logError);
  37. return false;
  38. }
  39. if (!checkIfSnapshotIsCompatible(c->second, snapshotName))
  40. {
  41. logManager.log((std::string("Snapshot incompatible: ") + snapshotName).c_str(),
  42. pika::logError);
  43. return false;
  44. }
  45. std::string file = PIKA_ENGINE_RESOURCES_PATH;
  46. file += snapshotName;
  47. file += ".snapshot";
  48. auto s = pika::getFileSize(file.c_str());
  49. if (s != (c->second.totalSize + sizeof(pika::RuntimeContainer)) )
  50. {
  51. logManager.log((std::string("Snapshot corrupted probably, file size incorrect: ")
  52. + snapshotName).c_str(),
  53. pika::logError);
  54. return false;
  55. }
  56. pika::readEntireFile(file.c_str(), c->second.getBaseAdress(),
  57. c->second.totalSize, sizeof(pika::RuntimeContainer));
  58. //c->second.requestedContainerInfo.requestedImguiIds
  59. // = imguiIdManager.getImguiIds(c->second.requestedContainerInfo.imguiTotalRequestedIds);
  60. logManager.log("Loaded snapshot");
  61. return true;
  62. }
  63. bool pika::ContainerManager::setRecordingToContainer(pika::containerId_t containerId, const char *recordingName,
  64. pika::LogManager &logManager, pika::pikaImgui::ImGuiIdsManager &imguiIdManager)
  65. {
  66. auto c = runningContainers.find(containerId);
  67. if (c == runningContainers.end())
  68. {
  69. logManager.log((std::string("Couldn't find container for setting recording: #")
  70. + std::to_string(containerId)).c_str(),
  71. pika::logError);
  72. return false;
  73. }
  74. if (!setSnapshotToContainer(containerId, recordingName, logManager, imguiIdManager))
  75. {
  76. return false;
  77. }
  78. c->second.flags.status = pika::RuntimeContainer::FLAGS::STATUS_BEING_PLAYBACK;
  79. c->second.flags.frameNumber = 0;
  80. pika::strlcpy(c->second.flags.recordingName, recordingName, sizeof(c->second.flags.recordingName));
  81. }
  82. //todo mabe use regions further appart in production
  83. void* pika::ContainerManager::allocateContainerMemory(pika::RuntimeContainer &container,
  84. pika::ContainerInformation containerInformation, void *memPos)
  85. {
  86. size_t memoryRequired = containerInformation.calculateMemoryRequirements();
  87. void *baseMemory = allocateOSMemory(memoryRequired, memPos);
  88. if (baseMemory == nullptr) { return 0; }
  89. container.totalSize = memoryRequired;
  90. allocateContainerMemoryAtBuffer(container,
  91. containerInformation, baseMemory);
  92. return baseMemory;
  93. }
  94. void pika::ContainerManager::allocateContainerMemoryAtBuffer(pika::RuntimeContainer &container,
  95. pika::ContainerInformation containerInformation, void *buffer)
  96. {
  97. const size_t staticMemory = containerInformation.containerStructBaseSize;
  98. const size_t heapMemory = containerInformation.containerStaticInfo.defaultHeapMemorySize;
  99. char *currentMemoryAdress = (char *)buffer;
  100. container.arena.containerStructMemory.size = staticMemory;
  101. container.arena.containerStructMemory.block = currentMemoryAdress;
  102. currentMemoryAdress += staticMemory;
  103. pika::align64(currentMemoryAdress);
  104. container.allocator.init(currentMemoryAdress, heapMemory);
  105. currentMemoryAdress += heapMemory;
  106. for (int i = 0; i < containerInformation.containerStaticInfo.bonusAllocators.size(); i++)
  107. {
  108. pika::align64(currentMemoryAdress);
  109. pika::memory::FreeListAllocator allocator;
  110. allocator.init(
  111. currentMemoryAdress,
  112. containerInformation.containerStaticInfo.bonusAllocators[i]
  113. );
  114. container.bonusAllocators.push_back(allocator);
  115. currentMemoryAdress += containerInformation.containerStaticInfo.bonusAllocators[i];
  116. }
  117. }
  118. void pika::ContainerManager::freeContainerStuff(pika::RuntimeContainer &container)
  119. {
  120. deallocateOSMemory(container.arena.containerStructMemory.block);
  121. //container.arena.dealocateStaticMemory(); //static memory
  122. //deallocateOSMemory(container.allocator.originalBaseMemory); //heap memory
  123. //
  124. //for (auto &i : container.bonusAllocators)
  125. //{
  126. // deallocateOSMemory(i.originalBaseMemory);
  127. //}
  128. }
  129. pika::containerId_t pika::ContainerManager::createContainer
  130. (pika::ContainerInformation containerInformation,
  131. pika::LoadedDll &loadedDll, pika::LogManager &logManager, pika::pikaImgui::ImGuiIdsManager &imguiIDsManager,
  132. ConsoleWindow *consoleWindow, std::string &cmd,
  133. size_t memoryPos)
  134. {
  135. containerId_t id = ++idCounter;
  136. //not necessary if this is the only things that assigns ids.
  137. //if (runningContainers.find(id) != runningContainers.end())
  138. //{
  139. // logManager.log((std::string("Container id already exists: #") + std::to_string(id)).c_str(), pika::logError);
  140. // return false;
  141. //}
  142. //todo a create and destruct wrapper
  143. pika::RuntimeContainer container = {};
  144. pika::strlcpy(container.baseContainerName, containerInformation.containerName,
  145. sizeof(container.baseContainerName));
  146. container.andInputWithWindowHasFocus = containerInformation.containerStaticInfo.andInputWithWindowHasFocus;
  147. container.andInputWithWindowHasFocusLastFrame = containerInformation.containerStaticInfo.andInputWithWindowHasFocusLastFrame;
  148. if (!allocateContainerMemory(container, containerInformation, (void*)memoryPos))
  149. {
  150. logManager.log((std::string("Couldn't allocate memory for constructing container: #")
  151. + std::to_string(id)).c_str(), pika::logError);
  152. return 0;
  153. }
  154. //create imgui fbo just for developement mode
  155. #ifndef PIKA_PRODUCTION
  156. if (containerInformation.containerStaticInfo.requestImguiFbo)
  157. {
  158. container.requestedContainerInfo.requestedFBO.createFramebuffer(40, 40);
  159. container.imguiWindowId = imguiIDsManager.getImguiIds();
  160. }
  161. #endif
  162. loadedDll.bindAllocatorDllRealm(&container.allocator);
  163. //this calls the constructors (from the dll realm)
  164. if (!loadedDll.constructRuntimeContainer(container, containerInformation.containerName.c_str()))
  165. {
  166. loadedDll.resetAllocatorDllRealm();
  167. logManager.log((std::string("Couldn't construct container: #") + std::to_string(id)).c_str(), pika::logError);
  168. freeContainerStuff(container);
  169. container.requestedContainerInfo.requestedFBO.deleteFramebuffer();
  170. return 0;
  171. }
  172. loadedDll.resetAllocatorDllRealm();
  173. #pragma region setup requested container info
  174. container.requestedContainerInfo.mainAllocator = &container.allocator;
  175. container.requestedContainerInfo.bonusAllocators = &container.bonusAllocators;
  176. container.requestedContainerInfo.requestedImguiIds =
  177. imguiIDsManager.getImguiIds(containerInformation.containerStaticInfo.requestImguiIds);
  178. container.requestedContainerInfo.imguiTotalRequestedIds = containerInformation.containerStaticInfo.requestImguiIds;
  179. container.requestedContainerInfo.pushImguiIdForMe = imguiIDsManager.getImguiIds(containerInformation.containerStaticInfo.pushAnImguiIdForMe);
  180. container.requestedContainerInfo.consoleWindow = consoleWindow;
  181. container.requestedContainerInfo.logManager = &logManager;
  182. #pragma endregion
  183. pika::StaticString<256> cmdArgs = {};
  184. if (cmd.size() > cmdArgs.MAX_SIZE)
  185. {
  186. logManager.log(std::string(std::string("Couldn't pass cmd argument because it is too big ")
  187. + container.baseContainerName + " #" + std::to_string(id)).c_str(), pika::logError);
  188. }
  189. else
  190. {
  191. cmdArgs = cmd.c_str();
  192. }
  193. loadedDll.bindAllocatorDllRealm(&container.allocator);
  194. bool rezult = container.pointer->create(container.requestedContainerInfo, cmdArgs); //this calls create() (from the dll realm)
  195. loadedDll.resetAllocatorDllRealm();//sets the global allocator back to standard (used for runtime realm)
  196. runningContainers[id] = container;
  197. if (!rezult)
  198. {
  199. logManager.log((std::string("Couldn't create container because it returned 0")
  200. + container.baseContainerName + " #" + std::to_string(id)).c_str(), pika::logWarning);
  201. destroyContainer(id, loadedDll, logManager);
  202. return 0;
  203. }
  204. else
  205. {
  206. logManager.log(("Created container: " + std::string(container.baseContainerName)).c_str());
  207. }
  208. return id;
  209. }
  210. void pika::ContainerManager::init()
  211. {
  212. }
  213. void pika::ContainerManager::update(pika::LoadedDll &loadedDll, pika::PikaWindow &window,
  214. pika::LogManager &logs, pika::pikaImgui::ImGuiIdsManager &imguiIdManager, pika::ConsoleWindow *consoleWindow)
  215. {
  216. PIKA_DEVELOPMENT_ONLY_ASSERT(loadedDll.dllHand != 0, "dll not loaded when trying to update containers");
  217. #pragma region reload dll
  218. //todo try to recover from a failed load
  219. if (loadedDll.shouldReloadDll())
  220. {
  221. reloadDll(loadedDll, window, logs);
  222. //todo mark that it failed so it doesn't repeat on a loop
  223. }
  224. #pragma endregion
  225. std::vector<CreateContainerInfo> containersToCreate;
  226. std::vector<containerId_t> containersToDelete;//delete because they returned 0
  227. #pragma region running containers
  228. for (auto &c : runningContainers)
  229. {
  230. c.second.requestedContainerInfo.consoleWindow = consoleWindow;
  231. c.second.requestedContainerInfo.logManager = &logs;
  232. c.second.requestedContainerInfo.internal.containersToCreate = &containersToCreate;
  233. if (c.second.flags.status == pika::RuntimeContainer::FLAGS::STATUS_RUNNING
  234. ||
  235. c.second.flags.status == pika::RuntimeContainer::FLAGS::STATUS_BEING_RECORDED
  236. ||
  237. c.second.flags.status == pika::RuntimeContainer::FLAGS::STATUS_BEING_PLAYBACK
  238. )
  239. {
  240. PIKA_DEVELOPMENT_ONLY_ASSERT(
  241. (c.second.requestedContainerInfo.requestedFBO.fbo == 0 &&
  242. c.second.imguiWindowId == 0) ||
  243. (
  244. c.second.requestedContainerInfo.requestedFBO.fbo != 0 &&
  245. c.second.imguiWindowId != 0), "we have a fbo but no imguiwindow id"
  246. );
  247. auto windowInput = window.input;
  248. #if PIKA_DEVELOPMENT
  249. if (c.second.flags.status == pika::RuntimeContainer::FLAGS::STATUS_BEING_RECORDED)
  250. {
  251. if (!makeRecordingStep(c.first, logs, windowInput))
  252. {
  253. c.second.flags.status = pika::RuntimeContainer::FLAGS::STATUS_RUNNING;
  254. logs.log((std::string("Stopped container recording because we couldn't oppen file")
  255. + std::to_string(c.first)).c_str(),
  256. pika::logError);
  257. }
  258. }
  259. if (c.second.flags.status == pika::RuntimeContainer::FLAGS::STATUS_BEING_PLAYBACK)
  260. {
  261. pika::Input readInput = {};
  262. std::string fileName = c.second.flags.recordingName;
  263. fileName += ".recording";
  264. fileName = PIKA_ENGINE_RESOURCES_PATH + fileName;
  265. auto s = pika::getFileSize(fileName.c_str());
  266. if (c.second.flags.frameNumber * sizeof(pika::Input) >= s && s != 0)
  267. {
  268. //todo optional logs here
  269. if (!setSnapshotToContainer(c.first, c.second.flags.recordingName, logs, imguiIdManager))
  270. {
  271. logs.log((std::string("Stopped container playback because we couldn't assign it's snapshot on frame 0")
  272. + std::to_string(c.first)).c_str(),
  273. pika::logError);
  274. c.second.flags.status = pika::RuntimeContainer::FLAGS::STATUS_RUNNING;
  275. goto endContainerErrorChecking;
  276. }
  277. c.second.flags.frameNumber = 0;
  278. }
  279. if (s == 0)
  280. {
  281. logs.log((std::string("Stopped container playback because we couldn't oppen file or its content is empty")
  282. + std::to_string(c.first)).c_str(),
  283. pika::logError);
  284. c.second.flags.status = pika::RuntimeContainer::FLAGS::STATUS_RUNNING;
  285. }
  286. else if (s % sizeof(pika::Input) != 0)
  287. {
  288. logs.log((std::string("Stopped container playback because the file content is corrupt")
  289. + std::to_string(c.first)).c_str(),
  290. pika::logError);
  291. c.second.flags.status = pika::RuntimeContainer::FLAGS::STATUS_RUNNING;
  292. }
  293. if (!pika::readEntireFile(fileName.c_str(), &readInput, sizeof(pika::Input), sizeof(pika::Input) * c.second.flags.frameNumber))
  294. {
  295. logs.log((std::string("Stopped container playback because we couldn't oppen file")
  296. + std::to_string(c.first)).c_str(),
  297. pika::logError);
  298. c.second.flags.status = pika::RuntimeContainer::FLAGS::STATUS_RUNNING;
  299. }
  300. else
  301. {
  302. windowInput = readInput;
  303. c.second.flags.frameNumber++;
  304. }
  305. }
  306. #endif
  307. endContainerErrorChecking:
  308. #if PIKA_PRODUCTION
  309. constexpr bool isProduction = 1;
  310. #else
  311. constexpr bool isProduction = 0;
  312. #endif
  313. auto callUpdate = [&](pika::WindowState &windowState) -> bool
  314. {
  315. windowInput.lastFrameHasFocus = c.second.lastFrameFocus;
  316. c.second.lastFrameFocus = windowInput.hasFocus;
  317. if (c.second.andInputWithWindowHasFocus || c.second.andInputWithWindowHasFocusLastFrame)
  318. {
  319. bool andValue = 1;
  320. if (c.second.andInputWithWindowHasFocus && !windowInput.hasFocus)
  321. {
  322. andValue = 0;
  323. }
  324. if (c.second.andInputWithWindowHasFocusLastFrame && !windowInput.lastFrameHasFocus)
  325. {
  326. andValue = 0;
  327. }
  328. if (!andValue)
  329. {
  330. memset(windowInput.typedInput, 0, sizeof(windowInput.typedInput));
  331. windowInput.lMouse = {};
  332. windowInput.rMouse = {};
  333. for (int i = 0; i < Button::BUTTONS_COUNT; i++)
  334. {
  335. windowInput.buttons[i] = {};
  336. }
  337. for (int i = 0; i < Input::MAX_CONTROLLERS_COUNT; i++)
  338. {
  339. windowInput.controllers[i].resetAllButtons();
  340. }
  341. windowInput.anyController.resetAllButtons();
  342. }
  343. }
  344. windowInput.deltaTime *= c.second.simulationSpeed;
  345. windowInput.deltaTime *= !c.second.deltaTimePaused;
  346. c.second.requestedContainerInfo.mainAllocator = &c.second.allocator; //reset this
  347. c.second.requestedContainerInfo.bonusAllocators = &c.second.bonusAllocators;
  348. if (c.second.requestedContainerInfo.pushImguiIdForMe)
  349. {
  350. ImGui::PushID(c.second.requestedContainerInfo.pushImguiIdForMe);
  351. }
  352. auto t1 = std::chrono::high_resolution_clock::now();
  353. loadedDll.bindAllocatorDllRealm(&c.second.allocator);
  354. bool rez = c.second.pointer->update(windowInput, windowState, c.second.requestedContainerInfo);
  355. loadedDll.resetAllocatorDllRealm();
  356. auto t2 = std::chrono::high_resolution_clock::now();
  357. if (c.second.requestedContainerInfo.pushImguiIdForMe)
  358. {
  359. ImGui::PopID();
  360. }
  361. auto milliseconds = (std::chrono::duration_cast<std::chrono::microseconds>(t2 - t1)).count()/1000.f;
  362. c.second.frameTimer += milliseconds;
  363. c.second.frameCounter++;
  364. if (c.second.frameCounter >= 100)
  365. {
  366. c.second.currentMs = c.second.frameTimer/100.f;
  367. c.second.frameTimer = 0;
  368. c.second.frameCounter = 0;
  369. }
  370. return rez;
  371. };
  372. bool rez = 0;
  373. if (c.second.imguiWindowId && !isProduction) //todo remove is in production here and replace with remove imgui option
  374. {
  375. #pragma region imguiwindow
  376. ImGui::PushID(c.second.imguiWindowId);
  377. bool isOpen = 1;
  378. ImGui::PushStyleColor(ImGuiCol_WindowBg, ImVec4(0.f, 0.f, 0.f, 1.0f));
  379. ImGui::SetNextWindowSize({200,200}, ImGuiCond_Once);
  380. ImGui::Begin( (std::string("gameplay window id: ") + std::to_string(c.first)).c_str(),
  381. &isOpen, ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoScrollWithMouse | ImGuiWindowFlags_NoNav);
  382. //mouse pos and focus
  383. auto windowPos = ImGui::GetWindowPos();
  384. if(c.second.flags.status != pika::RuntimeContainer::FLAGS::STATUS_BEING_PLAYBACK)
  385. {
  386. ImVec2 globalMousePos = {};
  387. {
  388. ImGuiContext *g = ImGui::GetCurrentContext();
  389. globalMousePos = g->IO.MousePos;
  390. }
  391. windowInput.mouseX = globalMousePos.x;
  392. windowInput.mouseY = globalMousePos.y;
  393. ImVec2 vMin = ImGui::GetWindowContentRegionMin();
  394. windowInput.mouseX -= windowPos.x + vMin.x;
  395. windowInput.mouseY -= windowPos.y + vMin.y;
  396. //https://github.com/ocornut/imgui/issues/5882
  397. ImGuiViewport *viewPort = ImGui::GetWindowViewport();
  398. auto io = ImGui::GetIO();
  399. if (viewPort->PlatformUserData)
  400. {
  401. windowInput.hasFocus = ImGui::IsWindowFocused()
  402. && ImGui::GetPlatformIO().Platform_GetWindowFocus(viewPort) && !io.AppFocusLost;
  403. }
  404. else
  405. {
  406. windowInput.hasFocus = 0;
  407. }
  408. //windowInput.hasFocus = windowInput.hasFocus && !io.AppFocusLost;
  409. }
  410. auto s = ImGui::GetContentRegionMax();
  411. //todo try set borders here at 0,0, easiest thing to do probably
  412. ImGui::PushStyleVar(ImGuiStyleVar_WindowBorderSize, 0.f);
  413. //ImGui::Image((void *)c.second.requestedContainerInfo.requestedFBO.texture, s, {0, 1}, {1, 0},
  414. // {1,1,1,1}, {0,0,0,0});
  415. ImVec2 pos = ImGui::GetCursorScreenPos();
  416. ImVec2 maxPos = {ImGui::GetWindowPos().x + ImGui::GetWindowSize().x,
  417. ImGui::GetWindowPos().y + ImGui::GetWindowSize().y};
  418. unsigned texId = c.second.requestedContainerInfo.requestedFBO.texture;
  419. ImGui::GetWindowDrawList()->AddImage(
  420. (void *)texId,
  421. ImVec2(pos.x, pos.y),
  422. ImVec2(maxPos),
  423. ImVec2(0, 1), ImVec2(1, 0)
  424. );
  425. ImGui::PopStyleVar();
  426. ImGui::End();
  427. ImGui::PopStyleColor();
  428. ImGui::PopID();
  429. #pragma endregion
  430. auto windowState = window.windowState;
  431. windowState.windowW = s.x;
  432. windowState.windowH = s.y;
  433. windowState.frameBufferW = s.x;
  434. windowState.frameBufferH = s.y;
  435. c.second.requestedContainerInfo.requestedFBO.resizeFramebuffer(windowState.windowW, windowState.windowH);
  436. c.second.requestedContainerInfo.internal.mainWindow = 0;
  437. c.second.requestedContainerInfo.internal.window = window.context.wind;
  438. c.second.requestedContainerInfo.internal.windowPosX = windowPos.x;
  439. c.second.requestedContainerInfo.internal.windowPosY = windowPos.y;
  440. c.second.requestedContainerInfo.internal.setCursorPosFunc = glfwSetCursorPos;
  441. c.second.requestedContainerInfo.internal.getWindowPosFunc = glfwGetWindowPos;
  442. c.second.requestedContainerInfo.internal.setInputModeFunc = glfwSetInputMode;
  443. glBindFramebuffer(GL_FRAMEBUFFER, c.second.requestedContainerInfo.requestedFBO.fbo);
  444. rez = callUpdate(windowState);
  445. glBindFramebuffer(GL_FRAMEBUFFER, 0);
  446. if (!isOpen)
  447. {
  448. rez = 1;
  449. containersToDelete.push_back(c.first);
  450. }
  451. }
  452. else
  453. {
  454. c.second.requestedContainerInfo.internal.mainWindow = 1;
  455. c.second.requestedContainerInfo.internal.window = window.context.wind;
  456. glfwGetWindowPos(window.context.wind,
  457. &c.second.requestedContainerInfo.internal.windowPosX,
  458. &c.second.requestedContainerInfo.internal.windowPosY);
  459. c.second.requestedContainerInfo.internal.setCursorPosFunc = glfwSetCursorPos;
  460. c.second.requestedContainerInfo.internal.getWindowPosFunc = glfwGetWindowPos;
  461. c.second.requestedContainerInfo.internal.setInputModeFunc = glfwSetInputMode;
  462. rez = callUpdate(window.windowState);
  463. }
  464. if (!rez)
  465. {
  466. logs.log(("Terminated container because it returned 0: " + std::string(c.second.baseContainerName)
  467. + " #" + std::to_string(c.first)).c_str());
  468. containersToDelete.push_back(c.first);
  469. }
  470. }
  471. else //on pause
  472. {
  473. //still keep it running on the same frame mabe
  474. }
  475. }
  476. for (auto i : containersToDelete)
  477. {
  478. destroyContainer(i, loadedDll, logs);
  479. }
  480. #pragma endregion
  481. #pragma region create new containers
  482. for (auto &i : containersToCreate)
  483. {
  484. auto s = i.cmdArgs.to_string();
  485. createContainer(i.containerName.to_string(), loadedDll, logs, imguiIdManager, consoleWindow, s);
  486. }
  487. #pragma endregion
  488. }
  489. bool pika::ContainerManager::reloadDll(pika::LoadedDll &loadedDll, pika::PikaWindow &window, pika::LogManager &logs)
  490. {
  491. std::this_thread::sleep_for(std::chrono::milliseconds(200)); // make sure that the compiler had enough time
  492. //to get hold onto the dll
  493. auto oldContainerInfo = loadedDll.containerInfo;
  494. if (!loadedDll.tryToloadDllUntillPossible(loadedDll.id, logs, std::chrono::seconds(2)))
  495. {
  496. logs.log("Couldn't reloaded dll", pika::logWarning);
  497. return 0;
  498. }
  499. //todo pospone dll reloading and make this timer shorter
  500. std::unordered_map<std::string, pika::ContainerInformation> containerNames;
  501. for (auto &c : loadedDll.containerInfo)
  502. {
  503. containerNames[c.containerName] = c;
  504. }
  505. std::unordered_map<std::string, pika::ContainerInformation> oldContainerNames;
  506. for (auto &c : oldContainerInfo)
  507. {
  508. oldContainerNames[c.containerName] = c;
  509. }
  510. //clear containers that dissapeared
  511. {
  512. std::vector<pika::containerId_t> containersToClean;
  513. for (auto &i : runningContainers)
  514. {
  515. if (containerNames.find(i.second.baseContainerName) ==
  516. containerNames.end())
  517. {
  518. std::string l = "Killed container because it does not exist anymore in dll: " +
  519. std::string(i.second.baseContainerName)
  520. + " #" + std::to_string(i.first);
  521. logs.log(l.c_str(), pika::logError);
  522. containersToClean.push_back(i.first);
  523. }
  524. }
  525. for (auto i : containersToClean)
  526. {
  527. forceTerminateContainer(i, loadedDll, logs);
  528. }
  529. }
  530. //clear containers that changed static info
  531. {
  532. std::vector<pika::containerId_t> containersToClean;
  533. for (auto &i : runningContainers)
  534. {
  535. auto &newContainer = containerNames[i.second.baseContainerName];
  536. auto &oldContainer = oldContainerNames[i.second.baseContainerName];
  537. if (newContainer != oldContainer)
  538. {
  539. std::string l = "Killed container because its static container info\nhas changed: "
  540. + std::string(i.second.baseContainerName)
  541. + " #" + std::to_string(i.first);
  542. logs.log(l.c_str(), pika::logError);
  543. containersToClean.push_back(i.first);
  544. }
  545. }
  546. for (auto i : containersToClean)
  547. {
  548. forceTerminateContainer(i, loadedDll, logs);
  549. }
  550. }
  551. //realocate pointers
  552. {
  553. std::unordered_map<std::string, size_t> vtable;
  554. for (auto &i : runningContainers)
  555. {
  556. auto pos = vtable.find(i.second.baseContainerName);
  557. if (pos == vtable.end())
  558. {
  559. pika::RuntimeContainer container = {};
  560. pika::strlcpy(container.baseContainerName, i.second.baseContainerName,
  561. sizeof(container.baseContainerName));
  562. pika::ContainerInformation info;
  563. for (auto &l : loadedDll.containerInfo)
  564. {
  565. if (l.containerName == i.second.baseContainerName)
  566. {
  567. info = l;
  568. }
  569. }
  570. if (!allocateContainerMemory(container, info, 0))
  571. {
  572. logs.log("Internal error 1", pika::logError);
  573. }
  574. else
  575. {
  576. loadedDll.bindAllocatorDllRealm(&container.allocator);
  577. //this calls the constructors (from the dll realm)
  578. if (!loadedDll.constructRuntimeContainer(container, i.second.baseContainerName))
  579. {
  580. loadedDll.resetAllocatorDllRealm();
  581. logs.log("Internal error 2", pika::logError);
  582. freeContainerStuff(container);
  583. loadedDll.resetAllocatorDllRealm();
  584. }
  585. else
  586. {
  587. size_t id = *(size_t *)container.pointer;
  588. freeContainerStuff(container);
  589. loadedDll.resetAllocatorDllRealm();
  590. vtable[i.second.baseContainerName] = id;
  591. }
  592. }
  593. }
  594. pos = vtable.find(i.second.baseContainerName);
  595. if (pos != vtable.end())
  596. {
  597. memcpy(i.second.pointer, (void*)&pos->second, sizeof(size_t));
  598. }
  599. }
  600. }
  601. loadedDll.gameplayReload_(window.context, logs);
  602. logs.log("Reloaded dll");
  603. return 1;
  604. }
  605. //todo not verbose flag
  606. bool pika::ContainerManager::destroyContainer(containerId_t id, pika::LoadedDll &loadedDll,
  607. pika::LogManager &logManager)
  608. {
  609. PIKA_DEVELOPMENT_ONLY_ASSERT(loadedDll.dllHand != 0, "dll not loaded when trying to destroy container");
  610. auto c = runningContainers.find(id);
  611. if (c == runningContainers.end())
  612. {
  613. logManager.log((std::string("Couldn't find container for destruction: #") + std::to_string(id)).c_str(),
  614. pika::logError);
  615. return false;
  616. }
  617. auto name = c->second.baseContainerName;
  618. loadedDll.bindAllocatorDllRealm(&c->second.allocator);
  619. c->second.requestedContainerInfo.mainAllocator = &c->second.allocator; //reset this
  620. c->second.requestedContainerInfo.bonusAllocators = &c->second.bonusAllocators;
  621. c->second.pointer->destruct(c->second.requestedContainerInfo);
  622. loadedDll.destructContainer_(&(c->second.pointer), &c->second.arena);
  623. loadedDll.resetAllocatorDllRealm();
  624. freeContainerStuff(c->second);
  625. c->second.requestedContainerInfo.requestedFBO.deleteFramebuffer();
  626. runningContainers.erase(c);
  627. logManager.log((std::string("Destroyed continer: ") + name + " #" + std::to_string(id)).c_str());
  628. return true;
  629. }
  630. //todo remove some of this functions in production
  631. //snapshot file format:
  632. //
  633. // binary
  634. //
  635. // pika::RuntimeContainer
  636. //
  637. // static memory
  638. //
  639. // heap memory
  640. //
  641. //
  642. bool pika::ContainerManager::makeSnapshot(containerId_t id, pika::LogManager &logManager, const char *fileName)
  643. {
  644. auto c = runningContainers.find(id);
  645. if (c == runningContainers.end())
  646. {
  647. logManager.log((std::string("Couldn't find container for making snapshot: #") + std::to_string(id)).c_str(),
  648. pika::logError);
  649. return false;
  650. }
  651. std::string filePath = PIKA_ENGINE_RESOURCES_PATH;
  652. filePath += fileName;
  653. filePath += ".snapshot";
  654. if(!pika::writeEntireFile(filePath.c_str(), &c->second, sizeof(c->second)))
  655. {
  656. logManager.log(("Couldn't write to file for making snapshot: " + filePath).c_str(),
  657. pika::logError);
  658. return false;
  659. }
  660. if (!pika::appendToFile(filePath.c_str(),
  661. c->second.getBaseAdress(), c->second.totalSize))
  662. {
  663. pika::deleteFile(filePath.c_str());
  664. logManager.log(("Couldn't write to file for making snapshot: " + filePath).c_str(),
  665. pika::logError);
  666. return false;
  667. }
  668. //if (!pika::appendToFile(filePath.c_str(),
  669. // c->second.arena.containerStructMemory.block, c->second.arena.containerStructMemory.size))
  670. //{
  671. // pika::deleteFile(filePath.c_str());
  672. // logManager.log(("Couldn't write to file for making snapshot: " + filePath).c_str(),
  673. // pika::logError);
  674. // return false;
  675. //}
  676. //
  677. //if (!pika::appendToFile(filePath.c_str(),
  678. // c->second.allocator.originalBaseMemory, c->second.allocatorSize))
  679. //{
  680. // pika::deleteFile(filePath.c_str());
  681. // logManager.log(("Couldn't write to file for making snapshot: " + filePath).c_str(),
  682. // pika::logError);
  683. // return false;
  684. //}
  685. return true;
  686. }
  687. bool pika::ContainerManager::startRecordingContainer(containerId_t id, pika::LogManager &logManager, const char *fileName)
  688. {
  689. auto c = runningContainers.find(id);
  690. if (c == runningContainers.end())
  691. {
  692. logManager.log((std::string("Couldn't find container for making recording: #") + std::to_string(id)).c_str(),
  693. pika::logError);
  694. return false;
  695. }
  696. if(c->second.flags.status != pika::RuntimeContainer::FLAGS::STATUS_RUNNING)
  697. {
  698. logManager.log((std::string("Trying to record a container that is not running (on status): #") + std::to_string(id)).c_str(),
  699. pika::logError);
  700. return false;
  701. }
  702. std::string filePath = PIKA_ENGINE_RESOURCES_PATH;
  703. filePath += fileName;
  704. filePath += ".recording";
  705. if (filePath.size() > sizeof(c->second.flags.recordingName) - 1)
  706. {
  707. logManager.log((std::string("File path too big (on trying to record)") + std::to_string(id)).c_str(),
  708. pika::logError);
  709. return 0;
  710. }
  711. if (!makeSnapshot(id, logManager, fileName))
  712. {
  713. logManager.log((std::string("Couldn't make snapshot for starting recording") + std::to_string(id)).c_str(),
  714. pika::logError);
  715. return 0;
  716. }
  717. //cear file
  718. {
  719. std::ofstream record(filePath);
  720. if (!record.is_open())
  721. {
  722. logManager.log((std::string("Couldn't open recording file for starting recording") + std::to_string(id)).c_str(),
  723. pika::logError);
  724. return 0;
  725. }
  726. record.close();
  727. }
  728. c->second.flags.status = pika::RuntimeContainer::FLAGS::STATUS_BEING_RECORDED;
  729. pika::strlcpy(c->second.flags.recordingName, filePath, sizeof(c->second.flags.recordingName));
  730. }
  731. bool pika::ContainerManager::stopRecordingContainer(containerId_t id, pika::LogManager &logManager)
  732. {
  733. auto c = runningContainers.find(id);
  734. if (c == runningContainers.end())
  735. {
  736. logManager.log((std::string("Couldn't find container for stopping recording: #") + std::to_string(id)).c_str(),
  737. pika::logError);
  738. return false;
  739. }
  740. c->second.flags.status = pika::RuntimeContainer::FLAGS::STATUS_RUNNING;
  741. }
  742. bool pika::ContainerManager::makeRecordingStep(containerId_t id, pika::LogManager &logManager,
  743. pika::Input &input)
  744. {
  745. auto c = runningContainers.find(id);
  746. if (c == runningContainers.end())
  747. {
  748. logManager.log((std::string("Couldn't find container for making recording step: #") + std::to_string(id)).c_str(),
  749. pika::logError);
  750. return false;
  751. }
  752. if (!pika::appendToFile(c->second.flags.recordingName, &input, sizeof(input)))
  753. {
  754. logManager.log((std::string("Couldn't append to file for recording container") + std::to_string(id)).c_str(),
  755. pika::logError);
  756. return false;
  757. }
  758. return true;
  759. }
  760. bool pika::ContainerManager::forceTerminateContainer(containerId_t id, pika::LoadedDll &loadedDll, pika::LogManager &logManager)
  761. {
  762. PIKA_DEVELOPMENT_ONLY_ASSERT(loadedDll.dllHand != 0, "dll not loaded when trying to destroy container");
  763. auto c = runningContainers.find(id);
  764. if (c == runningContainers.end())
  765. {
  766. logManager.log((std::string("Couldn't find container for destruction: #") + std::to_string(id)).c_str(),
  767. pika::logError);
  768. return false;
  769. }
  770. auto name = c->second.baseContainerName;
  771. freeContainerStuff(c->second);
  772. runningContainers.erase(c);
  773. logManager.log((std::string("Force terminated continer: ") + name + " #" + std::to_string(id)).c_str());
  774. c->second.requestedContainerInfo.requestedFBO.deleteFramebuffer();
  775. return true;
  776. }
  777. void pika::ContainerManager::destroyAllContainers(pika::LoadedDll &loadedDll,
  778. pika::LogManager &logManager)
  779. {
  780. std::vector < pika::containerId_t> containersId;
  781. containersId.reserve(runningContainers.size());
  782. for (auto &c : runningContainers)
  783. {
  784. containersId.push_back(c.first);
  785. }
  786. for (auto i : containersId)
  787. {
  788. destroyContainer(i, loadedDll, logManager);
  789. }
  790. }
  791. #ifdef PIKA_PRODUCTION
  792. void *pika::ContainerManager::allocateOSMemory(size_t size, void *baseAdress)
  793. {
  794. PIKA_PERMA_ASSERT(baseAdress == nullptr, "can't allocate fixed memory in production");
  795. return malloc(size);
  796. }
  797. void pika::ContainerManager::deallocateOSMemory(void *baseAdress)
  798. {
  799. free(baseAdress);
  800. }
  801. #else
  802. #include <Windows.h>
  803. void *pika::ContainerManager::allocateOSMemory(size_t size, void *baseAdress)
  804. {
  805. return VirtualAlloc(baseAdress, size, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
  806. }
  807. void pika::ContainerManager::deallocateOSMemory(void *baseAdress)
  808. {
  809. VirtualFree(baseAdress, 0, MEM_RELEASE);
  810. }
  811. #endif
  812. std::vector<std::string> pika::getAvailableSnapshots(pika::RuntimeContainer &info)
  813. {
  814. std::vector<std::string> files;
  815. auto curDir = std::filesystem::directory_iterator(PIKA_ENGINE_RESOURCES_PATH);
  816. for (const auto &iter : curDir)
  817. {
  818. if (std::filesystem::is_regular_file(iter)
  819. && iter.path().extension() == ".snapshot"
  820. )
  821. {
  822. if (pika::checkIfSnapshotIsCompatible(info, iter.path().stem().string().c_str()))
  823. {
  824. files.push_back(iter.path().stem().string());
  825. }
  826. }
  827. }
  828. return files;
  829. }
  830. std::vector<std::string> pika::getAvailableRecordings(pika::RuntimeContainer &info)
  831. {
  832. auto snapshots = getAvailableSnapshots(info);
  833. std::vector<std::string> returnVec;
  834. returnVec.reserve(snapshots.size());
  835. auto curDir = std::filesystem::directory_iterator(PIKA_ENGINE_RESOURCES_PATH);
  836. for (const auto &iter : curDir)
  837. {
  838. if (std::filesystem::is_regular_file(iter)
  839. && iter.path().extension() == ".recording"
  840. )
  841. {
  842. if (std::find(snapshots.begin(), snapshots.end(), iter.path().stem().string()) != snapshots.end())
  843. {
  844. returnVec.push_back(iter.path().stem().string());
  845. }
  846. }
  847. }
  848. return returnVec;
  849. }
  850. std::vector<std::string> pika::getAvailableSnapshotsAnyMemoryPosition(pika::RuntimeContainer &info)
  851. {
  852. std::vector<std::string> files;
  853. auto curDir = std::filesystem::directory_iterator(PIKA_ENGINE_RESOURCES_PATH);
  854. for (const auto &iter : curDir)
  855. {
  856. if (std::filesystem::is_regular_file(iter)
  857. && iter.path().extension() == ".snapshot"
  858. )
  859. {
  860. if (pika::checkIfSnapshotIsCompatibleAnyMemoryPosition(info, iter.path().stem().string().c_str()))
  861. {
  862. files.push_back(iter.path().stem().string());
  863. }
  864. }
  865. }
  866. return files;
  867. }
  868. std::vector<std::string> pika::getAvailableRecordingAnyMemoryPosition(pika::RuntimeContainer &info)
  869. {
  870. auto snapshots = getAvailableSnapshotsAnyMemoryPosition(info);
  871. std::vector<std::string> returnVec;
  872. returnVec.reserve(snapshots.size());
  873. auto curDir = std::filesystem::directory_iterator(PIKA_ENGINE_RESOURCES_PATH);
  874. for (const auto &iter : curDir)
  875. {
  876. if (std::filesystem::is_regular_file(iter)
  877. && iter.path().extension() == ".recording"
  878. )
  879. {
  880. if (std::find(snapshots.begin(), snapshots.end(), iter.path().stem().string()) != snapshots.end())
  881. {
  882. returnVec.push_back(iter.path().stem().string());
  883. }
  884. }
  885. }
  886. return returnVec;
  887. }
  888. std::vector<std::string> pika::getAvailableSnapshotsAnyMemoryPosition(pika::ContainerInformation &info)
  889. {
  890. std::vector<std::string> files;
  891. if (!std::filesystem::is_directory(PIKA_ENGINE_RESOURCES_PATH))
  892. {
  893. std::filesystem::create_directory(PIKA_ENGINE_RESOURCES_PATH);
  894. }
  895. auto curDir = std::filesystem::directory_iterator(PIKA_ENGINE_RESOURCES_PATH);
  896. for (const auto &iter : curDir)
  897. {
  898. if (std::filesystem::is_regular_file(iter)
  899. && iter.path().extension() == ".snapshot"
  900. )
  901. {
  902. if (pika::checkIfSnapshotIsCompatibleAnyMemoryPosition(info, iter.path().stem().string().c_str()))
  903. {
  904. files.push_back(iter.path().stem().string());
  905. }
  906. }
  907. }
  908. return files;
  909. }
  910. std::vector<std::string> pika::getAvailableRecordingsAnyMemoryPosition(pika::ContainerInformation &info)
  911. {
  912. auto snapshots = getAvailableSnapshotsAnyMemoryPosition(info);
  913. std::vector<std::string> returnVec;
  914. returnVec.reserve(snapshots.size());
  915. auto curDir = std::filesystem::directory_iterator(PIKA_ENGINE_RESOURCES_PATH);
  916. for (const auto &iter : curDir)
  917. {
  918. if (std::filesystem::is_regular_file(iter)
  919. && iter.path().extension() == ".recording"
  920. )
  921. {
  922. if (std::find(snapshots.begin(), snapshots.end(), iter.path().stem().string()) != snapshots.end())
  923. {
  924. returnVec.push_back(iter.path().stem().string());
  925. }
  926. }
  927. }
  928. return returnVec;
  929. }
  930. bool pika::checkIfSnapshotIsCompatible(pika::RuntimeContainer &info, const char *snapshotName)
  931. {
  932. std::string file = PIKA_ENGINE_RESOURCES_PATH;
  933. file += snapshotName;
  934. file += ".snapshot";
  935. pika::RuntimeContainer loadedInfo = {};
  936. auto s = pika::readEntireFile(file.c_str(), &loadedInfo, sizeof(loadedInfo));
  937. if (s != sizeof(loadedInfo))
  938. {
  939. return 0;
  940. }
  941. //todo mabe a method here?
  942. if (loadedInfo.allocator.originalBaseMemory != info.allocator.originalBaseMemory)
  943. {
  944. return false;
  945. }
  946. if (loadedInfo.requestedContainerInfo.imguiTotalRequestedIds != info.requestedContainerInfo.imguiTotalRequestedIds)
  947. {
  948. return false;
  949. }
  950. if (loadedInfo.arena.containerStructMemory.block != info.arena.containerStructMemory.block)
  951. {
  952. return false;
  953. }
  954. if (loadedInfo.arena.containerStructMemory.size != info.arena.containerStructMemory.size)
  955. {
  956. return false;
  957. }
  958. if (std::strcmp(loadedInfo.baseContainerName, info.baseContainerName) != 0)
  959. {
  960. return false;
  961. }
  962. if (loadedInfo.bonusAllocators != info.bonusAllocators)
  963. {
  964. return false;
  965. }
  966. //check if user requested an imgui window
  967. if (
  968. !(
  969. (info.imguiWindowId == 0&&
  970. loadedInfo.imguiWindowId == 0
  971. )||
  972. (
  973. info.imguiWindowId != 0 &&
  974. loadedInfo.imguiWindowId != 0
  975. )
  976. )
  977. )
  978. {
  979. return false;
  980. }
  981. if (loadedInfo.totalSize != info.totalSize)
  982. {
  983. return false;
  984. }
  985. return true;
  986. }
  987. bool pika::checkIfSnapshotIsCompatibleAnyMemoryPosition(pika::RuntimeContainer &info, const char *snapshotName)
  988. {
  989. std::string file = PIKA_ENGINE_RESOURCES_PATH;
  990. file += snapshotName;
  991. file += ".snapshot";
  992. pika::RuntimeContainer loadedInfo = {};
  993. auto s = pika::readEntireFile(file.c_str(), &loadedInfo, sizeof(loadedInfo));
  994. if (s != sizeof(loadedInfo))
  995. {
  996. return 0;
  997. }
  998. if (loadedInfo.arena.containerStructMemory.size != info.arena.containerStructMemory.size)
  999. {
  1000. return false;
  1001. }
  1002. if (std::strcmp(loadedInfo.baseContainerName, info.baseContainerName) != 0)
  1003. {
  1004. return false;
  1005. }
  1006. if (loadedInfo.requestedContainerInfo.bonusAllocators != info.requestedContainerInfo.bonusAllocators)
  1007. {
  1008. return false;
  1009. }
  1010. //check if user requested an imgui window
  1011. if (
  1012. !(
  1013. (info.imguiWindowId == 0 &&
  1014. loadedInfo.imguiWindowId == 0
  1015. ) ||
  1016. (
  1017. info.imguiWindowId != 0 &&
  1018. loadedInfo.imguiWindowId != 0
  1019. )
  1020. )
  1021. )
  1022. {
  1023. return false;
  1024. }
  1025. if (loadedInfo.totalSize != info.totalSize)
  1026. {
  1027. return false;
  1028. }
  1029. return true;
  1030. }
  1031. bool pika::checkIfSnapshotIsCompatibleAnyMemoryPosition(pika::ContainerInformation &info, const char *snapshotName)
  1032. {
  1033. std::string file = PIKA_ENGINE_RESOURCES_PATH;
  1034. file += snapshotName;
  1035. file += ".snapshot";
  1036. pika::RuntimeContainer loadedInfo = {};
  1037. auto s = pika::readEntireFile(file.c_str(), &loadedInfo, sizeof(loadedInfo));
  1038. if (s != sizeof(loadedInfo))
  1039. {
  1040. return 0;
  1041. }
  1042. if (loadedInfo.arena.containerStructMemory.size != info.containerStructBaseSize)
  1043. {
  1044. return false;
  1045. }
  1046. if (std::strcmp(loadedInfo.baseContainerName, info.containerName.c_str()) != 0)
  1047. {
  1048. return false;
  1049. }
  1050. if (loadedInfo.bonusAllocators.size() != info.containerStaticInfo.bonusAllocators.size())
  1051. {
  1052. return false;
  1053. }
  1054. for (int i = 0; i < loadedInfo.bonusAllocators.size(); i++)
  1055. {
  1056. if (loadedInfo.bonusAllocators[i].heapSize != info.containerStaticInfo.bonusAllocators[i]) //todo this doesn't seem to work
  1057. {
  1058. return false;
  1059. }
  1060. }
  1061. //check if user requested an imgui window
  1062. if (
  1063. !(
  1064. (info.containerStaticInfo.requestImguiFbo == false &&
  1065. loadedInfo.imguiWindowId == 0
  1066. ) ||
  1067. (
  1068. info.containerStaticInfo.requestImguiFbo == true &&
  1069. loadedInfo.imguiWindowId != 0
  1070. )
  1071. )
  1072. )
  1073. {
  1074. return false;
  1075. }
  1076. if (loadedInfo.allocator.heapSize != info.containerStaticInfo.defaultHeapMemorySize)
  1077. {
  1078. return false;
  1079. }
  1080. return true;
  1081. }
  1082. void *pika::getSnapshotMemoryPosition(const char *snapshotName)
  1083. {
  1084. std::string file = PIKA_ENGINE_RESOURCES_PATH;
  1085. file += snapshotName;
  1086. file += ".snapshot";
  1087. pika::RuntimeContainer loadedInfo = {};
  1088. auto s = pika::readEntireFile(file.c_str(), &loadedInfo, sizeof(loadedInfo));
  1089. if (s != sizeof(loadedInfo))
  1090. {
  1091. return nullptr;
  1092. }
  1093. return loadedInfo.getBaseAdress();
  1094. }