- Add DesktopSandbox class that integrates timer, JSON, crypto, and VirtualFS APIs - Fix mouse coordinate handling: GLFW reports window coordinates, not physical pixels - Fix font path resolution to search multiple locations for test apps - Fix screenshot capture timing (capture before buffer swap) - Fix test app CSS: use border-width instead of border:none, add display:block - Fix test app Lua: add document nil checks, use HTML entities for symbols - Update hot_reload to reset sandbox state on reload Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
101 lines
2.7 KiB
C++
101 lines
2.7 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
|
|
// Create a manual-reset event for signaling shutdown
|
|
m_stop_event = CreateEventW(nullptr, TRUE, FALSE, nullptr);
|
|
if (!m_stop_event) {
|
|
std::cerr << "Failed to create stop event" << std::endl;
|
|
m_running = false;
|
|
return;
|
|
}
|
|
|
|
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;
|
|
CloseHandle(m_stop_event);
|
|
m_stop_event = nullptr;
|
|
m_running = false;
|
|
return;
|
|
}
|
|
#endif
|
|
m_watch_thread = std::thread(&HotReload::WatchThread, this);
|
|
}
|
|
|
|
void HotReload::Stop() {
|
|
m_running = false;
|
|
#ifdef _WIN32
|
|
// Signal the stop event to wake up the watch thread
|
|
if (m_stop_event) {
|
|
SetEvent(m_stop_event);
|
|
}
|
|
#endif
|
|
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;
|
|
}
|
|
if (m_stop_event) {
|
|
CloseHandle(m_stop_event);
|
|
m_stop_event = nullptr;
|
|
}
|
|
#endif
|
|
}
|
|
|
|
void HotReload::WatchThread() {
|
|
while (m_running) {
|
|
#ifdef _WIN32
|
|
// Wait on both the file change notification and the stop event
|
|
HANDLE handles[2] = { m_notification_handle, m_stop_event };
|
|
DWORD result = WaitForMultipleObjects(2, handles, FALSE, INFINITE);
|
|
|
|
if (result == WAIT_OBJECT_0) {
|
|
// File change notification
|
|
// Debounce - wait a bit for file writes to complete
|
|
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
|
if (m_callback && m_running) {
|
|
m_callback();
|
|
}
|
|
FindNextChangeNotification(m_notification_handle);
|
|
} else if (result == WAIT_OBJECT_0 + 1) {
|
|
// Stop event signaled - exit the loop
|
|
break;
|
|
}
|
|
// WAIT_FAILED or other errors will just loop and check m_running
|
|
#else
|
|
// TODO: Linux inotify / macOS FSEvents implementation
|
|
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
|
#endif
|
|
}
|
|
}
|
|
|
|
} // namespace mosis
|