|
@@ -1,5 +1,6 @@
|
|
|
#include "dllLoader.h"
|
|
#include "dllLoader.h"
|
|
|
#include "pikaConfig.h"
|
|
#include "pikaConfig.h"
|
|
|
|
|
+#include <assert/assert.h>
|
|
|
|
|
|
|
|
#ifdef PIKA_DEVELOPMENT
|
|
#ifdef PIKA_DEVELOPMENT
|
|
|
|
|
|
|
@@ -10,25 +11,49 @@
|
|
|
#include <Windows.h>
|
|
#include <Windows.h>
|
|
|
|
|
|
|
|
|
|
|
|
|
- static HMODULE dllHand;
|
|
|
|
|
|
|
+
|
|
|
|
|
+ static FILETIME getLastWriteFile(const char *name)
|
|
|
|
|
+ {
|
|
|
|
|
+ FILETIME time = {};
|
|
|
|
|
+
|
|
|
|
|
+ WIN32_FILE_ATTRIBUTE_DATA Data = {};
|
|
|
|
|
+ if (GetFileAttributesEx(name, GetFileExInfoStandard, &Data))
|
|
|
|
|
+ {
|
|
|
|
|
+ time = Data.ftLastWriteTime;
|
|
|
|
|
+ }
|
|
|
|
|
+ else
|
|
|
|
|
+ {
|
|
|
|
|
+ PIKA_PERMA_ASSERT(0, "Couldn't get file time");
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return(time);
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
//todo error reporting with strings
|
|
//todo error reporting with strings
|
|
|
bool pika::DllLoader::loadDll(std::filesystem::path path)
|
|
bool pika::DllLoader::loadDll(std::filesystem::path path)
|
|
|
{
|
|
{
|
|
|
- path /= "pikaGameplay.dll";
|
|
|
|
|
|
|
+ p = path;
|
|
|
|
|
+
|
|
|
|
|
+ std::filesystem::path originalDll = path / "pikaGameplay.dll";
|
|
|
|
|
+ std::filesystem::path copyDll = path / "pikaGameplayCopy.dll";
|
|
|
|
|
+
|
|
|
|
|
+ filetime = getLastWriteFile(originalDll.string().c_str());
|
|
|
|
|
+
|
|
|
|
|
|
|
|
- dllHand = LoadLibraryA(path.string().c_str());
|
|
|
|
|
|
|
+ std::filesystem::copy(originalDll, copyDll, std::filesystem::copy_options::overwrite_existing);
|
|
|
|
|
+
|
|
|
|
|
+ dllHand = LoadLibraryA(copyDll.string().c_str());
|
|
|
|
|
|
|
|
if (!dllHand) { return false; }
|
|
if (!dllHand) { return false; }
|
|
|
|
|
|
|
|
gameplayStart_ = (gameplayStart_t *)GetProcAddress(dllHand, "gameplayStart");
|
|
gameplayStart_ = (gameplayStart_t *)GetProcAddress(dllHand, "gameplayStart");
|
|
|
- gameplayUpdate_ = (gameplayUpdate_t *)GetProcAddress(dllHand, "gameplayUpdate");
|
|
|
|
|
|
|
+ gameplayReload_ = (gameplayReload_t *)GetProcAddress(dllHand, "gameplayReload");
|
|
|
getContainersInfo_ = (getContainersInfo_t *)GetProcAddress(dllHand, "getContainersInfo");
|
|
getContainersInfo_ = (getContainersInfo_t *)GetProcAddress(dllHand, "getContainersInfo");
|
|
|
constructContainer_ = (constructContainer_t *)GetProcAddress(dllHand, "constructContainer");
|
|
constructContainer_ = (constructContainer_t *)GetProcAddress(dllHand, "constructContainer");
|
|
|
destructContainer_ = (destructContainer_t *)GetProcAddress(dllHand, "destructContainer");
|
|
destructContainer_ = (destructContainer_t *)GetProcAddress(dllHand, "destructContainer");
|
|
|
|
|
|
|
|
if (!gameplayStart_) { return false; }
|
|
if (!gameplayStart_) { return false; }
|
|
|
- if (!gameplayUpdate_) { return false; }
|
|
|
|
|
|
|
+ if (!gameplayReload_) { return false; }
|
|
|
if (!getContainersInfo_) { return false; }
|
|
if (!getContainersInfo_) { return false; }
|
|
|
if (!constructContainer_) { return false; }
|
|
if (!constructContainer_) { return false; }
|
|
|
if (!destructContainer_) { return false; }
|
|
if (!destructContainer_) { return false; }
|
|
@@ -36,6 +61,40 @@
|
|
|
return true;
|
|
return true;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ void pika::DllLoader::unloadDll()
|
|
|
|
|
+ {
|
|
|
|
|
+ FreeLibrary(dllHand);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ bool pika::DllLoader::reloadDll()
|
|
|
|
|
+ {
|
|
|
|
|
+ std::filesystem::path originalDll = p / "pikaGameplay.dll";
|
|
|
|
|
+ std::filesystem::path copyDll = p / "pikaGameplayCopy.dll";
|
|
|
|
|
+
|
|
|
|
|
+ FILETIME newFiletime = getLastWriteFile(originalDll.string().c_str());
|
|
|
|
|
+
|
|
|
|
|
+ if (CompareFileTime(&filetime, &newFiletime) != 0)
|
|
|
|
|
+ {
|
|
|
|
|
+
|
|
|
|
|
+ unloadDll();
|
|
|
|
|
+
|
|
|
|
|
+ HANDLE fileCheck;
|
|
|
|
|
+ while ((fileCheck = CreateFile(originalDll.string().c_str(),
|
|
|
|
|
+ GENERIC_READ | GENERIC_WRITE, NULL, NULL,
|
|
|
|
|
+ OPEN_EXISTING, 0, NULL)) == INVALID_HANDLE_VALUE)
|
|
|
|
|
+ {
|
|
|
|
|
+ //Wait till the dll can be oppened. It is possible that the compiler still keeps it busy.
|
|
|
|
|
+ }
|
|
|
|
|
+ CloseHandle(fileCheck);
|
|
|
|
|
+
|
|
|
|
|
+ //try to load
|
|
|
|
|
+ while (!loadDll(p)) {};
|
|
|
|
|
+
|
|
|
|
|
+ return true;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return false;
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
#else
|
|
#else
|
|
|
#error "pika load dll works only on windows."
|
|
#error "pika load dll works only on windows."
|
|
@@ -50,7 +109,7 @@
|
|
|
{
|
|
{
|
|
|
|
|
|
|
|
gameplayStart_ = gameplayStart;
|
|
gameplayStart_ = gameplayStart;
|
|
|
- gameplayUpdate_ = gameplayUpdate;
|
|
|
|
|
|
|
+ gameplayReload_ = gameplayReload;
|
|
|
getContainersInfo_ = getContainersInfo;
|
|
getContainersInfo_ = getContainersInfo;
|
|
|
constructContainer_ = constructContainer;
|
|
constructContainer_ = constructContainer;
|
|
|
destructContainer_ = destructContainer;
|
|
destructContainer_ = destructContainer;
|
|
@@ -58,7 +117,15 @@
|
|
|
return true;
|
|
return true;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-
|
|
|
|
|
|
|
+ bool pika::DllLoader::reloadDll()
|
|
|
|
|
+ {
|
|
|
|
|
+ return false;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ void pika::DllLoader::unloadDll()
|
|
|
|
|
+ {
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
|
|
|
#endif
|
|
#endif
|
|
|
|
|
|
|
@@ -66,3 +133,5 @@
|
|
|
{
|
|
{
|
|
|
constructContainer_(&c.pointer, &c.arena, name);
|
|
constructContainer_(&c.pointer, &c.arena, name);
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
|
|
+
|