Files
endorphin-tessera-gui/docs/architecture/02-object-model.md
codex-bot 21439d4c4d
Verify Tessera GUI / verify (push) Failing after 1m30s
docs: render UML diagrams and embed portable previews
2026-10-25 22:09:47 +08:00

44 lines
3.2 KiB
Markdown

# 02 · 对象模型、展示位置与所有权
## 托管语义与原生快照是两种东西
业务对象、Block、Window、Mount、Task 等语义对象位于 Aster 堆中。Rust 的 `ObjectRef` 只是受检查的堆身份;能否存活由 VM 根及 `trace` 边决定。窗口侧的 `Arc<UiNode>`、Frame、Tab 是提取后的原生值,不能用来复活或直接修改语义对象。
下面是简化 UML 类图;实线关联表示有强引用/直接持有,虚线标明弱引用或派生关系。它省略类型表、回调捕获边和桌面的内部字典,不能当成完整 GC 根枚举。
![对象模型与引用关系](uml/rendered/domain.png)
[放大 SVG](uml/rendered/domain.svg) · [编辑 UML 源码](uml/domain.puml)
可编辑来源:[domain.puml](uml/domain.puml)。`Page` 是具有 Page 行为的托管 Block,不是另一棵浏览器 DOM;`ManagedWindow` 是 VM 中的窗口语义,和 winit 的原生 Window 有对应关系,但不是同一对象。
## 同一对象的两次出现
例如两个成绩页都引用同一个课程对象,并通过 `ui.textOf(course, "grade")` 展示字段。字段改变后,两处绑定都能更新。即使同一个可视 Block 出现两次,也必须分别布局:这两次出现对应不同 Mount,具有不同坐标、父位置、滚动偏移和焦点上下文。
`Child.slot` 是稳定的子出现标识,不能简单用数组下标替代。插入、移动子项时,这有助于保持原来的展示身份,而不是把所有后续位置都当作新出现。
## 谁保留什么
| 关系 | 保留/释放含义 |
| --- | --- |
| Candidate 的 globals / service roots | 保持当前程序全局对象和宿主服务可达 |
| Block → Cell → Data,或 Cell → Block | 支持共享赋值与别名;内容变化不会要求窗口侧重建对象身份 |
| Data → children / bindings / callbacks / history | 实际托管强边,交给 Aster GC 追踪 |
| Window 的 Page registry | 打开的 Page 被保留;关闭标签释放 registry 边 |
| 桌面内部 mount 字典 → Mount | 保留活跃展示位置;Mount 强引用其 Block |
| Mount → page / parent / siblings | 弱反向边,避免共享内容把 Page 留住 |
| MountTable、对象诊断索引、任务索引 | 使用弱身份,不单独延长对象寿命 |
| Subscription token → connection | 弱引用;丢弃 token 不等于取消监听,需 disconnect |
| 原生 Frame / Tab / DrawCommand | 无 VM handles;只是绘制和交互所需的值 |
关闭标签不必然销毁 Page:脚本仍引用它时可以重新打开。反之,关闭后不可达的对象图可以回收;没有“固定页面池”。重置 Console、删除程序或成功替换程序会触发活跃运行时的清理路径。
## 三种版本号不能混用
- `submission`:已接受写入工作的先后次序,用于撤销旧候选的发布资格。
- `revision`:已提交文档的修订,失败构建不应冒充成功修订。
- `runtime_session` / Frame.session 与 `layout_version`:界面输入属于哪一代运行时、哪份布局;旧点击和旧拖放不能作用到新对象。
对象模型源文件集中在 `src/model/`。实际分配、根清理和回调预算由 `runtime/endor_host.rs` 与 bridge 协作完成。