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

50 lines
2.2 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;
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()));
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()
}