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