docs: explain Tessera modules and execution flows in Chinese
This commit is contained in:
@@ -1,3 +1,7 @@
|
||||
//! 源 measure/arrange 协议的分片布局驱动器。自底向上的测量与自顶向下的安排共享一个只读 VM 调用域。
|
||||
//! Plan 只保存派生几何和求解过程;Measurement 缓存记录真实读取依赖。已有业务对象在只读阶段不能被修改。
|
||||
//! 较大树可在节点/指令量子之间挂起。Work 拥有尚未发布的执行状态,必须 resume 或 cancel;完成后才把 Draft 交给桥接层提交。
|
||||
//!
|
||||
//! Bottom-up measurement and top-down arrangement share one read-only VM call.
|
||||
//! The host scratch plan contains derived data only, never a second business heap.
|
||||
use crate::{
|
||||
@@ -22,9 +26,11 @@ use std::{
|
||||
// same per-occurrence VM driver so even intrinsic work can yield between nodes.
|
||||
const NATIVE_FAST_PATH_MAX_NODES: usize = 64;
|
||||
|
||||
/// 统一构造本模块的参数错误,让调用方停止处理无效输入。
|
||||
fn invalid(message: &'static str) -> VmError {
|
||||
VmError::InvalidArgument(message)
|
||||
}
|
||||
/// 读取当前 desktop 的类型字典,为布局协议结果提供名义类型检查。
|
||||
fn desktop_type_registry(cx: &NativeContext<'_>, desktop: ObjectRef) -> Result<ObjectRef, VmError> {
|
||||
match cx.store().get_attr(desktop, "types")? {
|
||||
Value::Object(object) => Ok(object),
|
||||
@@ -32,6 +38,7 @@ fn desktop_type_registry(cx: &NativeContext<'_>, desktop: ObjectRef) -> Result<O
|
||||
}
|
||||
}
|
||||
#[derive(Debug, Clone)]
|
||||
/// 一次源测量的缓存输入、输出和真实读取依赖;不同约束或依赖版本不能复用。
|
||||
struct Measurement {
|
||||
owner: ObjectRef,
|
||||
method: ObjectRef,
|
||||
@@ -42,12 +49,14 @@ struct Measurement {
|
||||
}
|
||||
/// Borrowed identities and versions only: this cache adds no managed roots.
|
||||
#[derive(Debug, Default, Clone)]
|
||||
/// 按 Mount 弱身份保存源测量结果,不为业务对象增加托管根。
|
||||
pub struct Cache {
|
||||
entries: HashMap<WeakObjectRef, Measurement>,
|
||||
pub hits: usize,
|
||||
pub misses: usize,
|
||||
}
|
||||
impl Cache {
|
||||
/// 从测量缓存依赖中移除宿主私有 desktop 记账对象,防止内部同步造成自我失效。
|
||||
pub(crate) fn exclude_host_desktops(&mut self, desktops: &HashSet<ObjectRef>) {
|
||||
for entry in self.entries.values_mut() {
|
||||
entry
|
||||
@@ -55,10 +64,12 @@ impl Cache {
|
||||
.retain(|read| !desktops.contains(&read.object()));
|
||||
}
|
||||
}
|
||||
/// 移除受影响 owner 的源测量缓存;其他出现继续按其读取版本检查。
|
||||
pub fn invalidate(&mut self, owners: &HashSet<ObjectRef>) {
|
||||
self.entries
|
||||
.retain(|_, entry| !owners.contains(&entry.owner));
|
||||
}
|
||||
/// 清空本对象维护的当前内容或缓存,后续状态由调用方重新建立。
|
||||
pub fn clear(&mut self) {
|
||||
self.entries.clear();
|
||||
self.hits = 0;
|
||||
@@ -66,6 +77,7 @@ impl Cache {
|
||||
}
|
||||
}
|
||||
#[derive(Debug)]
|
||||
/// 一个等待源测量返回的收集项,记录本次方法、约束和子项输入。
|
||||
struct Pending {
|
||||
token: usize,
|
||||
owner: ObjectRef,
|
||||
@@ -75,10 +87,13 @@ struct Pending {
|
||||
key: WeakObjectRef,
|
||||
}
|
||||
#[derive(Debug)]
|
||||
/// 未发布的布局求解工作区,包含出现树、期望尺寸、分配边界、收敛记录和缓存。
|
||||
struct Plan {
|
||||
// 使用出现索引保存树和几何,不为每个位置建立第二份业务对象。
|
||||
nodes: Vec<Arc<UiNode>>,
|
||||
children: Vec<Vec<usize>>,
|
||||
sizes: Vec<Size>,
|
||||
// preferred 是测量偏好,bounds 是父级实际分配;换行/flex 会使两者不同。
|
||||
preferred: Vec<Option<Size>>,
|
||||
bounds: Vec<Option<[f32; 4]>>,
|
||||
runtime: LayoutRuntime,
|
||||
@@ -92,16 +107,19 @@ struct Plan {
|
||||
native_arrange: Vec<bool>,
|
||||
custom_measure: Vec<bool>,
|
||||
measured_limits: Vec<[Option<f32>; 2]>,
|
||||
// 保存几何状态用于检测收敛和重复状态,防止相互依赖布局无限循环。
|
||||
previous: Option<Vec<u32>>,
|
||||
seen: BTreeSet<Vec<u32>>,
|
||||
}
|
||||
type Shared = Arc<Mutex<Plan>>;
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
/// 源视觉调用当前处于测量还是安排阶段,决定调用方法与结果解码。
|
||||
enum Phase {
|
||||
Measure,
|
||||
Arrange,
|
||||
}
|
||||
impl Phase {
|
||||
/// 把当前布局阶段映射为 measure 或 arrange 方法名称。
|
||||
fn method(self) -> &'static str {
|
||||
match self {
|
||||
Self::Measure => "measure",
|
||||
@@ -110,6 +128,7 @@ impl Phase {
|
||||
}
|
||||
}
|
||||
#[derive(Debug)]
|
||||
/// 为某次出现准备一个 measure/arrange 调用,选择原生快速结果或真正的源覆盖。
|
||||
struct Step {
|
||||
plan: Shared,
|
||||
index: usize,
|
||||
@@ -118,10 +137,12 @@ struct Step {
|
||||
desktop: ObjectRef,
|
||||
}
|
||||
impl NativeCallable for Step {
|
||||
/// 声明宿主可调用对象接受的参数个数,供 VM 在执行前检查。
|
||||
fn arity(&self) -> Option<endor_core::CallArity> {
|
||||
Some(endor_core::CallArity::exact(0))
|
||||
}
|
||||
|
||||
/// VM 调入本宿主能力的入口;按所属操作解码参数并返回托管值或后续调用。
|
||||
fn invoke(&self, cx: &mut NativeContext<'_>, _: &[Value]) -> Result<NativeResult, VmError> {
|
||||
let mount = cx.store().payload::<Mount>(self.mount, "Mount")?.clone();
|
||||
let definition = cx
|
||||
@@ -293,6 +314,7 @@ impl NativeCallable for Step {
|
||||
}
|
||||
}
|
||||
#[derive(Debug)]
|
||||
/// 接收并检查源协议返回结果,将其合入 Plan,而不是直接写成发布帧。
|
||||
struct Collect {
|
||||
plan: Shared,
|
||||
index: usize,
|
||||
@@ -300,10 +322,12 @@ struct Collect {
|
||||
desktop: ObjectRef,
|
||||
}
|
||||
impl NativeCallable for Collect {
|
||||
/// 声明宿主可调用对象接受的参数个数,供 VM 在执行前检查。
|
||||
fn arity(&self) -> Option<endor_core::CallArity> {
|
||||
Some(endor_core::CallArity::exact(1))
|
||||
}
|
||||
|
||||
/// VM 调入本宿主能力的入口;按所属操作解码参数并返回托管值或后续调用。
|
||||
fn invoke(&self, cx: &mut NativeContext<'_>, args: &[Value]) -> Result<NativeResult, VmError> {
|
||||
let pending = if matches!(self.phase, Phase::Measure) {
|
||||
self.plan
|
||||
@@ -496,14 +520,17 @@ impl NativeCallable for Collect {
|
||||
}
|
||||
}
|
||||
#[derive(Debug)]
|
||||
/// 检查本轮布局是否已收敛,必要时安排下一次测量/分配迭代。
|
||||
struct Settle {
|
||||
plan: Shared,
|
||||
mounts: Arc<[WeakObjectRef]>,
|
||||
}
|
||||
impl NativeCallable for Settle {
|
||||
/// 声明宿主可调用对象接受的参数个数,供 VM 在执行前检查。
|
||||
fn arity(&self) -> Option<endor_core::CallArity> {
|
||||
Some(endor_core::CallArity::exact(0))
|
||||
}
|
||||
/// VM 调入本宿主能力的入口;按所属操作解码参数并返回托管值或后续调用。
|
||||
fn invoke(&self, cx: &mut NativeContext<'_>, _: &[Value]) -> Result<NativeResult, VmError> {
|
||||
let repeat = {
|
||||
let mut plan = self
|
||||
@@ -626,15 +653,18 @@ impl NativeCallable for Settle {
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
/// 准备当前求解步骤所需的约束和 Mount 临时上下文。
|
||||
struct Prepare {
|
||||
plan: Shared,
|
||||
mounts: Vec<WeakObjectRef>,
|
||||
desktop: ObjectRef,
|
||||
}
|
||||
impl NativeCallable for Prepare {
|
||||
/// 声明宿主可调用对象接受的参数个数,供 VM 在执行前检查。
|
||||
fn arity(&self) -> Option<endor_core::CallArity> {
|
||||
Some(endor_core::CallArity::exact(0))
|
||||
}
|
||||
/// VM 调入本宿主能力的入口;按所属操作解码参数并返回托管值或后续调用。
|
||||
fn invoke(&self, cx: &mut NativeContext<'_>, _: &[Value]) -> Result<NativeResult, VmError> {
|
||||
let advance = cx.allocate(ContextNativeFunction::new(
|
||||
"next layout occurrence",
|
||||
@@ -655,6 +685,7 @@ impl NativeCallable for Prepare {
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
/// 在同一驱动帧中安排下一项布局工作,使大树能够分片让出。
|
||||
struct Advance {
|
||||
plan: Shared,
|
||||
mounts: Arc<[WeakObjectRef]>,
|
||||
@@ -662,9 +693,11 @@ struct Advance {
|
||||
next: Mutex<usize>,
|
||||
}
|
||||
impl NativeCallable for Advance {
|
||||
/// 声明宿主可调用对象接受的参数个数,供 VM 在执行前检查。
|
||||
fn arity(&self) -> Option<endor_core::CallArity> {
|
||||
Some(endor_core::CallArity::exact(0))
|
||||
}
|
||||
/// VM 调入本宿主能力的入口;按所属操作解码参数并返回托管值或后续调用。
|
||||
fn invoke(&self, cx: &mut NativeContext<'_>, _: &[Value]) -> Result<NativeResult, VmError> {
|
||||
let count = self.mounts.len();
|
||||
let position = {
|
||||
@@ -741,6 +774,7 @@ impl NativeCallable for Advance {
|
||||
|
||||
/// An unpublished layout frame and derived caches. These are merged only after
|
||||
/// the driver completes; they are not another copy of application state.
|
||||
/// 已经完成本阶段、但尚未由桥接层发布的派生结果,包含帧/缓存或真实读取依赖。
|
||||
pub struct Draft {
|
||||
pub frame: Frame,
|
||||
pub runtime: LayoutRuntime,
|
||||
@@ -749,6 +783,7 @@ pub struct Draft {
|
||||
}
|
||||
|
||||
#[must_use = "pending layout work must be resumed or cancelled with its owning VM"]
|
||||
/// 本次推进处于挂起还是完成;挂起工作必须继续恢复或显式取消。
|
||||
pub enum Progress {
|
||||
Pending(Work),
|
||||
Complete(Draft),
|
||||
@@ -756,6 +791,7 @@ pub enum Progress {
|
||||
|
||||
/// Host-owned continuation. No borrowed frame/cache references cross a pause.
|
||||
/// The prepare handle owns one root until completion or explicit cancellation.
|
||||
/// 拥有未完成源调用及临时根的工作句柄;丢弃 Rust 值不能替代 VM 内的取消。
|
||||
pub struct Work {
|
||||
state: Draft,
|
||||
plan: Shared,
|
||||
@@ -765,12 +801,14 @@ pub struct Work {
|
||||
}
|
||||
|
||||
impl Work {
|
||||
/// 恢复当前 Work 拥有的 VM 续体,继续同一轮求解而不是重放 measure/arrange。
|
||||
pub fn resume(mut self, vm: &mut Vm, slice: usize) -> Result<Progress> {
|
||||
self.slices += 1;
|
||||
let progress = vm.resume_read_only_call(slice);
|
||||
self.accept(vm, progress)
|
||||
}
|
||||
|
||||
/// 显式结束布局续体和只读域,释放本次尚未提交的临时根。
|
||||
pub fn cancel(self, vm: &mut Vm) -> Result<()> {
|
||||
let cancelled = vm.cancel_read_only_call();
|
||||
let released = vm.release(self.prepare);
|
||||
@@ -779,6 +817,7 @@ impl Work {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// 接收一次续体进度,挂起时保留工作,完成时将派生结果交给收尾阶段。
|
||||
fn accept(
|
||||
self,
|
||||
vm: &mut Vm,
|
||||
@@ -805,6 +844,7 @@ impl Work {
|
||||
}
|
||||
}
|
||||
|
||||
/// 建立只读布局 Plan 与托管驱动函数;小型原生树可走直接路径,大树保留分片推进能力。
|
||||
pub fn start(
|
||||
vm: &mut Vm,
|
||||
desktop: ObjectRef,
|
||||
@@ -945,6 +985,7 @@ pub fn start(
|
||||
work.accept(vm, progress)
|
||||
}
|
||||
|
||||
/// 验证求解已收敛,收集最终几何、读取依赖和缓存,返回尚待桥接层提交的 Draft。
|
||||
fn finish(
|
||||
vm: &mut Vm,
|
||||
mut work: Work,
|
||||
|
||||
Reference in New Issue
Block a user