Seregon/StratoSDK

StratoSDK is a framework with a declarative approach similar to Flutter/React, written and designed entirely for Rust.

Rust/27.3 KB/No license
crates/strato-ui-renderer/src/platform/headless/app.rs
1use futures::future::LocalBoxFuture;
2 
3use crate::platform::app::TerminationResult;
4use crate::platform::test::FontDB as TestFontDB;
5use crate::{
6 integration::TestDriver,
7 platform::{self},
8 AppContext, AssetProvider,
9};
10 
11use super::delegate::{self, AppDelegate};
12use super::event_loop::{self, AppEvent};
13use super::windowing::WindowManager;
14use std::sync::mpsc;
15 
16pub struct App {
17 callbacks: platform::app::AppCallbacks,
18 assets: Box<dyn AssetProvider>,
19}
20 
21impl App {
22 pub(in crate::platform) fn new(
23 callbacks: platform::app::AppCallbacks,
24 assets: Box<dyn AssetProvider>,
25 test_driver: Option<&TestDriver>,
26 ) -> Self {
27 // Other platforms use the test_driver parameter to enable an alternative platform delegate implementation
28 // in integration tests - that doesn't apply here.
29 let _ = test_driver;
30 Self { callbacks, assets }
31 }
32 
33 pub(in crate::platform) fn run(
34 self,
35 init_fn: impl FnOnce(&mut AppContext, LocalBoxFuture<'static, crate::App>) + 'static,
36 ) -> TerminationResult {
37 let App { callbacks, assets } = self;
38 
39 let (sender, receiver) = mpsc::channel::<AppEvent>();
40 
41 // Mark this thread as the main thread for DispatchDelegate checks.
42 delegate::mark_current_thread_as_main();
43 
44 let platform_delegate = Box::new(AppDelegate::new(sender.clone()));
45 let window_manager = Box::new(WindowManager::new(sender.clone()));
46 // Reuse the testing FontDB implementation, as no font features are needed in headless mode.
47 let font_db: Box<dyn platform::FontDB> = Box::new(TestFontDB::new());
48 
49 let ui_app = crate::App::new(platform_delegate, window_manager, font_db, assets)
50 .expect("should not fail to construct application");
51 
52 let mut callbacks =
53 strato_ui_core::platform::app::AppCallbackDispatcher::new(callbacks, ui_app.clone());
54 
55 // Run the event loop until the app terminates.
56 event_loop::run(ui_app, &mut callbacks, Box::new(init_fn), receiver, sender)
57 }
58}
59