aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorladevieq <ladevie.quentin@gmail.com>2022-07-20 00:09:03 +0200
committerladevieq <ladevie.quentin@gmail.com>2022-07-20 00:09:03 +0200
commite77054b80568f65aaf8a6201cf8432d000288209 (patch)
tree845f38235652b11ef8c435f48b95005616b33fea /src
parent9cf2e341adfdb389c0dd8eb9a621d83ccba78826 (diff)
Add file watching api
Diffstat (limited to 'src')
-rw-r--r--src/main.cpp29
-rw-r--r--src/utils.cpp90
2 files changed, 116 insertions, 3 deletions
diff --git a/src/main.cpp b/src/main.cpp
index 1c83ce8..368a429 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -12,6 +12,7 @@
#include "scene.hpp"
#include "vk-renderer.hpp"
#include "window.hpp"
+#include "utils.hpp"
#include "Tracy.hpp"
@@ -79,7 +80,31 @@ int main() {
auto main_scene = scene(cam, width, height, renderer);
auto *raytracing_pass = renderer.create_compute_renderpass();
- raytracing_pass->set_pipeline(raytracing_shader_name);
+ raytracing_pass->set_pipeline("compute");
+
+ watcher::watch_file(std::filesystem::path("../shaders/compute.comp"), [&]() {
+ LPSTR cmd_line = "glslc.exe --target-env=vulkan1.2 -std=460 ../shaders/compute.comp -o shaders/compute.comp.spv -I \"../shaders/include\"\0";
+ STARTUPINFO start_info {};
+ PROCESS_INFORMATION proc_info {};
+ if (FAILED(CreateProcessA(
+ nullptr,
+ cmd_line,
+ nullptr,
+ nullptr,
+ FALSE,
+ 0,
+ nullptr,
+ nullptr,
+ &start_info,
+ &proc_info
+ )))
+ log_last_error();
+ WaitForSingleObject(proc_info.hProcess, INFINITE);
+ CloseHandle(proc_info.hProcess);
+ CloseHandle(proc_info.hThread);
+
+ raytracing_pass->set_pipeline("compute");
+ });
auto *accumulation_texture = renderer.create_2d_texture(width, height, VK_FORMAT_R32G32B32A32_SFLOAT);
auto *output_texture = renderer.create_2d_texture(width, height, VK_FORMAT_R32G32B32A32_SFLOAT);
@@ -124,6 +149,8 @@ int main() {
io.DeltaTime = delta_time;
+ watcher::pull_changes();
+
wnd.poll_events();
for (auto &event : wnd.events) {
diff --git a/src/utils.cpp b/src/utils.cpp
index dc5791c..9994064 100644
--- a/src/utils.cpp
+++ b/src/utils.cpp
@@ -45,6 +45,92 @@ std::vector<uint8_t> read_file(const char* path) {
return file_content;
}
-std::vector<uint8_t> read_file(std::string& path) {
- return read_file(path.c_str());
+
+#ifdef WINDOWS
+void log_last_error() {
+ auto error_code = GetLastError();
+ const char* error_message = nullptr;
+
+ FormatMessageA(
+ FORMAT_MESSAGE_ALLOCATE_BUFFER |
+ FORMAT_MESSAGE_FROM_SYSTEM |
+ FORMAT_MESSAGE_IGNORE_INSERTS,
+ nullptr,
+ error_code,
+ MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+ (LPTSTR) &error_message,
+ 0,
+ nullptr
+ );
+
+ std::cerr << error_message << std::endl;
}
+
+bool watcher::watch_file(std::filesystem::path&& filepath, std::function<void()> callback) {
+ if (!std::filesystem::exists(filepath))
+ return false;
+
+ if (!watcher::watch_dir(filepath.parent_path()))
+ return false;
+
+ auto [_, is_inserted] = watcher::callbacks.emplace(filepath.filename().string(), callback);
+
+ return is_inserted;
+}
+
+bool watcher::watch_dir(std::filesystem::path&& dir_path) {
+ if (!std::filesystem::exists(dir_path))
+ return false;
+
+ if (watcher::watched_dirs.find(dir_path.string()) != watcher::watched_dirs.end())
+ return true;
+
+ HANDLE dir_handle = CreateFileW(
+ dir_path.c_str(),
+ FILE_LIST_DIRECTORY,
+ FILE_SHARE_WRITE | FILE_SHARE_READ,
+ nullptr,
+ OPEN_EXISTING,
+ FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OVERLAPPED,
+ nullptr
+ );
+
+ if(dir_handle == INVALID_HANDLE_VALUE) {
+ log_last_error();
+ return false;
+ }
+
+ auto [dir, _] = watcher::watched_dirs.emplace(dir_path.string(), watch_data{ .dir_handle = dir_handle });
+
+ if (FAILED(ReadDirectoryChangesW(dir_handle, dir->second.buffer, sizeof(watch_data::buffer), FALSE, FILE_NOTIFY_CHANGE_LAST_WRITE, nullptr, &dir->second.overlapped, nullptr))) {
+ log_last_error();
+ return false;
+ }
+
+ return true;
+}
+
+void watcher::pull_changes() {
+ for (auto& dir : watcher::watched_dirs) {
+ auto& watch_data = dir.second;
+ if (!HasOverlappedIoCompleted(&watch_data.overlapped))
+ continue;
+
+ auto* dir_event = (PFILE_NOTIFY_INFORMATION)watch_data.buffer;
+ do {
+ if (dir_event->Action == FILE_ACTION_MODIFIED) {
+ auto w_filename = std::wstring{ dir_event->FileName, dir_event->FileNameLength / sizeof(wchar_t) };
+ auto filename = std::string{w_filename.begin(), w_filename.end()};
+ if (callbacks.contains(filename))
+ callbacks[filename]();
+ }
+
+ dir_event += dir_event->NextEntryOffset;
+ } while(dir_event->NextEntryOffset != 0);
+
+ if (FAILED(ReadDirectoryChangesW(watch_data.dir_handle, watch_data.buffer, sizeof(watch_data::buffer), FALSE, FILE_NOTIFY_CHANGE_LAST_WRITE, nullptr, &watch_data.overlapped, nullptr))) {
+ log_last_error();
+ }
+ }
+}
+#endif