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::{DioxusNativeWindowRenderer, Features, Limits};
25
26#[cfg(not(all(target_os = "ios", target_abi = "sim")))]
27pub use dioxus_renderer::use_wgpu;
28
29use blitz_shell::{create_default_event_loop, BlitzShellEvent, Config, WindowConfig};
30use dioxus_core::{ComponentFunction, Element, VirtualDom};
31use link_handler::DioxusNativeNavigationProvider;
32use std::any::Any;
33use std::sync::Arc;
34use winit::window::WindowAttributes;
35
36pub fn launch(app: fn() -> Element) {
38 launch_cfg(app, vec![], vec![])
39}
40
41pub fn launch_cfg(
42 app: fn() -> Element,
43 contexts: Vec<Box<dyn Fn() -> Box<dyn Any> + Send + Sync>>,
44 cfg: Vec<Box<dyn Any>>,
45) {
46 launch_cfg_with_props(app, (), contexts, cfg)
47}
48
49pub fn launch_cfg_with_props<P: Clone + 'static, M: 'static>(
51 app: impl ComponentFunction<P, M>,
52 props: P,
53 contexts: Vec<Box<dyn Fn() -> Box<dyn Any> + Send + Sync>>,
54 configs: Vec<Box<dyn Any>>,
55) {
56 macro_rules! try_read_config {
58 ($input:ident, $store:ident, $kind:ty) => {
59 match $input.downcast::<$kind>() {
61 Ok(value) => {
63 $store = Some(*value);
64 continue;
65 }
66 Err(cfg) => cfg,
69 }
70 };
71 }
72
73 let mut features = None;
75 let mut limits = None;
76 let mut window_attributes = None;
77 let mut _config = None;
78 for mut cfg in configs {
79 cfg = try_read_config!(cfg, features, Features);
80 cfg = try_read_config!(cfg, limits, Limits);
81 cfg = try_read_config!(cfg, window_attributes, WindowAttributes);
82 cfg = try_read_config!(cfg, _config, Config);
83 let _ = cfg;
84 }
85
86 let event_loop = create_default_event_loop::<BlitzShellEvent>();
87
88 #[cfg(feature = "net")]
90 let rt = tokio::runtime::Builder::new_multi_thread()
91 .enable_all()
92 .build()
93 .unwrap();
94 #[cfg(feature = "net")]
95 let _guard = rt.enter();
96
97 #[cfg(all(
99 feature = "hot-reload",
100 debug_assertions,
101 not(target_os = "android"),
102 not(target_os = "ios")
103 ))]
104 {
105 let proxy = event_loop.create_proxy();
106 dioxus_devtools::connect(move |event| {
107 let dxn_event = DioxusNativeEvent::DevserverEvent(event);
108 let _ = proxy.send_event(BlitzShellEvent::embedder_event(dxn_event));
109 })
110 }
111
112 let mut vdom = VirtualDom::new_with_props(app, props);
116
117 for context in contexts {
119 vdom.insert_any_root_context(context());
120 }
121
122 let net_provider = Some(DioxusNativeNetProvider::shared(event_loop.create_proxy()));
123
124 #[cfg(feature = "html")]
125 let html_parser_provider = Some(Arc::new(blitz_html::HtmlProvider) as _);
126 #[cfg(not(feature = "html"))]
127 let html_parser_provider = None;
128
129 let navigation_provider = Some(Arc::new(DioxusNativeNavigationProvider) as _);
130
131 let doc = DioxusDocument::new(
133 vdom,
134 DocumentConfig {
135 net_provider,
136 html_parser_provider,
137 navigation_provider,
138 ..Default::default()
139 },
140 );
141 #[cfg(not(all(target_os = "ios", target_abi = "sim")))]
142 let renderer = DioxusNativeWindowRenderer::with_features_and_limits(features, limits);
143 #[cfg(all(target_os = "ios", target_abi = "sim"))]
144 let renderer = DioxusNativeWindowRenderer::new();
145 let config = WindowConfig::with_attributes(
146 Box::new(doc) as _,
147 renderer.clone(),
148 window_attributes.unwrap_or_default(),
149 );
150
151 let mut application = DioxusNativeApplication::new(event_loop.create_proxy(), config);
153
154 event_loop.run_app(&mut application).unwrap();
156}