feat: phase 1 complete - dependency system, cascade unload, pending queue (v1.0.0-pre.1)

This commit is contained in:
2026-03-06 22:13:35 +01:00
parent 6477cde367
commit 2e2c3d5e9e
4 changed files with 85 additions and 17 deletions
+28 -1
View File
@@ -7,6 +7,31 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased]
## [1.0.0-pre.1] - 2026-03-06
### Added
- **Dependency System**: Full module dependency declaration and resolution
- Modules declare dependencies via an exported `stk_mod_deps` symbol, no stk headers required in modules, only the memory layout contract must be respected (`{ char[64], char[32] }` sentinel-terminated array)
- Version constraint operators: `=` (exact), `>=` (minimum, default), `^` (compatible — same major, greater or equal minor/patch)
- Version defaults to `0.0.0` if not provided or unparseable
- Dependency validation on `stk_init` and every `stk_poll` cycle
- Topological sort with cycle detection, load and unload ordering enforced
- All dependency failures logged before returning
- **Cascade Unload**: When a module is removed, all dependents cascade unload automatically and are added to the pending queue. Cascades repeat until the loaded set is stable
- **Pending Queue**: Modules that fail dependency validation are deferred. When their dependencies become available they are retried and loaded automatically. Entries are removed if their file is deleted
### Changed
- `stk_set_module_dependencies_fn` renamed to `stk_set_module_deps_sym`. Deps are now an exported array symbol, not a function
- Default deps symbol name changed from `stk_mod_dependencies` to `stk_mod_deps`
- `stk_dep_t` added to public header `stk.h`
- `stk_mod_t` field order changed to largest-to-smallest for correct memory alignment with zero padding waste
- Dependency validation failure during `stk_init` no longer fatal, affected modules are deferred to the pending queue
- Poll cycle now logs the full loaded module list as a single summary after any event that changes the loaded set, instead of logging each module individually
### Notes
- This release marks Phase 1 complete: hot-reloading foundation with dependency management
- Memory layout contract for `stk_mod_deps`: sentinel-terminated array of `{ char[64], char[32] }`. Modules do not need to include `stk.h`, define the struct inline or via your engine's own header as long as the layout matches
## [0.1.3] - 2026-02-25
### Added
@@ -115,7 +140,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Dependency management and versioning not yet implemented
- API is unstable and subject to change in future releases
[Unreleased]: https://github.com/anth64/stk/compare/v0.1.2...HEAD
[Unreleased]: https://github.com/anth64/stk/compare/v1.0.0-pre.1...HEAD
[1.0.0-pre.1]: https://github.com/anth64/stk/compare/v0.1.3...v1.0.0-pre.1
[0.1.3]: https://github.com/anth64/stk/releases/tag/v0.1.3
[0.1.2]: https://github.com/anth64/stk/releases/tag/v0.1.2
[0.1.1]: https://github.com/anth64/stk/releases/tag/v0.1.1
[0.1.1]: https://github.com/anth64/stk/releases/tag/v0.1.1
+50 -9
View File
@@ -131,6 +131,42 @@ cc -shared -o my_module.dll my_module.c
Place the compiled module in the `mods/` directory (default), and `stk` will automatically load it and watch for changes.
### Module Metadata
Modules can optionally export metadata functions:
```c
const char *stk_mod_name(void) { return "My Module"; }
const char *stk_mod_version(void) { return "1.2.0"; }
const char *stk_mod_description(void) { return "Does something useful"; }
```
All three are optional. Version defaults to `0.0.0` if not exported or unparseable.
### Declaring Dependencies
Modules declare dependencies via an exported sentinel-terminated array. No stk headers are required in the module. The only requirement is that the memory layout matches: `{ char[64], char[32] }`.
```c
typedef struct {
char id[64];
char version[32];
} dep_t;
dep_t stk_mod_deps[] = {
{ "physics", ">=2.0.0" },
{ "renderer", "^1.0.0" },
{ "", "" } /* sentinel */
};
```
Version constraint operators:
- `=1.0.0` exact match
- `>=2.0.0` minimum version, also the default if no operator is specified
- `^1.0.0` same major, greater or equal minor/patch
If a dependency is removed at runtime, all affected modules are unloaded and queued. When the dependency comes back, they load automatically.
### Configuration
```c
@@ -146,15 +182,18 @@ stk_set_module_init_fn("my_init");
/* Set custom shutdown function name (default: "stk_mod_shutdown") */
stk_set_module_shutdown_fn("my_shutdown");
/* Set function name to get module name */
/* Set function name to get module name (default: "stk_mod_name") */
stk_set_module_name_fn("my_mod_name");
/* Set function name to get module version */
/* Set function name to get module version (default: "stk_mod_version") */
stk_set_module_version_fn("my_mod_version");
/* Set function name to get module description */
/* Set function name to get module description (default: "stk_mod_description") */
stk_set_module_description_fn("my_mod_description");
/* Set deps array symbol name (default: "stk_mod_deps") */
stk_set_module_deps_sym("my_mod_deps");
/*
* All the above functions must be called before stk_init()
* if the defaults need to be changed.
@@ -180,7 +219,7 @@ stk_init();
- `void stk_set_module_name_fn(const char *name);` - Set module name function name
- `void stk_set_module_version_fn(const char *name);` - Set module version function name
- `void stk_set_module_description_fn(const char *name);` - Set module description function name
- `void stk_set_module_dependencies_fn(const char *name);` - Set module dependencies function name
- `void stk_set_module_deps_sym(const char *name)` - Set module deps array symbol name (default: `stk_mod_deps`)
#### Logging
- `void stk_set_logging_enabled(unsigned char enabled)` - Enable/disable all logging
@@ -195,9 +234,7 @@ stk_init();
## Project Status
**Current Version:** 0.1.3 (Pre-release)
Added optional module metadata support.
**Current Version:** 1.0.0-pre.1
### What Works
- Cross-platform module loading and hot-reloading
@@ -206,9 +243,13 @@ Added optional module metadata support.
- Enhanced logging with levels, timestamps, and filtering
- Runtime-configurable logging behavior
- Optional module metadata (name, version, description)
- Dependency declaration, validation, and versioning
- Cascade unload when dependencies are removed
- Pending queue with automatic retry when deps become available
- Topological sort with cycle detection
### In Progress (Phase 1)
- Dependency management and versioning
### Phase 2
- WASM module support
See [CHANGELOG.md](CHANGELOG.md) for detailed release notes.
+3 -3
View File
@@ -1,9 +1,9 @@
#ifndef STK_VERSION_H
#define STK_VERSION_H
#define STK_VERSION_MAJOR 0
#define STK_VERSION_MINOR 1
#define STK_VERSION_PATCH 3
#define STK_VERSION_MAJOR 1
#define STK_VERSION_MINOR 0
#define STK_VERSION_PATCH 0
#define STK_STRINGIFY_HELPER(x) #x
#define STK_STRINGIFY(x) STK_STRINGIFY_HELPER(x)
+4 -4
View File
@@ -497,18 +497,18 @@ validate_deps:
break;
for (j = 0; j < cascade_count; j++) {
size_t idx = cascade_indices[j];
size_t index = cascade_indices[j];
stk_log(STK_LOG_WARN,
"Unloading '%s': unmet dependencies",
stk_modules[idx].id);
stk_modules[index].id);
build_path(cascade_tmp_path,
sizeof(cascade_tmp_path),
stk_tmp_dir, stk_modules[idx].id);
stk_tmp_dir, stk_modules[index].id);
strncat(cascade_tmp_path, STK_MODULE_EXT,
sizeof(cascade_tmp_path) -
strlen(cascade_tmp_path) - 1);
stk_pending_add(cascade_tmp_path);
stk_module_unload(idx);
stk_module_unload(index);
}
cascade_write = 0;