引擎架构概览
This content is not available in your language yet.
本章面向希望深入了解甚至参与末语引擎 Rust 层开发的读者。阅读前,建议先了解 为什么采用这种架构。
Crate 结构
Section titled “Crate 结构”crates/├── moyu/ # 主入口 crate,整合所有模块├── core/ # 核心引擎:渲染循环、事件、节点树、插件系统├── nodes/ # 内置节点类型(Sprite、Text、Animation 等)├── runtime/ # QuickJS VM 封装├── ops/ # JS ↔ Rust 桥接操作├── resource/ # 资源加载与管理(纹理、字体等)├── audio/ # 音频系统(Kira + Symphonia)├── platform/ # 平台抽象层(文件系统、日志、时间等)├── scenario/ # 剧情脚本执行器├── gamepad/ # 手柄输入├── macros/ # 过程宏(#[derive(Node)]、#[derive(Plugin)] 等)└── run_wasm/ # WASM 构建与开发服务器引擎启动经历以下阶段:
- 平台入口 — 桌面使用
main()+ tokio,移动端和 Web 使用moyu_init() - 事件循环创建 — 使用 winit 的
EventLoop ApplicationHandler::resumed— 创建窗口和Core实例- 多阶段初始化(通过
ApplicationInitEvent):Start— 初始化资源管理器Graphic— 创建 wgpu 图形管线和内置渲染器Plugin— 注册节点类型、插件和渲染器LoadUserScript— 启动 QuickJS VM 并加载用户脚本ShowAndStart— 显示窗口,分发GameEvent::Ready
核心数据结构
Section titled “核心数据结构”pub struct Core { pub window: Arc<Window>, pub graphics: ArcSwapOption<Graphics>, pub node_factories: DashMap<String, NodeFactory>, // 节点工厂注册表 pub plugins: DashMap<String, PluginLock>, // 插件注册表 pub node_map: NodeMap, // 所有活跃节点(DashMap<u32, NodeLock>) pub stage_size: Arc<RwLock<SurfaceSize>>, // 逻辑舞台尺寸 // ...}每帧执行的核心流程:
- 插件更新 — 遍历所有插件调用
plugin.update(vsync) - 节点树遍历 — 以深度优先遍历节点树
- 进入回调:更新变换矩阵、判断可见性、调用
renderer.update() - 退出回调:计算内容边界、调用
renderer.collect_commands()
- 进入回调:更新变换矩阵、判断可见性、调用
- 渲染命令提交 — 渲染器通过
RenderCommandSender发送渲染命令到 GPU 线程 - GPU 绘制 — 渲染线程消费命令队列,执行 wgpu 绘制
引擎内部事件通过 dispatch_event_async() 分发:
pub trait Event: Serialize + TS + Send + 'static { fn name(&self) -> &'static str;}- 节点事件:通过
NodeEventSourcetrait 从节点发送 - 插件事件:通过
PluginEventSourcetrait 从插件发送 - 事件最终通过
__moyu_receive_event传递到 JS 层
#[cfg(native)] // 桌面 + 移动原生平台#[cfg(web)] // WebAssembly 平台#[cfg(desktop)] // 仅桌面#[cfg(mobile)] // 仅移动端