This commit is contained in:
Asuro
2025-02-09 13:47:20 +01:00
parent df752065af
commit af22a2e87f
4 changed files with 111 additions and 45 deletions

9
.gitmodules vendored
View File

@@ -1,12 +1,3 @@
[submodule "src/dependency/bx"]
path = src/dependency/bx
url = https://github.com/bkaradzic/bx
[submodule "src/dependency/bgfx"]
path = src/dependency/bgfx
url = https://github.com/bkaradzic/bgfx
[submodule "src/dependency/bimg"]
path = src/dependency/bimg
url = https://github.com/bkaradzic/bimg
[submodule "src/dependency/bgfx.cmake"] [submodule "src/dependency/bgfx.cmake"]
path = src/dependency/bgfx.cmake path = src/dependency/bgfx.cmake
url = https://github.com/bkaradzic/bgfx.cmake url = https://github.com/bkaradzic/bgfx.cmake

View File

@@ -1,5 +1,6 @@
#pragma once #pragma once
#include <cstdint> #include <cstdint>
#include <bx/spscqueue.h>
struct SharedWindowData struct SharedWindowData
{ {
@@ -8,6 +9,16 @@ struct SharedWindowData
int32_t WindowHeight = 1080; int32_t WindowHeight = 1080;
}; };
struct FileChangeNotification
{
wchar_t FileName[128]{0};
};
struct SharedDevData
{
bx::SpScUnboundedQueueT<FileChangeNotification>* ShaderChangeQueue;
};
struct GameData struct GameData
{ {
void* PermanentStorage = nullptr; void* PermanentStorage = nullptr;
@@ -16,6 +27,7 @@ struct GameData
struct SharedData struct SharedData
{ {
SharedDevData Dev;
SharedWindowData Window; SharedWindowData Window;
GameData Game; GameData Game;
}; };

View File

@@ -1,3 +1,6 @@
#include <cstdlib>
#include <cwchar>
#include <fileapi.h>
#define WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN
#include <Windows.h> #include <Windows.h>
#undef min #undef min
@@ -5,6 +8,8 @@
#include <cstdio> #include <cstdio>
#include <bx/string.h> #include <bx/string.h>
#include <bx/spscqueue.h>
#include <bx/allocator.h>
#include "Shared.h" #include "Shared.h"
#include "Window.h" #include "Window.h"
@@ -21,16 +26,31 @@ constexpr const char* DLLPath = "libPuzGame.dll";
constexpr const wchar_t* DLLWatch = L"cmake-build\\libPuzGame2.dll"; constexpr const wchar_t* DLLWatch = L"cmake-build\\libPuzGame2.dll";
#endif #endif
namespace
{
bx::AllocatorI* defaultAllocator = new bx::DefaultAllocator{};
}
enum class FileChangeType
{
DLL,
Shader,
CompiledShader,
};
struct FileWatcherData struct FileWatcherData
{ {
bool Change = false; bx::SpScUnboundedQueueT<FileChangeNotification> ShaderQueue{defaultAllocator};
bx::SpScUnboundedQueueT<FileChangeNotification> DLLQueue{defaultAllocator};
}; };
struct DevelopmentData struct DevelopmentData
{ {
uint8_t FileChangeBuffer[1024]{ 0 }; uint8_t FileChangeBuffer[1024]{ 0 };
HMODULE GameLib = NULL; HMODULE GameLib = NULL;
HANDLE hDevDir = NULL; HANDLE DevDir = NULL;
HANDLE ShaderDir = NULL;
HANDLE CompiledShaderDir = NULL;
FileWatcherData FileWatcher; FileWatcherData FileWatcher;
}; };
@@ -49,27 +69,37 @@ namespace
Shutdown ShutdownFunc; Shutdown ShutdownFunc;
} }
unsigned long FileWatcherThread(void* data) void FileChangeCheck(HANDLE dirHandle, FileChangeType changeType, const wchar_t* compName = nullptr)
{ {
DWORD bytesReturned = 0; DWORD bytesReturned = 0;
bool isRunning = DevData.hDevDir;
while (isRunning)
{
bx::memSet(DevData.FileChangeBuffer, 0, sizeof(DevData.FileChangeBuffer)); bx::memSet(DevData.FileChangeBuffer, 0, sizeof(DevData.FileChangeBuffer));
if (ReadDirectoryChangesW(DevData.hDevDir, DevData.FileChangeBuffer, sizeof(DevData.FileChangeBuffer), true, FILE_NOTIFY_CHANGE_FILE_NAME | FILE_NOTIFY_CHANGE_LAST_WRITE | FILE_NOTIFY_CHANGE_SIZE, &bytesReturned, NULL, NULL)) if (ReadDirectoryChangesW(dirHandle, DevData.FileChangeBuffer, sizeof(DevData.FileChangeBuffer), true, FILE_NOTIFY_CHANGE_FILE_NAME | FILE_NOTIFY_CHANGE_LAST_WRITE | FILE_NOTIFY_CHANGE_SIZE, &bytesReturned, NULL, NULL))
{ {
uint32_t offset = 0; uint32_t offset = 0;
while (true) while (true)
{ {
FILE_NOTIFY_INFORMATION* notifyData = reinterpret_cast<FILE_NOTIFY_INFORMATION*>(&DevData.FileChangeBuffer[offset]); FILE_NOTIFY_INFORMATION* notifyData = reinterpret_cast<FILE_NOTIFY_INFORMATION*>(&DevData.FileChangeBuffer[offset]);
// wprintf(L"Change: %ls\n", notifyData->FileName);
if (notifyData->Action == FILE_ACTION_ADDED || notifyData->Action == FILE_ACTION_MODIFIED || notifyData->Action == FILE_ACTION_RENAMED_NEW_NAME) if (notifyData->Action == FILE_ACTION_ADDED || notifyData->Action == FILE_ACTION_MODIFIED || notifyData->Action == FILE_ACTION_RENAMED_NEW_NAME)
{ {
if (wcscmp(notifyData->FileName, DLLWatch) == 0) if (compName == nullptr || wcscmp(notifyData->FileName, compName) == 0)
{ {
DevData.FileWatcher.Change = true; FileChangeNotification notif;
printf("detected dll change!\n"); wcscpy(notif.FileName, notifyData->FileName);
if (changeType == FileChangeType::DLL)
{
DevData.FileWatcher.DLLQueue.push(&notif);
}
else if (changeType == FileChangeType::Shader)
{
std::system("../shadercompile.bat");
}
else if (changeType == FileChangeType::CompiledShader)
{
DevData.FileWatcher.ShaderQueue.push(&notif);
}
printf("detected file change of type %u!\n", changeType);
wprintf(L"%s\n", notifyData->FileName);
} }
} }
@@ -77,6 +107,16 @@ unsigned long FileWatcherThread(void* data)
offset += notifyData->NextEntryOffset; offset += notifyData->NextEntryOffset;
} }
} }
}
unsigned long FileWatcherThread(void* data)
{
bool isRunning = DevData.DevDir;
while (isRunning)
{
FileChangeCheck(DevData.DevDir, FileChangeType::DLL, DLLWatch);
FileChangeCheck(DevData.ShaderDir, FileChangeType::Shader);
FileChangeCheck(DevData.CompiledShaderDir, FileChangeType::CompiledShader);
} }
printf("File watcher thread ended!\n"); printf("File watcher thread ended!\n");
return 0; return 0;
@@ -151,6 +191,17 @@ bool ReloadDLL()
return true; return true;
} }
HANDLE LoadDirHandle(const char* name)
{
return CreateFileA(name,
FILE_LIST_DIRECTORY,
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
NULL,
OPEN_EXISTING,
FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OVERLAPPED,
NULL);
}
int main() int main()
{ {
char PathBuf[512]{ 0 }; char PathBuf[512]{ 0 };
@@ -166,13 +217,11 @@ int main()
return 1; return 1;
} }
DevData.hDevDir = CreateFile(".", Shared.Dev.ShaderChangeQueue = &DevData.FileWatcher.ShaderQueue;
FILE_LIST_DIRECTORY, DevData.DevDir = LoadDirHandle(".");
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, DevData.ShaderDir = LoadDirHandle("../game/shaders");
NULL, DevData.CompiledShaderDir = LoadDirHandle("../game/compiled-shaders");
OPEN_EXISTING,
FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OVERLAPPED,
NULL);
DWORD fileWatcherThreadId = 0; DWORD fileWatcherThreadId = 0;
CreateThread(NULL, 0, FileWatcherThread, NULL, 0, &fileWatcherThreadId); CreateThread(NULL, 0, FileWatcherThread, NULL, 0, &fileWatcherThreadId);
@@ -186,9 +235,11 @@ int main()
{ {
isRunning = false; isRunning = false;
} }
if (DevData.FileWatcher.Change) FileChangeNotification* DLLChange = nullptr;
if (DevData.FileWatcher.DLLQueue.pop())
{ {
DevData.FileWatcher.Change = false; // Empty queue to avoid multiple reloads
while (DevData.FileWatcher.DLLQueue.pop()) {}
ShutdownFunc(); ShutdownFunc();
ReloadDLL(); ReloadDLL();
StartupFunc(Shared); StartupFunc(Shared);

View File

@@ -152,6 +152,18 @@ namespace Game
void GameRendering::Update() void GameRendering::Update()
{ {
SharedData& shared = GetShared(); SharedData& shared = GetShared();
FileChangeNotification* shaderChange = nullptr;
while ((shaderChange = shared.Dev.ShaderChangeQueue->pop()))
{
bgfx::destroy(Shader);
VertexBuffer = bgfx::createVertexBuffer(bgfx::makeRef(cubeVertices, sizeof(cubeVertices)), VertLayout);
IndexBuffer = bgfx::createIndexBuffer(bgfx::makeRef(cubeTriList, sizeof(cubeTriList)));
bgfx::ShaderHandle vertexShader = loadShader("vert");
bgfx::ShaderHandle fragmentShader = loadShader("frag");
Shader = bgfx::createProgram(vertexShader, fragmentShader, true);
}
int64_t tickDelta = bx::getHPCounter() - GetInstance().StartTime; int64_t tickDelta = bx::getHPCounter() - GetInstance().StartTime;
double time = tickDelta / double(bx::getHPFrequency()); double time = tickDelta / double(bx::getHPFrequency());
@@ -211,7 +223,7 @@ namespace Game
} }
} }
bgfx::dbgTextPrintf(1, 1, 0x0F, "Time: %.1f", time); bgfx::dbgTextPrintf(1, 1, 0x0F, "Time: %.2f", time);
bgfx::dbgTextPrintf(1, 2, 0x0f, "Frame: %u", GetInstance().FrameCounter); bgfx::dbgTextPrintf(1, 2, 0x0f, "Frame: %u", GetInstance().FrameCounter);
bgfx::frame(); bgfx::frame();