//! 应用组合入口。先创建原生事件循环和共享发布状态,再启动 API/VM worker,最后把窗口事件交给 TesseraApp。 //! VM 操作由运行时线程串行处理;窗口线程只消费发布文档与纯数据通知。crate 私有别名用于保持模块内部引用路径稳定。 //! //! Application composition root. Directory modules own implementation; these //! crate-private aliases keep existing internal paths stable during reorganization. mod bridge; mod model; mod render; mod runtime; mod shell; pub(crate) use bridge::ui_bridge; 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::::with_user_event().build()?; event_loop.set_control_flow(ControlFlow::Wait); // 共享最近完整发布的文档。后台 worker 拥有 VM,GUI 不借用其托管堆。 let namespace = Arc::new(RwLock::new(NamespaceState::default())); let (activity, control) = api::start(namespace.clone(), event_loop.create_proxy())?; let mut app = TesseraApp::new(namespace, activity, event_loop.create_proxy(), control)?; // run_app 接管线程直至退出;退出后仍需检查清理过程中记录的错误。 event_loop.run_app(&mut app)?; app.exit_result() }