1#![cfg_attr(docsrs, feature(doc_cfg))]
2
3mod assets;
13mod contexts;
14mod dioxus_application;
15mod dioxus_renderer;
16
17#[doc(inline)]
18pub use dioxus_native_dom::*;
19
20pub use anyrender_vello::{
21 wgpu_context::DeviceHandle, CustomPaintCtx, CustomPaintSource, TextureHandle,
22};
23use assets::DioxusNativeNetProvider;
24pub use dioxus_application::{DioxusNativeApplication, DioxusNativeEvent};
25pub use dioxus_renderer::{use_wgpu, DioxusNativeWindowRenderer, Features, Limits};
26
27use blitz_shell::{create_default_event_loop, BlitzShellEvent, Config, WindowConfig};
28use dioxus_core::{ComponentFunction, Element, VirtualDom};
29use std::any::Any;
30use winit::window::WindowAttributes;
31
32pub fn launch(app: fn() -> Element) {
34 launch_cfg(app, vec![], vec![])
35}
36
37pub fn launch_cfg(
38 app: fn() -> Element,
39 contexts: Vec<Box<dyn Fn() -> Box<dyn Any> + Send + Sync>>,
40 cfg: Vec<Box<dyn Any>>,
41) {
42 launch_cfg_with_props(app, (), contexts, cfg)
43}
44
45pub fn launch_cfg_with_props<P: Clone + 'static, M: 'static>(
47 app: impl ComponentFunction<P, M>,
48 props: P,
49 contexts: Vec<Box<dyn Fn() -> Box<dyn Any> + Send + Sync>>,
50 configs: Vec<Box<dyn Any>>,
51) {
52 macro_rules! try_read_config {
54 ($input:ident, $store:ident, $kind:ty) => {
55 match $input.downcast::<$kind>() {
57 Ok(value) => {
59 $store = Some(*value);
60 continue;
61 }
62 Err(cfg) => cfg,
65 }
66 };
67 }
68
69 let mut features = None;
71 let mut limits = None;
72 let mut window_attributes = None;
73 let mut _config = None;
74 for mut cfg in configs {
75 cfg = try_read_config!(cfg, features, Features);
76 cfg = try_read_config!(cfg, limits, Limits);
77 cfg = try_read_config!(cfg, window_attributes, WindowAttributes);
78 cfg = try_read_config!(cfg, _config, Config);
79 let _ = cfg;
80 }
81
82 let event_loop = create_default_event_loop::<BlitzShellEvent>();
83
84 let rt = tokio::runtime::Builder::new_multi_thread()
86 .enable_all()
87 .build()
88 .unwrap();
89 let _guard = rt.enter();
90
91 #[cfg(all(
93 feature = "hot-reload",
94 debug_assertions,
95 not(target_os = "android"),
96 not(target_os = "ios")
97 ))]
98 {
99 let proxy = event_loop.create_proxy();
100 dioxus_devtools::connect(move |event| {
101 let dxn_event = DioxusNativeEvent::DevserverEvent(event);
102 let _ = proxy.send_event(BlitzShellEvent::embedder_event(dxn_event));
103 })
104 }
105
106 let mut vdom = VirtualDom::new_with_props(app, props);
110
111 for context in contexts {
113 vdom.insert_any_root_context(context());
114 }
115
116 #[cfg(feature = "net")]
117 let net_provider = {
118 let proxy = event_loop.create_proxy();
119 let net_provider = DioxusNativeNetProvider::shared(proxy);
120 Some(net_provider)
121 };
122
123 #[cfg(not(feature = "net"))]
124 let net_provider = None;
125
126 let doc = DioxusDocument::new(vdom, net_provider);
128 let renderer = DioxusNativeWindowRenderer::with_features_and_limits(features, limits);
129 let config = WindowConfig::with_attributes(
130 Box::new(doc) as _,
131 renderer.clone(),
132 window_attributes.unwrap_or_default(),
133 );
134
135 let mut application = DioxusNativeApplication::new(event_loop.create_proxy(), config);
137
138 event_loop.run_app(&mut application).unwrap();
140}