docs: explain Tessera modules and execution flows in Chinese

This commit is contained in:
2026-11-11 23:36:03 +08:00
parent 4c3fc8b5dd
commit 1fedd21d3c
77 changed files with 1418 additions and 0 deletions
+39
View File
@@ -1,3 +1,6 @@
//! 托管事件与订阅的传播实现。Connection 持有回调引用,Event 保存目标、阶段与停止传播状态。
//! 分发沿出现关系执行 capture → target → bubble,并处理默认行为;只有同一 VM 中的回调可以接触托管对象。
//!
//! Managed subscriptions and occurrence-specific propagation. A validated VM
//! function sequences calls, so all handlers share one execution budget.
use crate::{block, mount::Mount, ui_bridge::attach_desktop_type};
@@ -7,10 +10,12 @@ use endor_core::{
};
const MAX_DELIVERIES: usize = 10_000;
/// 统一构造本模块的参数错误,让调用方停止处理无效输入。
fn invalid(message: &'static str) -> VmError {
VmError::InvalidArgument(message)
}
/// 检查订阅回调满足事件处理器调用契约,避免等到实际点击才暴露签名错误。
pub fn validate_handler(
store: &endor_core::ObjectStore,
function: ObjectRef,
@@ -30,6 +35,7 @@ pub fn validate_handler(
}
#[derive(Debug, Clone, Default)]
/// 本次传播的托管事件状态,包含目标、当前阶段和阻止默认/停止传播控制。
pub struct Event {
dispatch: Option<WeakObjectRef>,
group: usize,
@@ -38,36 +44,45 @@ pub struct Event {
prevented: bool,
}
impl ObjectPayload for Event {
/// 声明此 payload 的赋值遵循引用身份语义,避免把内部宿主状态当作可复制值。
fn reference_assignment_only(&self) -> bool {
true
}
/// 提供受检查的 Any 下转型入口,让宿主按具体 payload 类型读取数据。
fn as_any(&self) -> &dyn std::any::Any {
self
}
/// 返回运行时诊断/类型检查使用的稳定 payload 名称。
fn kind_name(&self) -> &'static str {
"tessera-event"
}
/// 声明此 payload 是否允许使用托管属性存储,具体字段仍由类型与调用检查约束。
fn allows_attributes(&self) -> bool {
true
}
}
#[derive(Debug, Clone)]
/// 实际拥有回调引用的托管连接,挂在目标的订阅关系中参与 GC。
pub struct Connection {
pub handler: Option<ObjectRef>,
pub kind: String,
pub capture: bool,
}
impl ObjectPayload for Connection {
/// 声明此 payload 的赋值遵循引用身份语义,避免把内部宿主状态当作可复制值。
fn reference_assignment_only(&self) -> bool {
true
}
/// 提供受检查的 Any 下转型入口,让宿主按具体 payload 类型读取数据。
fn as_any(&self) -> &dyn std::any::Any {
self
}
/// 返回运行时诊断/类型检查使用的稳定 payload 名称。
fn kind_name(&self) -> &'static str {
"tessera-event-connection"
}
/// 枚举本对象真正拥有的托管强引用,供 Aster 引用追踪和循环回收使用。
fn trace(&self, visit: &mut dyn FnMut(ObjectRef)) {
if let Some(handler) = self.handler {
visit(handler);
@@ -77,22 +92,27 @@ impl ObjectPayload for Connection {
/// A token never retains its target or callback. The Block owns the connection.
#[derive(Debug)]
/// 源代码可保留的订阅能力包装,用于取消对应连接。
pub struct Subscription {
pub connection: WeakObjectRef,
}
impl ObjectPayload for Subscription {
/// 声明此 payload 的赋值遵循引用身份语义,避免把内部宿主状态当作可复制值。
fn reference_assignment_only(&self) -> bool {
true
}
/// 提供受检查的 Any 下转型入口,让宿主按具体 payload 类型读取数据。
fn as_any(&self) -> &dyn std::any::Any {
self
}
/// 返回运行时诊断/类型检查使用的稳定 payload 名称。
fn kind_name(&self) -> &'static str {
"tessera-subscription"
}
}
#[derive(Debug, Clone, Copy)]
/// 保存 owner、签名或操作枚举的原生方法适配器,统一由 VM 调用。
enum Method {
Stop,
StopImmediate,
@@ -102,10 +122,12 @@ enum Method {
Connected,
}
impl NativeCallable for Method {
/// 声明宿主可调用对象接受的参数个数,供 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 [Value::Object(owner)] = args else {
return Err(invalid("event method receiver"));
@@ -179,17 +201,21 @@ impl NativeCallable for Method {
}
#[derive(Debug)]
/// 安装到托管类型上的原生构造调用适配器。
pub struct Constructor {
pub signature: Option<endor_core::CallSignature>,
}
impl NativeCallable for Constructor {
/// 给出参数与返回值的托管类型契约;实际操作在 invoke 中执行。
fn signature(&self) -> Option<endor_core::CallSignature> {
self.signature.clone()
}
/// 声明宿主可调用对象接受的参数个数,供 VM 在执行前检查。
fn arity(&self) -> Option<endor_core::CallArity> {
Some(endor_core::CallArity::range(2, usize::MAX))
}
/// VM 调入本宿主能力的入口;按所属操作解码参数并返回托管值或后续调用。
fn invoke(&self, cx: &mut NativeContext<'_>, args: &[Value]) -> Result<NativeResult, VmError> {
let [Value::Object(definition), Value::Text(kind), values @ ..] = args else {
return Err(invalid("Event requires an event kind"));
@@ -212,6 +238,7 @@ impl NativeCallable for Constructor {
}
}
/// 建立本次分发拥有的托管 Event,保存目标、输入与传播控制状态。
pub fn new_event(
cx: &mut NativeContext<'_>,
definition: ObjectRef,
@@ -231,19 +258,23 @@ pub fn new_event(
}
#[derive(Debug)]
/// 带事件类型签名和 owner 的原生方法包装。
struct TypedMethod {
method: Method,
signature: endor_core::CallSignature,
}
impl NativeCallable for TypedMethod {
/// 给出参数与返回值的托管类型契约;实际操作在 invoke 中执行。
fn signature(&self) -> Option<endor_core::CallSignature> {
Some(self.signature.clone())
}
/// VM 调入本宿主能力的入口;按所属操作解码参数并返回托管值或后续调用。
fn invoke(&self, cx: &mut NativeContext<'_>, args: &[Value]) -> Result<NativeResult, VmError> {
self.method.invoke(cx, args)
}
}
/// 把本模块的类型、方法或能力注册到所属运行时上下文。
pub fn install(
vm: &mut Vm,
roots: &mut Vec<ObjectRef>,
@@ -292,12 +323,14 @@ pub fn install(
}
#[derive(Debug)]
/// 本次递送选择的对象方法或显式订阅处理器。
enum Handler {
Token(ObjectRef),
Legacy(ObjectRef),
ObjectMethod,
}
#[derive(Debug)]
/// 事件传播过程中将要调用的一项处理器及其阶段/目标上下文。
struct Delivery {
event: ObjectRef,
owner: ObjectRef,
@@ -307,10 +340,12 @@ struct Delivery {
handler: Handler,
}
impl NativeCallable for Delivery {
/// 声明宿主可调用对象接受的参数个数,供 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 mut event = cx.store().payload::<Event>(self.event, "Event")?.clone();
if event.immediate || event.stopped_at.is_some_and(|group| group != self.group) {
@@ -363,12 +398,15 @@ impl NativeCallable for Delivery {
}
}
#[derive(Debug)]
/// 传播结束后的默认行为收尾步骤。
struct Finish(ObjectRef);
impl NativeCallable for Finish {
/// 声明宿主可调用对象接受的参数个数,供 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 mut event = cx.store().payload::<Event>(self.0, "Event")?.clone();
event.dispatch = None;
@@ -383,6 +421,7 @@ impl NativeCallable for Finish {
/// Snapshot the selected occurrence's route and listener order. Disconnection
/// before a listener's turn skips it; newly registered listeners wait for the
/// next dispatch. A code event without a Mount visits only its target object.
/// 按 Mount 祖先路径执行捕获、目标与冒泡阶段,再处理对应默认行为。
pub fn dispatch(
cx: &mut NativeContext<'_>,
owner: ObjectRef,