#![cfg_attr(docsrs, feature(doc_cfg))]
mod assets;
mod config;
mod contexts;
mod dioxus_application;
mod dioxus_renderer;
mod link_handler;
#[cfg(feature = "prelude")]
pub mod prelude;
#[cfg(all(feature = "net", not(target_arch = "wasm32")))]
use blitz_traits::net::NetProvider;
#[doc(inline)]
pub use dioxus_native_dom::*;
use assets::DioxusNativeNetProvider;
pub use dioxus_application::{DioxusNativeApplication, DioxusNativeEvent};
pub use dioxus_renderer::DioxusNativeWindowRenderer;
#[cfg(target_os = "android")]
#[cfg_attr(docsrs, doc(cfg(target_os = "android")))]
pub fn set_android_app(app: android_activity::AndroidApp) {
blitz_shell::set_android_app(app);
}
#[cfg(target_os = "android")]
#[cfg_attr(docsrs, doc(cfg(target_os = "android")))]
pub fn current_android_app() -> android_activity::AndroidApp {
blitz_shell::current_android_app()
}
#[cfg(target_os = "android")]
#[cfg_attr(docsrs, doc(cfg(target_os = "android")))]
pub use android_activity::AndroidApp;
#[cfg(any(feature = "vello", feature = "vello-hybrid"))]
pub use {
dioxus_renderer::{Features, Limits},
wgpu_context::DeviceHandle,
};
pub use blitz_dom::{FontContext, Widget, build_single_font_ctx};
pub use config::Config;
pub use winit::dpi::{LogicalSize, PhysicalSize};
pub use winit::window::WindowAttributes;
use blitz_shell::{BlitzShellEvent, BlitzShellProxy, WindowConfig, create_default_event_loop};
use dioxus_core::{ComponentFunction, Element, VirtualDom, consume_context, use_hook};
use link_handler::DioxusNativeNavigationProvider;
use std::any::Any;
use std::sync::Arc;
use winit::{
raw_window_handle::{HasWindowHandle as _, RawWindowHandle},
window::Window,
};
pub fn use_window() -> Arc<dyn Window> {
use_hook(consume_context::<Arc<dyn Window>>)
}
pub fn use_raw_window_handle() -> RawWindowHandle {
use_hook(|| {
consume_context::<Arc<dyn Window>>()
.window_handle()
.unwrap()
.as_raw()
})
}
pub fn launch(app: fn() -> Element) {
launch_cfg(app, vec![], vec![])
}
pub fn launch_cfg(
app: fn() -> Element,
contexts: Vec<Box<dyn Fn() -> Box<dyn Any> + Send + Sync>>,
cfg: Vec<Box<dyn Any>>,
) {
launch_cfg_with_props(app, (), contexts, cfg)
}
pub fn launch_cfg_with_props<P: Clone + 'static, M: 'static>(
app: impl ComponentFunction<P, M>,
props: P,
contexts: Vec<Box<dyn Fn() -> Box<dyn Any> + Send + Sync>>,
configs: Vec<Box<dyn Any>>,
) {
macro_rules! try_read_config {
($input:ident, $store:ident, $kind:ty) => {
match $input.downcast::<$kind>() {
Ok(value) => {
$store = Some(*value);
continue;
}
Err(cfg) => cfg,
}
};
}
#[cfg(any(feature = "vello", feature = "vello-hybrid"))]
let (mut features, mut limits) = (None, None);
let mut window_attributes = None;
let mut config = None;
for mut cfg in configs {
#[cfg(any(feature = "vello", feature = "vello-hybrid"))]
{
cfg = try_read_config!(cfg, features, Features);
cfg = try_read_config!(cfg, limits, Limits);
}
cfg = try_read_config!(cfg, window_attributes, WindowAttributes);
cfg = try_read_config!(cfg, config, Config);
let _ = cfg;
}
let mut config = config.unwrap_or_default();
if let Some(window_attributes) = window_attributes {
config.window_attributes = window_attributes;
}
let event_loop = create_default_event_loop();
let winit_proxy = event_loop.create_proxy();
let (proxy, event_queue) = BlitzShellProxy::new(winit_proxy);
#[cfg(feature = "net")]
#[cfg(not(target_arch = "wasm32"))]
let rt = tokio::runtime::Builder::new_multi_thread()
.enable_all()
.build()
.unwrap();
#[cfg(feature = "net")]
#[cfg(not(target_arch = "wasm32"))]
let _guard = rt.enter();
#[cfg(all(feature = "hot-reload", debug_assertions))]
#[cfg(not(target_arch = "wasm32"))]
{
let proxy = proxy.clone();
dioxus_devtools::connect(move |event| {
let dxn_event = DioxusNativeEvent::DevserverEvent(event);
proxy.send_event(BlitzShellEvent::embedder_event(dxn_event));
})
}
let mut vdom = VirtualDom::new_with_props(app, props);
for context in contexts {
vdom.insert_any_root_context(context());
}
#[cfg(all(feature = "net", not(target_arch = "wasm32")))]
let net_provider = {
let net_waker = Some(Arc::new(proxy.clone()) as _);
let inner_net_provider = Arc::new(blitz_net::Provider::new(net_waker));
vdom.provide_root_context(Arc::clone(&inner_net_provider));
Arc::new(DioxusNativeNetProvider::with_inner(
proxy.clone(),
inner_net_provider as _,
)) as Arc<dyn NetProvider>
};
#[cfg(any(not(feature = "net"), target_arch = "wasm32"))]
let net_provider = DioxusNativeNetProvider::shared(proxy.clone());
vdom.provide_root_context(Arc::clone(&net_provider));
#[cfg(feature = "html")]
let html_parser_provider = {
let html_parser = Arc::new(blitz_html::HtmlProvider) as _;
vdom.provide_root_context(Arc::clone(&html_parser));
Some(html_parser)
};
#[cfg(not(feature = "html"))]
let html_parser_provider = None;
let navigation_provider = Some(Arc::new(DioxusNativeNavigationProvider) as _);
let doc = DioxusDocument::new(
vdom,
DocumentConfig {
net_provider: Some(net_provider),
html_parser_provider,
navigation_provider,
font_ctx: config.font_ctx,
..Default::default()
},
);
#[cfg(any(feature = "vello", feature = "vello-hybrid"))]
let renderer = DioxusNativeWindowRenderer::with_features_and_limits(features, limits);
#[cfg(not(any(feature = "vello", feature = "vello-hybrid")))]
let renderer = DioxusNativeWindowRenderer::new();
let config = WindowConfig::with_attributes(
Box::new(doc) as _,
renderer.clone(),
config.window_attributes,
);
let application = DioxusNativeApplication::new(proxy, event_queue, config);
event_loop.run_app(application).unwrap();
}