3.2 KiB
04 · 布局、绘制、输入与刷新
一帧不是重新执行整个程序
活跃 VM 中的属性修改先被依赖系统观察,必要时刷新绑定、派生 UiNode、布局、paint 和 Mount 几何,再发布原生 Frame。干净的派生子树和测量结果可以复用;这不意味着所有帧都只访问变化节点,arrange、出现遍历和版本校验仍有成本。
| 环节 | 文件 | 产物 / 约束 |
|---|---|---|
| 绑定与变化依赖 | model/binding.rs、snapshot.rs、presentation.rs |
属性/方法身份依赖、缓存失效 |
| 不可变视觉提取 | bridge/ui_bridge/tree.rs、model/block.rs |
无 VM handles 的 UiNode 树,可有共享子树 |
| native 布局 | render/layout.rs |
测量、排列、稳定出现身份与预算 |
| source 布局协议 | render/source_layout.rs、native_visual.rs |
只读 measure/arrange 调用、约束和缓存 |
| source/native 绘制 | render/source_paint.rs |
检查绘制命令、文字换行界限、依赖与预算 |
| 滚动 / 命中 | render/scroll.rs、source_hit.rs |
每 Mount 偏移、剪裁、逆绘制顺序选目标 |
| 窗口画面合成 | render/scene.rs |
guest 页面 + 标签 + 当前开发工具 |
| 文本 / 光栅化 | render/text.rs、software_renderer.rs |
系统字体 shaping、抗锯齿 glyph、像素和嵌套剪裁 |
GUI 在 redraw 时组合已发布的画面和宿主 chrome,并按实际屏幕倍率写入 softbuffer。需要运行 source 方法的布局或 paint 由 worker 处理;viewport 变化也会送回 worker,GUI 线程不执行这些 VM 方法。
点击如何回到对象
可编辑来源:input.puml。没有 Mount 的代码主动 dispatch 只访问目标;有 Mount 的事件沿该次出现的父路径传播。事件监听器连接由 Block 保留,Subscription token 是弱控制句柄。
stopPropagation、stopImmediatePropagation、preventDefault 有各自语义;preventDefault 目前没有额外宿主默认动作可取消。原生输入不应绕过同一分发器直接调用另一个回调机制。
为什么 Mount、剪裁与 source 协议必须一起看
一个 Block 在两个容器出现时,源方法接收不同 Mount 的约束和几何。滚动需要更新该次出现的坐标、剪裁和祖先选择;命中顺序必须对应画出来的顺序。仅修改 paint 而不修改 hit/layout 会导致“看得到点不到”,反过来也会产生不可见点击区域。
只读协议及签名约束用于保护这些阶段,但不应表述为语言的所有 effect/trait 特性都已完成。当前具体原生签名和检查见 bridge/ui_bridge/signatures.rs、model/protocols.rs 及 Aster 固定版本。
刷新中的过时工作
尺寸、对象内容或运行时代际在刷新中变化时,旧 layout/paint 可以取消或重启。worker 负责完成当前清理并重新对齐 viewport,不能把旧 Mount 几何发布为新布局。当前刷新主协调仍在 runtime/endor_host.rs 与 bridge/ui_bridge.rs,后续可继续拆出独立 coordinator;本次没有改变该调度算法。
