diff --git a/include/HotReload.h b/include/HotReload.h index e8a15bb..1802fdb 100644 --- a/include/HotReload.h +++ b/include/HotReload.h @@ -5,14 +5,20 @@ class HotReload { public: - HotReload(const std::string& filename); - + // Accept either a single script file or a directory to watch. If a directory is + // provided, any change to any file in the directory will trigger a reload. + HotReload(const std::string& pathToWatch); + bool CheckForChanges(); void UpdateLastWriteTime(); private: - std::string scriptFile; + std::string path; std::time_t lastWriteTime; - + std::time_t GetFileWriteTime(const std::string& filename); + // Return the most recent write time found in the watched path. If `path` is a + // directory, this scans all files (non-recursive) and returns the newest + // modification time. If it's a file, it returns that file's write time. + std::time_t GetLatestWriteTimeInPath(); }; \ No newline at end of file diff --git a/scripts/update.as b/scripts/update.as index 97afa74..42dceaa 100644 --- a/scripts/update.as +++ b/scripts/update.as @@ -2,7 +2,7 @@ float x = 50; float y = 100; void Update(float dt) { - x += 50 * dt; + x += 500 * dt; if (x > 800) { x = 0; Print("X position reset!"); @@ -10,4 +10,4 @@ void Update(float dt) { Log(LOG_WARNING, "Log WARNING: reset happened"); Log(LOG_ERROR, "Log ERROR: reset happened"); } -} \ No newline at end of file +}// diff --git a/src/Application.cpp b/src/Application.cpp index 510556d..f435cd4 100644 --- a/src/Application.cpp +++ b/src/Application.cpp @@ -2,6 +2,7 @@ #include "raylib.h" #include #include +#include #include "log/log.h" const char* Application::WINDOW_TITLE = "Raylib + AngelScript"; const char* Application::SCRIPT_FILE = "scripts/test.as"; @@ -28,8 +29,14 @@ bool Application::Initialize() { return false; } - // Initialize hot reload - hotReload = new HotReload(SCRIPT_FILE); + // Initialize hot reload to watch the scripts directory so any script change + // (not just the main file) triggers a reload. + { + std::filesystem::path p(SCRIPT_FILE); + std::string watchPath = p.parent_path().string(); + if (watchPath.empty()) watchPath = "."; + hotReload = new HotReload(watchPath); + } // Compile initial script scriptCompilationError = !scriptEngine.CompileScript(SCRIPT_FILE); diff --git a/src/HotReload.cpp b/src/HotReload.cpp index 90ef84c..ca96ae9 100644 --- a/src/HotReload.cpp +++ b/src/HotReload.cpp @@ -3,21 +3,21 @@ namespace fs = std::filesystem; -HotReload::HotReload(const std::string& filename) : scriptFile(filename), lastWriteTime(0) { +HotReload::HotReload(const std::string& pathToWatch) : path(pathToWatch), lastWriteTime(0) { UpdateLastWriteTime(); } bool HotReload::CheckForChanges() { - std::time_t currentWriteTime = GetFileWriteTime(scriptFile); - if (currentWriteTime != lastWriteTime) { - lastWriteTime = currentWriteTime; + std::time_t current = GetLatestWriteTimeInPath(); + if (current != lastWriteTime) { + lastWriteTime = current; return true; } return false; } void HotReload::UpdateLastWriteTime() { - lastWriteTime = GetFileWriteTime(scriptFile); + lastWriteTime = GetLatestWriteTimeInPath(); } std::time_t HotReload::GetFileWriteTime(const std::string& filename) { @@ -29,4 +29,28 @@ std::time_t HotReload::GetFileWriteTime(const std::string& filename) { } catch (const std::exception&) { return 0; } +} + +std::time_t HotReload::GetLatestWriteTimeInPath() { + try { + fs::path p(path); + if (fs::is_regular_file(p)) { + return GetFileWriteTime(path); + } + + // If it's a directory, scan files (non-recursively) and return the + // newest write time found. + if (fs::is_directory(p)) { + std::time_t newest = 0; + for (auto &entry : fs::directory_iterator(p)) { + if (!fs::is_regular_file(entry.path())) continue; + std::time_t t = GetFileWriteTime(entry.path().string()); + if (t > newest) newest = t; + } + return newest; + } + } catch (const std::exception&) { + // fall through + } + return 0; } \ No newline at end of file diff --git a/src/log/log.c b/src/log/log.c index fd30a59..ef058a4 100644 --- a/src/log/log.c +++ b/src/log/log.c @@ -21,6 +21,7 @@ */ #include "log.h" +#include // for memcpy #define MAX_CALLBACKS 32 @@ -187,6 +188,14 @@ static void init_event(log_Event *ev, void *udata) } void log_log(int level, const char *file, int line, const char *fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + log_vlog(level, file, line, fmt, ap); + va_end(ap); +} + +void log_vlog(int level, const char *file, int line, const char *fmt, va_list ap) { log_Event ev = { .fmt = fmt, @@ -200,9 +209,11 @@ void log_log(int level, const char *file, int line, const char *fmt, ...) if (!L.quiet && level >= L.level) { init_event(&ev, stderr); - va_start(ev.ap, fmt); + va_list ap_copy; + va_copy(ap_copy, ap); + memcpy(&ev.ap, &ap_copy, sizeof(va_list)); stdout_callback(&ev); - va_end(ev.ap); + va_end(ap_copy); } for (int i = 0; i < MAX_CALLBACKS && L.callbacks[i].fn; i++) @@ -211,9 +222,11 @@ void log_log(int level, const char *file, int line, const char *fmt, ...) if (level >= cb->level) { init_event(&ev, cb->udata); - va_start(ev.ap, fmt); + va_list ap_copy; + va_copy(ap_copy, ap); + memcpy(&ev.ap, &ap_copy, sizeof(va_list)); cb->fn(&ev); - va_end(ev.ap); + va_end(ap_copy); } } @@ -222,5 +235,5 @@ void log_log(int level, const char *file, int line, const char *fmt, ...) void raylib_log(int msgType, const char *text, va_list args) { - log_log(msgType, NULL, 0, text, args); + log_vlog(msgType, NULL, 0, text, args); } \ No newline at end of file diff --git a/src/log/log.h b/src/log/log.h index 6d62bc6..b02be28 100644 --- a/src/log/log.h +++ b/src/log/log.h @@ -48,6 +48,8 @@ int log_add_callback(log_LogFn fn, void *udata, int level); int log_add_fp(FILE *fp, int level); void log_log(int level, const char *file, int line, const char *fmt, ...); +// Variant that accepts a va_list for backends that already receive va_list +void log_vlog(int level, const char *file, int line, const char *fmt, va_list ap); void raylib_log(int msgType, const char *text, va_list args);