Files
endorphin-tessera-gui/src/main.rs
T

59 lines
3.3 KiB
Rust
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
//! 应用组合入口。先创建原生事件循环和共享发布状态,再启动 API/VM worker,最后把窗口事件交给 TesseraApp。
//! VM 操作由运行时线程串行处理;窗口线程只消费发布文档与纯数据通知。crate 私有别名用于保持模块内部引用路径稳定。
//!
//! Application composition root. Directory modules own implementation; these
//! crate-private aliases keep existing internal paths stable during reorganization.
// 以下目录模块只声明编译归属,真正启动服务和创建窗口发生在 main 的顺序调用中。
mod bridge;
mod model;
mod render;
mod runtime;
mod shell;
// crate 内旧路径通过私有重导出访问目录实现,不为 GUI 与 runtime 额外建立另一套对象或注册表。
pub(crate) use bridge::ui_bridge;
// 模型层负责从 VM 场景对象提取快照,渲染层 scene3d 负责原生计算;别名区分两者。
pub(crate) use model::scene3d as scene3d_model;
pub(crate) use model::{
binding, block, document, mount, object_list, presentation, protocols, snapshot, window,
};
pub(crate) use render::{
box_model, display_list, geometry, layout, native_visual, page, scene, scene3d, scroll,
software_renderer, source_hit, source_layout, source_paint, text, viewport,
};
pub(crate) use runtime::{
api, endor_host, endor_script, event_dispatch, events, io_tasks, tasks, vm_sequence,
};
#[cfg(target_os = "macos")]
pub(crate) use shell::native_chrome;
pub(crate) use shell::{
activity, app, clipboard, developer_tools, sidebar, sources, system_ui, tabs,
};
use std::sync::{Arc, RwLock};
use anyhow::Result;
use app::{AppEvent, TesseraApp};
use document::NamespaceState;
use winit::event_loop::{ControlFlow, EventLoop};
/// 按顺序建立事件循环、共享文档、API/VM worker 和应用窗口;事件循环结束后返回原生退出清理结果。
// 操作系统启动可执行文件时进入;各阶段的 ? 将启动/循环错误返回进程入口,不把失败当作成功运行。
fn main() -> Result<()> {
// 原生窗口由事件循环所属线程驱动;Wait 让空闲时休眠,而不是持续重绘。
let event_loop = EventLoop::<AppEvent>::with_user_event().build()?;
// 后台发布通过 EventLoopProxy 唤醒等待,原生窗口请求 RedrawRequested 驱动实际绘制。
event_loop.set_control_flow(ControlFlow::Wait);
// 共享最近完整发布的文档。后台 worker 拥有 VM,GUI 不借用其托管堆。
let namespace = Arc::new(RwLock::new(NamespaceState::default()));
// worker 发布完整 NamespaceState,activity 供 Network 工具观察,control 用于原生窗口发运行时控制请求。
// start 先绑定本机 API 并启动后台设施;端口或线程启动错误会阻止后续应用状态构造。
let (activity, control) = api::start(namespace.clone(), event_loop.create_proxy())?;
// 两个 proxy 指向同一事件循环;后台线程通过纯数据通知唤醒 GUI,不直接操作原生窗口。
let mut app = TesseraApp::new(namespace, activity, event_loop.create_proxy(), control)?;
// run_app 接管线程直至退出;退出后仍需检查清理过程中记录的错误。
event_loop.run_app(&mut app)?;
// 仅 run_app 正常返回后汇总窗口/VM 清理错误;循环本身返回 Err 时上面的 ? 已直接传播。
app.exit_result()
}