v0.2.0
ShrinkContext.Core
《Cordis: A Programming Paradigm for Spatiotemporal Composability》核心机制的 Unity/C# 实现。当前架构与边界见仓库根 DESIGN.md;已完成的迁移过程归档于 Docs/Archive/CORDIS_MIGRATION.completed.md。
共享内核不引用 Unity 或 Godot。Godot 和普通 .NET 项目安装 ShrinkSDK.Context.Core;可打包源码位于 DotNet~。
定位
时空可组合性的元框架核心库:不规定任何领域,只提供动态组合的两个通用原语——
- 可逆效应(时间可组合性,论文 3.1 / 算法 1):
ctx.Effect / EffectAsync,前向执行时产出逆操作,运行时按 LIFO 累积,卸载即回滚; - 响应式余效应(空间可组合性,论文 3.2 / 算法 2、3):
ctx.Set / Get,依赖键的安装/撤回自动通知依赖者,组件在依赖全部可用时激活、失效时停用、换提供者时重载; - 纤程生命周期(论文 4 / 算法 4、5):
runtime.Use(component)实例化组件为纤程,惯性状态机Loading → Active → Unloading → Inactive,卸载先等待依赖者排空再回滚自身效应,父卸载级联子卸载。 - 声明式协调与访问介导:加载器以事务更新期望组合,失败时恢复旧组合;
isolate / intercept控制解析域与服务视图,组件供给受Provide声明约束。
目录结构
| 目录 | 说明 |
|---|---|
Runtime/Context/ |
ShrinkCtx(一等上下文、隔离派生、介导访问)与 ShrinkEffectHandle(算法 1) |
Runtime/Coeffects/ |
绑定、强类型版本键、访问策略与异常类型 |
Runtime/Fibers/ |
IShrinkComponent(inject/provide/apply)、ShrinkFiber、分步效应接口 |
Runtime/Loader/ |
声明式加载器:ShrinkLoaderEntry / ShrinkComponentCatalog / ShrinkContextLoader 增量协调、事务恢复与条目诊断 |
Runtime/ |
ShrinkContextRuntime(注册表 + 算法 2-5 + notify 倒排索引)、诊断快照与 Domain Reload 重置 |
Tests/ |
EditMode 测试:对照论文定理 7/16/20/63/64 与算法 1/2/3/4/5/6 的可观察行为 + 加载器协调行为 |
论文 → API 对照
| 论文概念 | 本实现 |
|---|---|
ctx.effect(callback) → dispose |
ShrinkCtx.Effect / EffectAsync → ShrinkEffectHandle.DisposeAsync(armed 单次执行,等待进行中前向) |
ctx.get/set(算法 2) |
ShrinkCtx.Set<T>(可逆,安装+通知 / 撤回+通知) |
ctx.isolate(key, realm) |
ShrinkCtx.Isolate(派生子上下文,丢弃即恢复) |
ctx.intercept(key, metadata) |
ShrinkCtx.Intercept(派生访问元数据;provider 通过 IShrinkCoeffectAccessPolicy 返回受限视图或拒绝访问) |
| 代理介导访问(算法 6) | ShrinkCtx.Get<T>/TryGet(沿纤程链解析已提交视图;未声明/未激活/策略拒绝分别抛出不同异常) |
ctx.use(component)(算法 4) |
ShrinkContextRuntime.Use(实例化是父上下文的可逆效应 → 级联卸载;支持条目级 isolate 叠加) |
| 声明式配置 + 协调(论文 5.2) | ShrinkContextLoader.ApplyAsync(预校验期望组合;条目消失→退役;组件/配置变化→重建;intercept 变化→原位更新;失败→恢复旧组合) |
| refresh/reload/unload(算法 5) | RunTransitionAsync(惯性链式转换;卸载先 drain 依赖者) |
| notify(算法 3) | ShrinkContextRuntime.Notify(key → inject fibers 倒排索引选候选,再按 realm 过滤) |
| target = 按 inject 顺序解析的提供者 uid | ShrinkFiber.Target(保留键顺序与重复依赖;uid 永不复用,因此同值换提供者也会重载) |
𝔈iterΓ 分步效应 |
IShrinkIterativeComponent.ApplySteps(自定义 UniTask 步进器,步进边界守卫 → 部分回滚;不用 IAsyncEnumerable,规避 Mono ValueTask 迭代器的非内联调度) |
| fiber.committed 提交视图 | ShrinkFiber.Committed(装载前提交,拆除完才丢弃) |
测试覆盖(对照论文元理论)
- 定理 7(恢复初始上下文)/ 定理 16(LIFO)/ 选择性撤销 / armed 幂等 / dispose 等待进行中前向
- set 可逆性、介导访问纪律(UNDECLARED / INACTIVE)、隔离域派生与丢弃恢复
- 未声明供给回滚、访问策略拒绝、intercept 原位更新与只读服务视图
- 依赖驱动激活、缺依赖静默非活动、晚到提供者激活
- 退役次序:依赖者先于提供者逆操作排空(drain-before-inverse)
- 提供者替换重载(含同值替换,uid 语义)
- 父子级联、供给冲突、循环依赖静止(论文 6.5)
- 惯性:装载中途退役永不 Active、链式卸载(论文 4.3.3)
- 分步效应部分回滚(定理 64)
- apply 失败的部分效应回滚(L-Raise)
- 加载器失败恢复旧组合、跨 realm 替换隔离、notify 倒排索引候选计数与运行时诊断
- Domain Reload 重置
当前边界
intercept是经ShrinkCtx.Get的能力介导,不是对不可信 DLL 的内存、反射、文件或网络沙箱。- loader 的 isolate 变化仍通过重建条目生效;尚未提供运行中 fiber 的原位 realm 迁移。
- 强类型版本键是新增契约,现有字符串键不会在阶段 5 被一次性重写。
- Core 保持不依赖具体配置资产;
ShrinkContext.AppAdapter提供 ScriptableObject/JSON 组合、Editor 诊断窗和可重复容量基准。 - 主线程宿主与 Unity PlayerLoop 调度仍由上层应用负责。
- 当前上下文只协调单进程内组件;跨进程/独立服务器使用 Network 合同,不共享 fiber 或事务。
约定
- 仅主线程使用;异步转换在同步可完成路径上内联跑完(测试无需 PlayerLoop 泵即可确定性断言)。
- 测试中的
TestAwait.Run同步阻塞等待,仅用于保证延续同步完成的测试代码。
Languages
C#
100%