3#include <unordered_set>
5static std::filesystem::path
dllPath = std::filesystem::current_path();
7#ifdef SAMURAI_DEVELOPMENT
14 static FILETIME getLastWriteFile(
const char *name)
18 WIN32_FILE_ATTRIBUTE_DATA Data = {};
19 if (GetFileAttributesEx(name, GetFileExInfoStandard, &Data))
21 time = Data.ftLastWriteTime;
37void samurai::LoadedDll::reloadContainerExtensionsSupport()
39#pragma region reload extension support
41 containerExtensionsSupport.clear();
42 for (
auto &c : containerInfo)
44 for (
auto &e : c.containerStaticInfo.extensionsSuported)
46 containerExtensionsSupport[e.to_string()] = c.containerName;
53bool samurai::LoadedDll::constructRuntimeContainer(RuntimeContainer &c,
const char *name)
55 SAMURAI_DEVELOPMENT_ONLY_ASSERT(constructContainer_ !=
nullptr,
"dll not loaded");
56 return constructContainer_(&c.pointer, &c.arena, name);
63 SAMURAI_DEVELOPMENT_ONLY_ASSERT(bindAllocator_ !=
nullptr,
"dll not loaded");
64 bindAllocator_(allocator);
67void samurai::LoadedDll::resetAllocatorDllRealm()
69 SAMURAI_DEVELOPMENT_ONLY_ASSERT(resetAllocator_ !=
nullptr,
"dll not loaded");
75 containerInfo.clear();
76 containerInfo.reserve(100);
79 getContainersInfo_(containerInfo);
81 std::unordered_set<std::string> uniqueNames = {};
83 for (
int i = 0; i < containerInfo.size(); i++)
85 auto signalError = [&](
const char *e)
87 std::string l = e + containerInfo[i].containerName;
90 containerInfo.erase(containerInfo.begin() + i);
94 if (uniqueNames.find(containerInfo[i].containerName) == uniqueNames.end())
96 uniqueNames.insert(containerInfo[i].containerName);
100 signalError(
"Duplicate container name: ");
104 if (containerInfo[i].containerStaticInfo._internalNotImplemented)
106 signalError(
"Container did not implement containerInfo function: ");
110 if (containerInfo[i].containerStaticInfo.defaultHeapMemorySize < 100)
112 signalError(
"Too little heap memory for container: ");
127 std::filesystem::path originalDll =
dllPath /
"gameplay.dll";
128 std::filesystem::path copyDll =
dllPath / (
"gameplayCopy" + std::to_string(
id) +
".dll");
130 filetime = getLastWriteFile(originalDll.string().c_str());
132 if (filetime.dwLowDateTime == FILETIME().dwLowDateTime
134 filetime.dwHighDateTime == FILETIME().dwHighDateTime
139 if (!CopyFile(originalDll.string().c_str(), copyDll.string().c_str(),
false) ) {
return false; }
142 dllHand = LoadLibraryA(copyDll.string().c_str());
144 if (!dllHand) {
return false; }
146 gameplayStart_ = (gameplayStart_t *)GetProcAddress(dllHand,
"gameplayStart");
147 gameplayReload_ = (gameplayReload_t *)GetProcAddress(dllHand,
"gameplayReload");
148 getContainersInfo_ = (getContainersInfo_t *)GetProcAddress(dllHand,
"getContainersInfo");
149 constructContainer_ = (constructContainer_t *)GetProcAddress(dllHand,
"constructContainer");
150 destructContainer_ = (destructContainer_t *)GetProcAddress(dllHand,
"destructContainer");
151 bindAllocator_ = (bindAllocator_t *)GetProcAddress(dllHand,
"bindAllocator");
152 resetAllocator_ = (resetAllocator_t *)GetProcAddress(dllHand,
"resetAllocator");
153 dissableAllocators_ = (dissableAllocators_t *)GetProcAddress(dllHand,
"dissableAllocators");
155 if (!gameplayStart_) {
return false; }
156 if (!gameplayReload_) {
return false; }
157 if (!getContainersInfo_) {
return false; }
158 if (!constructContainer_) {
return false; }
159 if (!destructContainer_) {
return false; }
160 if (!bindAllocator_) {
return false; }
161 if (!resetAllocator_) {
return false; }
162 if (!dissableAllocators_) {
return false; }
165 getContainerInfoAndCheck(logs);
168 reloadContainerExtensionsSupport();
173bool samurai::LoadedDll::checkIfDllIsOpenable()
175 HANDLE fileCheck = {};
176 fileCheck = CreateFile((
dllPath /
"gameplay.dll").
string().c_str(),
177 GENERIC_READ | GENERIC_WRITE, NULL, NULL,
178 OPEN_EXISTING, 0, NULL);
180 if (fileCheck == INVALID_HANDLE_VALUE)
186 CloseHandle(fileCheck);
192 std::chrono::duration<long long> timeout)
194 auto startTime = std::chrono::steady_clock::now();
196 while (!checkIfDllIsOpenable())
198 if (timeout != std::chrono::seconds(0))
200 if (std::chrono::steady_clock::now() > startTime + timeout)
212 while (!loadDll(
id, logs))
214 if (timeout != std::chrono::seconds(0))
216 if (std::chrono::steady_clock::now() > startTime + timeout)
225void samurai::LoadedDll::unloadDll()
227 if (dllHand == 0) {
return; }
231 resetAllocatorDllRealm();
233 FreeLibrary(dllHand);
236 containerInfo.clear();
239bool samurai::LoadedDll::shouldReloadDll()
241 if (dllHand == 0) {
return 0; }
243 std::filesystem::path originalDll =
dllPath /
"gameplay.dll";
245 FILETIME newFiletime = getLastWriteFile(originalDll.string().c_str());
247 if (filetime.dwLowDateTime == FILETIME().dwLowDateTime
249 filetime.dwHighDateTime == FILETIME().dwHighDateTime
255 return (CompareFileTime(&filetime, &newFiletime) != 0);
static std::filesystem::path dllPath
void log(const char *l, int type=samurai::logNormal)