baseContainer.h 10.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411
  1. #pragma once
  2. #include <windowSystemm/window.h>
  3. #include <iostream>
  4. #include <pikaOptional.h>
  5. #include <string>
  6. #include <pikaAllocator/freeListAllocator.h>
  7. #include <staticVector.h>
  8. #include <pikaGL/frameBuffer.h>
  9. #include <pikaConsoleManager/pikaConsoleWindow.h>
  10. #include <globalAllocator/globalAllocator.h>
  11. #include <fstream>
  12. #include <staticString.h>
  13. #include <vector>
  14. #include <stringManipulation/stringManipulation.h>
  15. #include <fstream>
  16. #include <string_view>
  17. #define READENTIREFILE(x) bool x(const char* name, void* buffer, size_t size)
  18. typedef READENTIREFILE(readEntireFile_t);
  19. #undef READENTIREFILE
  20. #define GETFILESIZE(x) bool x(const char* name, size_t &size)
  21. typedef GETFILESIZE(getFileSize_t);
  22. #undef GETFILESIZE
  23. static constexpr size_t MaxAllocatorsCount = 64;
  24. struct CreateContainerInfo
  25. {
  26. pika::StaticString<257> containerName = {};
  27. pika::StaticString<257> cmdArgs = {};
  28. };
  29. //this is passed by the engine. You should not modify the data
  30. //this is also used by the engine to give you acces to some io functions
  31. struct RequestedContainerInfo
  32. {
  33. pika::memory::FreeListAllocator *mainAllocator = {};
  34. pika::StaticVector<pika::memory::FreeListAllocator, MaxAllocatorsCount> *bonusAllocators = {};
  35. //readEntireFile_t *readEntireFilePointer = {};
  36. //getFileSize_t *getFileSizePointer = {};
  37. pika::GL::PikaFramebuffer requestedFBO = {};
  38. int requestedImguiIds = 0;
  39. int imguiTotalRequestedIds = 0;
  40. int pushImguiIdForMe = 0;
  41. pika::ConsoleWindow *consoleWindow = nullptr;
  42. pika::LogManager *logManager = nullptr;
  43. void setMousePositionRelevantToWindow(int x, int y)
  44. {
  45. if (internal.mainWindow)
  46. {
  47. internal.setCursorPosFunc(internal.window, x, y);
  48. }
  49. else
  50. {
  51. int mainX = 0;
  52. int mainY = 0;
  53. internal.getWindowPosFunc(internal.window, &mainX, &mainY);
  54. //internal.setCursorPosFunc(internal.window, x + internal.windowPosX - mainX, y + internal.windowPosY - mainY);
  55. internal.setCursorPosFunc(internal.window, x + internal.windowPosX - mainX + 8, y + internal.windowPosY - mainY + 28);
  56. }
  57. };
  58. void setFpsCursor()
  59. {
  60. PIKA_DEVELOPMENT_ONLY_ASSERT(internal.setInputModeFunc, "missing setInputModeFunc func");
  61. internal.setInputModeFunc(internal.window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
  62. }
  63. void setNormalCursor()
  64. {
  65. PIKA_DEVELOPMENT_ONLY_ASSERT(internal.setInputModeFunc, "missing setInputModeFunc func");
  66. internal.setInputModeFunc(internal.window, GLFW_CURSOR, GLFW_CURSOR_NORMAL);
  67. }
  68. struct
  69. {
  70. int windowPosX = 0;
  71. int windowPosY = 0;
  72. GLFWwindow *window = 0;
  73. bool mainWindow = 0;
  74. decltype(glfwSetCursorPos) *setCursorPosFunc = nullptr;
  75. decltype(glfwGetWindowPos) *getWindowPosFunc = nullptr;
  76. decltype(glfwSetInputMode) *setInputModeFunc = nullptr;
  77. std::vector<CreateContainerInfo> *containersToCreate;
  78. }internal;
  79. //resets global allocator!
  80. void createContainer(std::string containerName, std::string cmdArgs = "")
  81. {
  82. PIKA_DEVELOPMENT_ONLY_ASSERT(internal.containersToCreate, "missing containersToCreate pointer");
  83. CreateContainerInfo info;
  84. if (containerName.size() >= info.containerName.MAX_SIZE-1) { return; }
  85. if (cmdArgs.size() >= info.cmdArgs.MAX_SIZE-1) { return; }
  86. info.containerName = {containerName.c_str()};
  87. info.cmdArgs = {cmdArgs.c_str()};
  88. pika::memory::pushCustomAllocatorsToStandard();
  89. internal.containersToCreate->push_back(info);
  90. pika::memory::popCustomAllocatorsToStandard();
  91. }
  92. bool log(const char* l, int type)
  93. {
  94. //do not allocate memory here!
  95. //log is from core realm
  96. //todo test
  97. if (!logManager) { return false; }
  98. ::pika::memory::pushCustomAllocatorsToStandard();
  99. logManager->log(l, type);
  100. ::pika::memory::popCustomAllocatorsToStandard();
  101. }
  102. //returns true if succeded (can return false if console is disabeled)
  103. bool consoleWrite(const char* c)
  104. {
  105. //do not allocate memory here!
  106. //console window is from core realm
  107. if (!consoleWindow) { return false; }
  108. consoleWindow->write(c);
  109. return true;
  110. }
  111. bool consoleWrite(std::string &s)
  112. {
  113. return consoleWrite(s.c_str());
  114. }
  115. bool writeEntireFile(const char *name, const std::string &content)
  116. {
  117. std::ofstream f(name);
  118. if (!f.is_open()) { return 0; }
  119. f.write(content.c_str(), content.size());
  120. f.close();
  121. return 1;
  122. }
  123. bool writeEntireFileBinary(const char *name, void *data, size_t s)
  124. {
  125. std::ofstream f(name, std::ios::binary | std::ios::out);
  126. if (!f.is_open()) { return 0; }
  127. f.write((char*)data, s);
  128. f.close();
  129. return 1;
  130. }
  131. //todo change to string
  132. bool appendFileBinary(std::string_view name, void *data, size_t s)
  133. {
  134. std::ofstream f(std::string(name), std::ios::binary | std::ios::out | std::ios::app);
  135. if (!f.is_open()) { return 0; }
  136. f.write((char *)data, s);
  137. f.close();
  138. return 1;
  139. }
  140. bool readEntireFileBinary(std::string_view name, std::vector<char> &data)
  141. {
  142. size_t s = 0;
  143. data.clear();
  144. if (!getFileSizeBinary(name, s)) { return 0; }
  145. data.resize(s);
  146. return readEntireFileBinary(name, data.data(), s);
  147. }
  148. bool readEntireFile(std::string_view name, std::string &data)
  149. {
  150. size_t s = 0;
  151. data.clear();
  152. if (!getFileSize(name, s)) { return 0; }
  153. data.resize(s);
  154. return readEntireFile(name, data.data(), s);
  155. }
  156. std::string readEntireFileBinaryAsAString(std::string_view name)
  157. {
  158. std::string rez;
  159. size_t s = 0;
  160. bool succeed = getFileSizeBinary(name, s);
  161. if (!succeed) { return rez; }
  162. rez.resize(s + 1);
  163. pika::memory::pushCustomAllocatorsToStandard();
  164. {
  165. std::ifstream f(std::string(name), std::ios::binary);
  166. if (!f.is_open())
  167. {
  168. succeed = false;
  169. }
  170. else
  171. {
  172. f.read((char *)rez.data(), s);
  173. f.close();
  174. }
  175. }
  176. pika::memory::popCustomAllocatorsToStandard();
  177. if (!succeed) { return ""; }
  178. return rez;
  179. }
  180. bool readEntireFileBinary(std::string_view name, void *buffer, size_t size, size_t from = 0)
  181. {
  182. //PIKA_DEVELOPMENT_ONLY_ASSERT(readEntireFilePointer, "read entire file pointer not assigned");
  183. bool success = true;
  184. pika::memory::pushCustomAllocatorsToStandard();
  185. {
  186. std::ifstream f(std::string(name), std::ios::binary);
  187. if (!f.is_open())
  188. {
  189. success = false;
  190. }
  191. else
  192. {
  193. f.seekg(from);
  194. f.read((char*)buffer, size);
  195. f.close();
  196. }
  197. }
  198. pika::memory::popCustomAllocatorsToStandard();
  199. return success;
  200. }
  201. bool readEntireFile(std::string_view name, void *buffer, size_t size)
  202. {
  203. //PIKA_DEVELOPMENT_ONLY_ASSERT(readEntireFilePointer, "read entire file pointer not assigned");
  204. bool success = true;
  205. pika::memory::pushCustomAllocatorsToStandard();
  206. {
  207. std::ifstream f{ std::string(name) };
  208. if (!f.is_open())
  209. {
  210. success = false;
  211. }
  212. else
  213. {
  214. f.read((char *)buffer, size);
  215. f.close();
  216. }
  217. }
  218. pika::memory::popCustomAllocatorsToStandard();
  219. return success;
  220. }
  221. //todo version that returns a char vector
  222. bool getFileSizeBinary(std::string_view name, size_t &size)
  223. {
  224. //PIKA_DEVELOPMENT_ONLY_ASSERT(getFileSizePointer, "get file size pointer not assigned");
  225. bool success = true;
  226. size = 0;
  227. pika::memory::pushCustomAllocatorsToStandard();
  228. {
  229. std::ifstream f(std::string(name), std::ifstream::ate | std::ifstream::binary);
  230. if (!f.is_open())
  231. {
  232. success = false;
  233. }
  234. else
  235. {
  236. size = f.tellg();
  237. f.close();
  238. }
  239. }
  240. pika::memory::popCustomAllocatorsToStandard();
  241. return size;
  242. }
  243. bool getFileSize(std::string_view name, size_t &size)
  244. {
  245. bool success = true;
  246. size = 0;
  247. pika::memory::pushCustomAllocatorsToStandard();
  248. {
  249. std::ifstream f(std::string(name), std::ifstream::ate);
  250. if (!f.is_open())
  251. {
  252. success = false;
  253. }
  254. else
  255. {
  256. size = f.tellg();
  257. f.close();
  258. }
  259. }
  260. pika::memory::popCustomAllocatorsToStandard();
  261. return success;
  262. }
  263. };
  264. struct ContainerStaticInfo
  265. {
  266. //this is the main heap allocator memory size
  267. size_t defaultHeapMemorySize = 0;
  268. //this will use the global allocator. you won't be able to use input recording or snapshots, and the
  269. //memory leak protection won't be possible.
  270. bool useDefaultAllocator = 0;
  271. pika::StaticVector<size_t, MaxAllocatorsCount> bonusAllocators = {};
  272. //add file extensions here so that the engine knows that your container can open them.
  273. pika::StaticVector<pika::StaticString<16>, 16> extensionsSuported = {};
  274. //the engine will create a new window for your container and give you the fbo to bind to
  275. //in release that fbo will just be the default framebuffer
  276. bool requestImguiFbo = 0;
  277. unsigned int requestImguiIds = 0;
  278. bool andInputWithWindowHasFocus = 1;
  279. bool andInputWithWindowHasFocusLastFrame = 1;
  280. bool openOnApplicationStartup = 0;
  281. bool pushAnImguiIdForMe = 0;
  282. bool _internalNotImplemented = 0;
  283. bool operator==(const ContainerStaticInfo &other)
  284. {
  285. if (this == &other) { return true; }
  286. return
  287. this->defaultHeapMemorySize == other.defaultHeapMemorySize &&
  288. this->bonusAllocators == other.bonusAllocators &&
  289. this->_internalNotImplemented == other._internalNotImplemented &&
  290. this->requestImguiFbo == other.requestImguiFbo &&
  291. this->requestImguiIds == other.requestImguiIds &&
  292. this->useDefaultAllocator == other.useDefaultAllocator &&
  293. this->andInputWithWindowHasFocus == other.andInputWithWindowHasFocus &&
  294. this->andInputWithWindowHasFocusLastFrame == other.andInputWithWindowHasFocusLastFrame &&
  295. this->pushAnImguiIdForMe == other.pushAnImguiIdForMe &&
  296. this->openOnApplicationStartup == other.openOnApplicationStartup;
  297. }
  298. bool operator!=(const ContainerStaticInfo &other)
  299. {
  300. return !(*this == other);
  301. }
  302. };
  303. struct Container
  304. {
  305. //this is used to give to the engine basic information about your container.
  306. //this function should be pure
  307. //this function should not allocate memory
  308. //this should not be dependent on anything that is called on create or library initialization
  309. static ContainerStaticInfo containerInfo() { ContainerStaticInfo c; c._internalNotImplemented = true; return c; };
  310. virtual bool create(RequestedContainerInfo &requestedInfo, pika::StaticString<256> commandLineArgument) = 0;
  311. virtual bool update(
  312. pika::Input input,
  313. pika::WindowState windowState,
  314. RequestedContainerInfo &requestedInfo) = 0;
  315. virtual void destruct(RequestedContainerInfo &requestedInfo) {};
  316. virtual ~Container() {};
  317. };