feat(mod): 完成外部 DLL 事务热替换

This commit is contained in:
2026-08-16 23:52:53 +08:00
parent ad256f109b
commit de5ab449cd
23 changed files with 416 additions and 18 deletions
+6 -5
View File
@@ -238,13 +238,14 @@ await loader.ApplyConfigAsync(configTree); // 增量协调:diff → reload/u
**阶段 3 保留边界**ClassicHost 与静态服务门面仍作为兼容层存在;Command-Network 的服务 handler 暂无逐项注销 API;全局静态桥在多根上下文并行时仍需引用计数或实例化。这些不阻塞单默认根主路径,但不能误写成完全隔离保证。
### 阶段 4ModFramework 合流 + 热替换 🔶 第一片完成(2026-08-16
### 阶段 4ModFramework 合流 + 热替换 完成(2026-08-16
- 新增 `ShrinkModComponentSource` / `ShrinkModContextHost`:将 `IShrinkMod` 的构造、注册、初始化、Ready 生命周期纳入 Cordis apply;模组效应通过本地逆操作登记,Registry、Network handler、Harmony lease 均可随组件退役清理。
- 事务单位固定为 `ModId + revision`:同一 revision 幂等复用;替换失败时保留 `LastError` 并重新应用上一组 source,旧模组实例、generation 与已登记内容恢复。
- 外部 DLL 按 SHA-256 扫描当前 revision;文件内容变化创建新的组件源,旧程序集仍驻留但不会继续被发现,坏 DLL 不覆盖当前有效 revision。Unity 程序集不可卸载,因此回滚单位是组件实例与效应,不是类型
- 外部 DLL 按 SHA-256 扫描当前 revision;文件内容变化创建新的组件源,旧程序集仍驻留但不会继续被发现,坏 DLL 不覆盖当前有效 revision。扫描状态随 Host 事务一起快照/恢复,失败替换不会把失败 revision 留在当前缓存中
- `ShrinkModLoader` 默认走 `ShrinkModContextHost``useContextHost=false` 保留旧加载路径作为兼容边界。Harmony 在 ContextHost 路径取得可逆 lease,旧路径仍是一次性应用。
- 当前验收:ModFramework ContextHost 5/5 EditMode;真实 Starter PlayMode 确认 `modCordis=true`、宿主 7 个模块 active 且无错误
- **阶段 4 剩余**:补一组真实编译外部 DLL 的 watcher 场景(valid → changedfailed → restore),再覆盖 watcher debounce、缓存失效与依赖导入失败;不把“程序集未卸载”伪装成已解决
- `ShrinkModRuntimeDriver` 监听新增、修改、删除、重命名,并用独立 debouncer 把 burst 事件折叠为一次主线程 reload;删除文件会提交完整期望组合,依赖缺失在协调前拒绝并保留旧组合
- 真实 fixture 验收覆盖:编译 DLL `valid → changed(fail) → restore`、损坏字节不污染当前 revision、有效 revision 恢复、watcher burst 去抖、删除卸载、依赖 DLL 删除/恢复。`ShrinkModFramework.Tests` **9/9**,全仓 EditMode **180/180**
- 真实 Starter PlayMode 确认 `modCordis=true``modLoaded=true`、宿主 7 个模块 active 且无错误。Unity 程序集不可卸载,因此回滚单位仍是组件实例与效应,而不是类型本身。
### 阶段 5:隔离与拦截(可选增强)
- 测试域 isolate(同一份组件在多个隔离域各跑一份);intercept 做访问控制(社区模组只读 DataSaver)。
@@ -267,4 +268,4 @@ await loader.ApplyConfigAsync(configTree); // 增量协调:diff → reload/u
- ShrinkSDK 与 Cordis 的**分层直觉一致**(核心库 / 编排层 / 领域层),差距集中在**核心库的两个原语缺失**:统一可逆效应追踪(时间)与响应式依赖解析(空间)。
- 改造的本质不是重写功能模块,而是**把 ShrinkApp 的"一次性安装器"升级为 Cordis 的"持续协调的组件加载器"**,并让七个 Integration 桥接包退化为薄适配直至消失。
- Unity 的"程序集不可卸载"不阻塞该范式——可回滚单位是组件实例与效应,而非类型;这与 ModFramework 既有边界声明兼容。
- 阶段 0-3 已完成到 Basic Starter 的默认运行主路径;阶段 4 已完成首片事务性 Mod/HMR 合流,剩余工作集中在真实外部 DLL watcher 与更完整的失败注入验收,不再新增第三套生命周期。
- 阶段 0-4 已完成到 Basic Starter 的默认运行主路径与 ModFramework 事务性 HMR;后续若继续推进,应进入阶段 5 的 isolate/intercept 能力或围绕程序集常驻做容量与运维策略,不再新增第三套生命周期。