53 lines
2.6 KiB
Rust
53 lines
2.6 KiB
Rust
//! 应用组合入口。先创建原生事件循环和共享发布状态,再启动 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;
|
||
// 模型层负责从 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()?;
|
||
event_loop.set_control_flow(ControlFlow::Wait);
|
||
// 共享最近完整发布的文档。后台 worker 拥有 VM,GUI 不借用其托管堆。
|
||
let namespace = Arc::new(RwLock::new(NamespaceState::default()));
|
||
// worker 发布完整 NamespaceState,activity 供 Network 工具观察,control 用于原生窗口发运行时控制请求。
|
||
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)?;
|
||
app.exit_result()
|
||
}
|