73 lines
1.8 KiB
C++
73 lines
1.8 KiB
C++
// D:\Dev\Mosis\MosisService\designer\src\hot_reload.cpp
|
|
#include "hot_reload.h"
|
|
#include <iostream>
|
|
|
|
#ifdef _WIN32
|
|
#include <Windows.h>
|
|
#endif
|
|
|
|
namespace mosis {
|
|
|
|
HotReload::HotReload(const std::filesystem::path& watch_path, ReloadCallback callback)
|
|
: m_watch_path(watch_path)
|
|
, m_callback(std::move(callback))
|
|
{}
|
|
|
|
HotReload::~HotReload() {
|
|
Stop();
|
|
}
|
|
|
|
void HotReload::Start() {
|
|
if (m_running) return;
|
|
|
|
m_running = true;
|
|
#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 set up file watching" << std::endl;
|
|
m_running = false;
|
|
return;
|
|
}
|
|
#endif
|
|
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
|
|
}
|
|
|
|
void HotReload::WatchThread() {
|
|
while (m_running) {
|
|
#ifdef _WIN32
|
|
DWORD result = WaitForSingleObject(m_notification_handle, 100); // 100ms timeout
|
|
if (result == WAIT_OBJECT_0) {
|
|
// Debounce - wait a bit for file writes to complete
|
|
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
|
if (m_callback) {
|
|
m_callback();
|
|
}
|
|
FindNextChangeNotification(m_notification_handle);
|
|
}
|
|
#else
|
|
// TODO: Linux inotify / macOS FSEvents implementation
|
|
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
|
#endif
|
|
}
|
|
}
|
|
|
|
} // namespace mosis
|