work in progress
This commit is contained in:
93
designer/src/hot_reload.cpp
Normal file
93
designer/src/hot_reload.cpp
Normal file
@@ -0,0 +1,93 @@
|
||||
// Hot-reload file watcher implementation
|
||||
#include "hot_reload.h"
|
||||
#include <iostream>
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <Windows.h>
|
||||
#endif
|
||||
|
||||
namespace mosis::desktop {
|
||||
|
||||
HotReload::HotReload(const std::filesystem::path& watch_path, ReloadCallback callback)
|
||||
: m_watch_path(watch_path)
|
||||
, m_callback(std::move(callback))
|
||||
, m_last_change(std::chrono::steady_clock::now())
|
||||
{}
|
||||
|
||||
HotReload::~HotReload() {
|
||||
Stop();
|
||||
}
|
||||
|
||||
void HotReload::Start() {
|
||||
if (m_running) return;
|
||||
|
||||
#ifdef _WIN32
|
||||
m_notification_handle = FindFirstChangeNotificationW(
|
||||
m_watch_path.c_str(),
|
||||
TRUE, // Watch subtree
|
||||
FILE_NOTIFY_CHANGE_LAST_WRITE
|
||||
);
|
||||
|
||||
if (m_notification_handle == INVALID_HANDLE_VALUE) {
|
||||
std::cerr << "Failed to create file change notification for: "
|
||||
<< m_watch_path << std::endl;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
m_running = true;
|
||||
m_watch_thread = std::thread(&HotReload::WatchThread, this);
|
||||
}
|
||||
|
||||
void HotReload::Stop() {
|
||||
m_running = false;
|
||||
|
||||
if (m_watch_thread.joinable()) {
|
||||
m_watch_thread.join();
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
if (m_notification_handle && m_notification_handle != INVALID_HANDLE_VALUE) {
|
||||
FindCloseChangeNotification(m_notification_handle);
|
||||
m_notification_handle = nullptr;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
bool HotReload::CheckForChanges() {
|
||||
if (m_change_detected) {
|
||||
auto now = std::chrono::steady_clock::now();
|
||||
if (now - m_last_change >= m_debounce_delay) {
|
||||
m_change_detected = false;
|
||||
if (m_callback) {
|
||||
m_callback();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void HotReload::WatchThread() {
|
||||
while (m_running) {
|
||||
#ifdef _WIN32
|
||||
DWORD result = WaitForSingleObject(m_notification_handle, 100); // 100ms timeout
|
||||
if (result == WAIT_OBJECT_0) {
|
||||
m_last_change = std::chrono::steady_clock::now();
|
||||
m_change_detected = true;
|
||||
|
||||
// Reset the notification
|
||||
if (!FindNextChangeNotification(m_notification_handle)) {
|
||||
std::cerr << "FindNextChangeNotification failed" << std::endl;
|
||||
break;
|
||||
}
|
||||
}
|
||||
#else
|
||||
// TODO: Linux inotify / macOS FSEvents implementation
|
||||
// For now, just sleep to avoid busy loop
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace mosis::desktop
|
||||
Reference in New Issue
Block a user