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

53 lines
2.6 KiB
Rust
Raw Permalink 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.
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()
}