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