workflow_egui/frame/
mod.rs

1use crate::imports::*;
2
3pub mod options;
4pub use options::*;
5pub mod app;
6pub mod core;
7
8pub type AppCreator<T> =
9    Box<dyn FnOnce(&eframe::CreationContext<'_>, Runtime) -> std::result::Result<Box<T>, DynError>>;
10
11cfg_if! {
12    if #[cfg(not(target_arch = "wasm32"))] {
13
14        pub fn main<T,C>(options: Options<T>, events : Option<ApplicationEventsChannel>, app_creator : C)
15        where T : App,
16        C : FnOnce(&eframe::CreationContext<'_>, Runtime) -> std::result::Result<Box<T>, DynError> + 'static
17        {
18
19            #[cfg(feature = "console")] {
20                std::env::set_var("RUST_BACKTRACE", "full");
21            }
22
23            let body = async {
24                if let Err(err) = platform_main(options, events, Box::new(app_creator)).await {
25                    log_error!("Error: {err}");
26                }
27            };
28
29            #[allow(clippy::expect_used, clippy::diverging_sub_expression)]
30            tokio::runtime::Builder::new_multi_thread()
31                .enable_all()
32                .build()
33                .expect("Failed building the Runtime")
34                .block_on(body);
35
36            #[cfg(feature = "console")]
37            {
38                println!("Press Enter to exit...");
39                let mut input = String::new();
40                std::io::stdin().read_line(&mut input).expect("Failed to read line");
41            }
42
43
44        }
45
46    } else {
47
48        pub fn main<T,C>(options: Options<T>, events : Option<ApplicationEventsChannel>, app_creator : C)
49        where T : App,
50        C : FnOnce(&eframe::CreationContext<'_>, Runtime) -> std::result::Result<Box<T>, DynError> + 'static
51        {
52
53            wasm_bindgen_futures::spawn_local(async {
54                log_info!("--- starting platform main... ---");
55
56                // todo!();
57                if let Err(err) = platform_main(options, events, Box::new(app_creator)).await {
58                    log_error!("Error: {err}");
59                }
60            });
61
62        }
63    }
64}
65
66cfg_if! {
67    if #[cfg(not(target_arch = "wasm32"))] {
68
69        async fn platform_main<T>(options : Options<T>, events : Option<ApplicationEventsChannel>, app_creator : AppCreator<T>) -> Result<()>
70        where T : App
71        {
72            use crate::runtime::signals::Signals;
73
74            // ------------------------------------------------------------
75            // ------------------------------------------------------------
76            // ------------------------------------------------------------
77            // workflow_log::set_colors_enabled(true);
78            // // Log to stderr (if you run with `RUST_LOG=debug`).
79            // env_logger::init();
80            // set_log_level(LevelFilter::Info);
81            // ------------------------------------------------------------
82            // ------------------------------------------------------------
83            // ------------------------------------------------------------
84
85            let runtime: Arc<Mutex<Option<Runtime>>> = Arc::new(Mutex::new(None));
86            let delegate = runtime.clone();
87
88            eframe::run_native(
89                options.caption.as_str(),
90                options.native_options,
91                Box::new(move |cc| {
92                    let runtime = Runtime::new(&cc.egui_ctx, events);
93                    delegate.lock().unwrap().replace(runtime.clone());
94                    Signals::bind(&runtime);
95                    runtime.start();
96
97                    Ok(Box::new(core::Core::try_new(cc, runtime, app_creator)?))
98                }),
99            )?;
100
101            let runtime = runtime.lock().unwrap().take().unwrap();
102            runtime.shutdown().await;
103
104
105            Ok(())
106        }
107    } else {
108
109        async fn platform_main<T>(options : Options<T>, events : Option<ApplicationEventsChannel>, app_creator : AppCreator<T>) -> Result<()>
110        where T : App
111        {
112            use workflow_dom::utils::document;
113
114            // Redirect `log` message to `console.log` and friends:
115            eframe::WebLogger::init(log::LevelFilter::Debug).ok();
116
117            if let Some(element) = document().get_element_by_id("loading") {
118                element.remove();
119            }
120
121            eframe::WebRunner::new()
122                .start(
123                    options.canvas_id.as_str(),
124                    options.web_options,
125                    Box::new(move |cc| {
126                        let runtime = Runtime::new(&cc.egui_ctx, events);
127                        runtime.start();
128                        Ok(Box::new(core::Core::try_new(cc, runtime, app_creator)?))
129                    }),
130                )
131                .await
132                .expect("failed to start eframe");
133            Ok(())
134        }
135    }
136}