跳转至

系统

系统(System)是节点、节律源和连线关系的封装边界。

系统做什么

  1. 组织节点拓扑
  2. 将节律触发映射到节点执行
  3. 管理主流与旁路通讯关系
  4. 承接多语言节点的生成与编译装配

#[roplat::system] 的角色

系统宏会解析系统函数体中的连接表达式,抽取为内部 IR,再进入后续排序/调度阶段。

你可以把它理解为“把可读的系统 DSL 转换成可执行图”的入口。

标注 main 函数

#[roplat::system] 可以直接标注 main 函数:

#[roplat::system]
async fn main() {
    // DSL ...
}

宏检测到函数名为 main 时,会自动内联 tokio::runtime::Builder::new_multi_thread() 构建异步运行时,不需要再叠加 #[tokio::main]。这避免了 two-pass 构建中两个属性宏冲突的问题。

main 函数仍然生成普通的 async fn

节点生命周期自动注入

系统宏在代码生成阶段会为每个节律闭包中捕获的节点自动注入生命周期调用:

on_init()     ← drive() 之前,按声明顺序
  drive(...)  ← 节律驱动循环
on_shutdown() ← drive() 之后,按声明逆序

用户不需要手动调用 on_init / on_shutdown。节点以 &mut 引用传入 drive(),在 drive 结束后仍然存活,保证 on_shutdown 可以正常执行。

system_item! 内联宏

除了属性宏,还可以使用函数式过程宏在任意位置内联展开 DSL:

roplat::system_item! {
    timer >> {
        source >> encoder >> decoder >> sink;
    };
}

system_item! 只生成循环体代码(不包装函数签名),适合在 main 中精确控制插入位置。

连线风格(概念)

Roplat 当前系统解析支持 >> 风格连接,并可识别节律闭包、match 分支等结构。

重点不是语法糖本身,而是它背后形成的依赖图可被分析与优化。

系统与 two-pass 的关系

系统本身在编译期参与图解析;多语言相关内容则在构建期继续完成文件落盘与本地编译。

流程可简化为:

  1. 编译期:宏解析系统与节点语义
  2. 构建期:读取 manifest,生成跨语言文件并编译本地桥接
  3. 最终编译:Rust 与本地产物统一链接

新人常见问题

  1. 系统是不是运行时动态图编辑器

不是。系统更偏向“受约束的图描述 + 编译期分析”。

  1. 系统是否只能服务 Rust 节点

不是。系统可统一调度 Rust 节点和多语言傀儡节点。

  1. 系统和节律谁驱动谁

系统组织关系,节律负责触发。