summaryrefslogtreecommitdiff
path: root/doc
diff options
context:
space:
mode:
authorskal <pascal.massimino@gmail.com>2026-02-09 17:35:32 +0100
committerskal <pascal.massimino@gmail.com>2026-02-09 17:35:32 +0100
commitd5f78a4c2e7b626a492643efd62ddeb394276722 (patch)
treecdf38c3d64f6bf417975ce396572fc425d6f8910 /doc
parent802e97ee695de1bc8657c5cbca653bb2f13b90a8 (diff)
feat: Add debug-only file change detection for rapid iteration
Enables --hot-reload flag to watch config files and notify on changes. Detects modifications to assets/sequences/music for rebuild workflow. Completely stripped from release builds (0 bytes overhead). Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Diffstat (limited to 'doc')
-rw-r--r--doc/HOT_RELOAD.md162
1 files changed, 162 insertions, 0 deletions
diff --git a/doc/HOT_RELOAD.md b/doc/HOT_RELOAD.md
new file mode 100644
index 0000000..681d0aa
--- /dev/null
+++ b/doc/HOT_RELOAD.md
@@ -0,0 +1,162 @@
+# Hot-Reload System
+
+## Overview
+
+The hot-reload system enables rapid iteration during development by detecting changes to configuration files at runtime. This feature is **debug-only** and completely stripped from release builds (adds 0 bytes to final binary).
+
+## Status
+
+**Implemented:**
+- File change detection (`FileWatcher` class)
+- Command-line flag `--hot-reload`
+- Notification when config files change
+
+**Not Implemented (Requires Rebuild):**
+- Asset reloading (`assets/final/demo_assets.txt`)
+- Sequence reloading (`assets/demo.seq`)
+- Music reloading (`assets/music.track`)
+
+Currently, the system **detects** file changes and informs the user to rebuild. Full runtime reload would require significant refactoring of the compile-time asset system.
+
+## Usage
+
+```bash
+# Launch with hot-reload enabled
+./build/demo64k --hot-reload
+
+# Edit config files while running
+vim assets/demo.seq
+
+# Demo will print:
+# [Hot-Reload] Config files changed - rebuild required
+# [Hot-Reload] Run: cmake --build build -j4 && ./build/demo64k
+```
+
+## Architecture
+
+### File Watcher (`src/util/file_watcher.h`)
+
+Simple polling-based file change detection using `stat()` mtime:
+
+```cpp
+#if !defined(STRIP_ALL)
+FileWatcher watcher;
+watcher.add_file("assets/demo.seq");
+
+if (watcher.check_changes()) {
+ // File changed
+ watcher.reset();
+}
+#endif
+```
+
+**Design:**
+- Polls file mtimes in main loop (~60Hz)
+- Cross-platform (POSIX stat)
+- 1-second mtime granularity (filesystem dependent)
+
+**Watched Files:**
+- `assets/final/demo_assets.txt` - Asset definitions
+- `assets/demo.seq` - Visual effect timeline
+- `assets/music.track` - Audio patterns
+
+### Integration (`src/main.cc`)
+
+```cpp
+#if !defined(STRIP_ALL)
+bool hot_reload_enabled = false;
+
+// Command-line parsing
+if (strcmp(argv[i], "--hot-reload") == 0) {
+ hot_reload_enabled = true;
+}
+
+// Setup
+FileWatcher file_watcher;
+if (hot_reload_enabled) {
+ file_watcher.add_file("assets/final/demo_assets.txt");
+ file_watcher.add_file("assets/demo.seq");
+ file_watcher.add_file("assets/music.track");
+}
+
+// Main loop
+if (hot_reload_enabled && file_watcher.check_changes()) {
+ printf("[Hot-Reload] Config files changed - rebuild required\n");
+ file_watcher.reset();
+}
+#endif
+```
+
+## Why Not Full Reload?
+
+The current architecture compiles all assets at build time:
+
+1. **Assets** (`demo_assets.txt`):
+ - Parsed by `asset_packer` tool
+ - Generates C++ arrays in `generated/assets.h`
+ - Linked into binary as static data
+ - Runtime reload would need file I/O + dynamic memory
+
+2. **Sequences** (`demo.seq`):
+ - Parsed by `seq_compiler` tool
+ - Generates `LoadTimeline()` function in C++
+ - Effect objects created with compile-time parameters
+ - Runtime reload would need C++ code generation or scripting
+
+3. **Music** (`music.track`):
+ - Parsed by `tracker_compiler` tool
+ - Generates static pattern/score data
+ - Referenced by pointers in audio engine
+ - Runtime reload needs atomic pointer swap + memory management
+
+Implementing full reload would require:
+- Runtime parsers (duplicate build-time compilers)
+- Dynamic memory allocation (conflicts with size optimization)
+- Effect state preservation (complex)
+- Thread-safe audio data swap
+- ~20-25 hours of work (per the plan)
+
+## Size Impact
+
+**Debug build:** +800 bytes (FileWatcher + main loop logic)
+**STRIP_ALL build:** 0 bytes (all code removed by `#if !defined(STRIP_ALL)`)
+
+## Testing
+
+Unit test: `src/tests/test_file_watcher.cc`
+
+```bash
+# Run test
+cd build && ctest -R FileWatcherTest
+
+# Note: Test sleeps 1 second to ensure mtime changes
+# (some filesystems have 1s mtime granularity)
+```
+
+## Future Work
+
+If hot-reload becomes critical for workflow, consider:
+
+1. **Incremental approach:**
+ - Phase 1: Asset cache clearing (easy, limited value)
+ - Phase 2: Sequence state preservation (medium, high value)
+ - Phase 3: Tracker atomic swap (hard, high value)
+
+2. **External scripting:**
+ - Watch files externally (fswatch/inotifywait)
+ - Auto-rebuild + restart demo
+ - Preserves current architecture
+
+3. **Hybrid approach:**
+ - Keep compile-time for release
+ - Add optional runtime parsers for debug
+ - Conditional on `--hot-reload` flag
+
+## Related Files
+
+- `src/util/file_watcher.h` - File change detection API
+- `src/util/file_watcher.cc` - Implementation
+- `src/util/asset_manager.cc` - Stub `ReloadAssetsFromFile()` (clears cache)
+- `src/main.cc` - Main loop integration
+- `src/tests/test_file_watcher.cc` - Unit tests
+- `CMakeLists.txt` - Build system integration