Repository navigation
File Watcher
File and directory change notification system using timestamp polling, with callbacks for asset hot-reload, script hot-reload, and configuration reloading.
Source: SparkEngine/Source/Utils/FileWatcher/FileWatcher.h
The File Watcher monitors files and directories for changes by polling filesystem timestamps at a configurable interval. When a file is created, modified, or deleted, the system fires a registered callback with a FileChangeEvent containing the file path, change type, and new size. This drives the engine's hot-reload pipeline for scripts, assets, data tables, and configuration files.
Directory watches scan the file tree on initialization to establish a baseline, then compare timestamps on each poll cycle. New files trigger Created events, changed timestamps trigger Modified events, and missing files trigger Deleted events. Watches can be filtered by file extension (e.g., only .csv or .as files) and optionally limited to non-recursive scanning. Individual file watches track a single path with the same create/modify/delete detection.
The system is designed to be called once per frame via Update(deltaTime). The poll interval prevents excessive filesystem access -- typically set to 0.5-2.0 seconds depending on the use case. Each watch returns an ID that can be used to stop watching later.
| Class / Struct | Description |
|---|---|
FileWatcher |
Singleton that manages watches and polls the filesystem each frame |
FileChangeEvent |
Event payload: full path, relative path, change type, new file size |
FileChangeType |
Enum: Created, Modified, Deleted
|
WatchEntry |
Internal watch record: path, directory flag, extension filter, tracked files, callback |
TrackedFile |
Internal per-file state: path, last write time, size, existence flag |
auto& watcher = Spark::Utils::FileWatcher::GetInstance();
watcher.Initialize(1.0f); // poll every 1 second
// Watch a directory for script changes (hot-reload)
auto scriptWatch = watcher.Watch("Assets/Scripts/", [](const Spark::Utils::FileChangeEvent& e) {
if (e.type == Spark::Utils::FileChangeType::Modified)
ReloadScript(e.path);
else if (e.type == Spark::Utils::FileChangeType::Created)
LoadNewScript(e.path);
}, ".as"); // only AngelScript files
// Watch a directory for texture changes
auto textureWatch = watcher.Watch("Assets/Textures/", [](const Spark::Utils::FileChangeEvent& e) {
if (e.type != Spark::Utils::FileChangeType::Deleted)
ReloadTexture(e.path);
}, ".png", /*recursive=*/true);
// Watch a single config file
auto configWatch = watcher.WatchFile("config.ini", [](const Spark::Utils::FileChangeEvent& e) {
if (e.type == Spark::Utils::FileChangeType::Modified)
ReloadConfig();
});
// In the main loop
void MainLoop(float deltaTime)
{
watcher.Update(deltaTime);
// ...
}
// Stop watching when no longer needed
watcher.Unwatch(scriptWatch);| Method | Return | Description |
|---|---|---|
Initialize(pollIntervalSeconds) |
void |
Initialize with the given poll interval (default 1.0s) |
Shutdown() |
void |
Remove all watches and shut down |
| Method | Return | Description |
|---|---|---|
Watch(dirPath, callback, extFilter, recursive) |
uint32_t |
Watch a directory; returns watch ID |
WatchFile(filePath, callback) |
uint32_t |
Watch a single file; returns watch ID |
Unwatch(watchId) |
void |
Stop watching a path |
| Method | Return | Description |
|---|---|---|
Update(deltaTime) |
void |
Poll for changes; call once per frame |
GetWatchCount() |
size_t |
Number of active watches |
GetTrackedFileCount() |
size_t |
Total tracked files across all watches |
SetPollInterval(seconds) |
void |
Change the poll interval (minimum 0.1s) |
| Field | Type | Description |
|---|---|---|
path |
string |
Full filesystem path to the changed file |
relativePath |
string |
Path relative to the watched directory |
type |
FileChangeType |
Created, Modified, or Deleted
|
newSize |
uint64_t |
New file size in bytes (0 if deleted) |
- AngelScript Scripting -- script hot-reload is triggered by FileWatcher
- Asset Dependency Graph -- graph updates when assets change on disk
- Asset Browser -- refreshes file listings on directory change events
- Editor Automation -- automation scripts can register file watches
Published from 2b03dc797148. Edit the canonical source in wiki/.
- Documentation
- Docs route
- Wiki index
- Guides
- Tutorials
- Samples
- Examples
- API Reference
- API route
- Reference
- Build Guide
- Dependencies
- FAQ
- Changelog
- Roadmap
- Contributing
- Code of Conduct
- Home
- FAQ
- Getting Started
- Quick-Start Tutorial
- Making Your First Game
- Making Your First Multiplayer Game
- Artist Workflow Guide
- Editor Walkthrough
- Migration Guide
- How SparkEngine Works
- Architecture Overview
- Engine Architecture Flowchart
- Creating a Game Module
- Game Modules (catalog)
- Entity Component System
- Rendering and Graphics
- Physics
- Cloth Simulation
- Audio
- Input System
- Camera System
- Scripting with AngelScript
- Visual Scripting
- AI and Navigation
- Animation
- 2D Systems
- Networking
- Dedicated Server
- Multiplayer Quick Start
- Area Server Architecture
- Scene Management
- Large World Support
- Collaborative Editing
- Coroutine System
- Event System
- Event Response System
- Job System
- UI System
- UI Layout Extensions
- Localization
- Dialogue System
- Destruction System
- Replay System
- Achievement System
- Loading System
- Mod System
- Content Delivery
- Tween System
- Memory Integrity
- Gameplay Systems
- Terrain and Procedural Generation
- Save System
- Persistence System
- Day Night Cycle and Weather
- Cinematic Sequencer
- Runtime Prefabs
- SparkEditor
- Editor Tutorials
- SparkConsole
- SparkDaemon
- Shader Pipeline
- Asset Pipeline
- Asset Validation
- Asset Migration
- Game Packaging
- Online Services
- DataTable System
- Loot and Crafting System
- CSG System
- Font System
- Timer Manager
- Movie Render Pipeline
- HLOD and World Partition
- Remote Debug System
- Selection Manager
- Asset Dependency Graph
- Editor Automation
- File Watcher
- Project Templates
- System Requirements
- VR Support
- Mobile Platform
- Accessibility
- Platform Input
- Platform Certification
- Cross-Compilation: Wine Testing
- RHI Abstraction Layer
- D3D11 Backend
- D3D12 Backend
- Vulkan Backend
- OpenGL Backend
- Metal Backend
- DXR Raytracing
- Hybrid Ray Tracing
- Upscaling (DLSS/FSR)
- Render Graph
- Shader Graph
- GPU Particles
- GPU-Driven Rendering
- Volumetric Fog
- Volumetric Clouds
- Global Illumination
- Virtual Texturing
- Water Rendering
- Clustered Lighting
- Material System
- Post-Processing
- Shadow System
- Particle System
- Decal System
- Sky and Atmosphere
- Foliage System
- Mesh Shaders
- Neural Rendering
- Configuration Reference
- Performance Tips
- Benchmark Framework
- Threading Model
- Fuzz Policy and Parser Security
- Memory Safety
- Memory Management Patterns
- Build System and CMake Modules
- Profiler and Debugging
- Performance Profiling Guide
- Telemetry System
- Crash Reporting
- Golden Image Testing
- Utilities
- Testing
- Fuzz Policy and Parser Security
- Codebase Statistics
- Codebase Health
- Error Handling Patterns
- Hot Reload Overview
- Troubleshooting
- Contributing
- Workflow Patterns
- Build Optimizations
- CI Reproducible Builds
- GitHub API and PR Checks
- Git Rebase Conflicts
- Clang-Format
- Code Quality Violations
- AI Bloat Pattern
- MinGW + Wine Cross-Compilation
- Live Editor Testing
- Engine & Renderer Landscape
- DuetOS Portability Catalog
- Five-Engine Analysis
- Eleven-Engine Analysis
- ThorVG / Unity Graphics Analysis
- Advanced Techniques Catalog
- Third-Party Library Evaluation
- Engine Viability Evaluation
- Engine Feature Recommendations
- Project Recommendations
- Mac Compatibility Analysis
- Codebase Observations
- Codebase Bloat Audit
- Test Suite Audit
- Documentation Coverage Audit
- ThirdParty Dependencies Audit
- Load Test Baseline
- Gameplay Systems Status
- SparkGame Module Status
- Stub and Abandoned Features
- Memory Integrity System
- Memory Safety Evaluation
- Hardware Acceleration Systems
- Jolt Physics Integration
- GPU/CPU Separation Plan
- Daemon Services Architecture
- Reflection & Polymorphism Refactoring Plan
- SparkBuild In-Tree
- Wine No-JobSystem Breakthrough
- Wine Role and Fallback Tiers