From 73d5069a2056c0a2ea4a0d88e00c91a7e0d12185 Mon Sep 17 00:00:00 2001 From: Jonathan Kelley Date: Thu, 4 Jan 2024 18:31:22 -0800 Subject: [PATCH] Move launch functions into their own file --- packages/desktop/src/launch.rs | 120 ++++++++++++++++++++++++++++++ packages/desktop/src/lib.rs | 130 ++------------------------------- 2 files changed, 126 insertions(+), 124 deletions(-) create mode 100644 packages/desktop/src/launch.rs diff --git a/packages/desktop/src/launch.rs b/packages/desktop/src/launch.rs new file mode 100644 index 000000000..8af51e137 --- /dev/null +++ b/packages/desktop/src/launch.rs @@ -0,0 +1,120 @@ +use crate::{ + app::App, + desktop_context::{EventData, UserWindowEvent}, + events::IpcMethod, + Config, +}; +use dioxus_core::*; +use tao::event::{Event, StartCause, WindowEvent}; +use tokio::runtime::Builder; + +/// Launch the WebView and run the event loop. +/// +/// This function will start a multithreaded Tokio runtime as well the WebView event loop. +/// +/// ```rust, no_run +/// use dioxus::prelude::*; +/// +/// fn main() { +/// dioxus_desktop::launch(app); +/// } +/// +/// fn app(cx: Scope) -> Element { +/// cx.render(rsx!{ +/// h1 {"hello world!"} +/// }) +/// } +/// ``` +pub fn launch(root: Component) { + launch_with_props(root, (), Config::default()) +} + +/// Launch the WebView and run the event loop, with configuration. +/// +/// This function will start a multithreaded Tokio runtime as well the WebView event loop. +/// +/// You can configure the WebView window with a configuration closure +/// +/// ```rust, no_run +/// use dioxus::prelude::*; +/// use dioxus_desktop::*; +/// +/// fn main() { +/// dioxus_desktop::launch_cfg(app, Config::default().with_window(WindowBuilder::new().with_title("My App"))); +/// } +/// +/// fn app(cx: Scope) -> Element { +/// cx.render(rsx!{ +/// h1 {"hello world!"} +/// }) +/// } +/// ``` +pub fn launch_cfg(root: Component, config_builder: Config) { + launch_with_props(root, (), config_builder) +} + +/// Launch the WebView and run the event loop, with configuration and root props. +/// +/// This function will start a multithreaded Tokio runtime as well the WebView event loop. This will block the current thread. +/// +/// You can configure the WebView window with a configuration closure +/// +/// ```rust, no_run +/// use dioxus::prelude::*; +/// use dioxus_desktop::Config; +/// +/// fn main() { +/// dioxus_desktop::launch_with_props(app, AppProps { name: "asd" }, Config::default()); +/// } +/// +/// struct AppProps { +/// name: &'static str +/// } +/// +/// fn app(cx: Scope) -> Element { +/// cx.render(rsx!{ +/// h1 {"hello {cx.props.name}!"} +/// }) +/// } +/// ``` +pub fn launch_with_props(root: Component

, props: P, cfg: Config) { + // We start the tokio runtime *on this thread* + // Any future we poll later will use this runtime to spawn tasks and for IO + // I would love to just allow dioxus to work with any runtime... but tokio is weird + let rt = Builder::new_multi_thread().enable_all().build().unwrap(); + let _guard = rt.enter(); + + let (event_loop, mut app) = App::new(cfg, props, root); + + event_loop.run(move |window_event, event_loop, control_flow| { + app.tick(&window_event, event_loop); + + match window_event { + Event::NewEvents(StartCause::Init) => app.handle_start_cause_init(event_loop), + Event::WindowEvent { + event, window_id, .. + } => match event { + WindowEvent::CloseRequested => app.handle_close_requested(window_id), + WindowEvent::Destroyed { .. } => app.window_destroyed(window_id), + _ => {} + }, + Event::UserEvent(UserWindowEvent(event, id)) => match event { + EventData::Poll => app.poll_vdom(id), + EventData::NewWindow => app.handle_new_window(), + EventData::CloseWindow => app.handle_close_msg(id), + EventData::HotReloadEvent(msg) => app.handle_hot_reload_msg(msg), + EventData::Ipc(msg) => match msg.method() { + IpcMethod::FileDialog => app.handle_file_dialog_msg(msg, id), + IpcMethod::UserEvent => app.handle_user_event_msg(msg, id), + IpcMethod::Query => app.handle_query_msg(msg, id), + IpcMethod::BrowserOpen => app.handle_browser_open(msg), + IpcMethod::Initialize => app.handle_initialize_msg(id), + IpcMethod::Other(_) => {} + }, + }, + _ => {} + } + + *control_flow = app.control_flow; + }) +} diff --git a/packages/desktop/src/lib.rs b/packages/desktop/src/lib.rs index ca1e851fb..818605dc5 100644 --- a/packages/desktop/src/lib.rs +++ b/packages/desktop/src/lib.rs @@ -23,12 +23,12 @@ mod shortcut; mod waker; mod webview; -// Re-exports -pub use tao::{ - self, - dpi::{LogicalSize, PhysicalSize}, - window::WindowBuilder, -}; +// The main entrypoint for this crate +pub use launch::*; +mod launch; + +// Reexport tao and wry, might want to re-export other important things +pub use tao; pub use wry; // Public exports @@ -40,121 +40,3 @@ pub use desktop_context::{ pub use hooks::{use_asset_handler, use_global_shortcut, use_window, use_wry_event_handler}; pub use menubar::build_default_menu_bar; pub use shortcut::{ShortcutHandle, ShortcutId, ShortcutRegistryError}; - -#[allow(deprecated)] -use desktop_context::{EventData, UserWindowEvent}; -use dioxus_core::*; -use events::IpcMethod; -use tao::event::{Event, StartCause, WindowEvent}; -use tokio::runtime::Builder; - -/// Launch the WebView and run the event loop. -/// -/// This function will start a multithreaded Tokio runtime as well the WebView event loop. -/// -/// ```rust, no_run -/// use dioxus::prelude::*; -/// -/// fn main() { -/// dioxus_desktop::launch(app); -/// } -/// -/// fn app(cx: Scope) -> Element { -/// cx.render(rsx!{ -/// h1 {"hello world!"} -/// }) -/// } -/// ``` -pub fn launch(root: Component) { - launch_with_props(root, (), Config::default()) -} - -/// Launch the WebView and run the event loop, with configuration. -/// -/// This function will start a multithreaded Tokio runtime as well the WebView event loop. -/// -/// You can configure the WebView window with a configuration closure -/// -/// ```rust, no_run -/// use dioxus::prelude::*; -/// use dioxus_desktop::*; -/// -/// fn main() { -/// dioxus_desktop::launch_cfg(app, Config::default().with_window(WindowBuilder::new().with_title("My App"))); -/// } -/// -/// fn app(cx: Scope) -> Element { -/// cx.render(rsx!{ -/// h1 {"hello world!"} -/// }) -/// } -/// ``` -pub fn launch_cfg(root: Component, config_builder: Config) { - launch_with_props(root, (), config_builder) -} - -/// Launch the WebView and run the event loop, with configuration and root props. -/// -/// This function will start a multithreaded Tokio runtime as well the WebView event loop. This will block the current thread. -/// -/// You can configure the WebView window with a configuration closure -/// -/// ```rust, no_run -/// use dioxus::prelude::*; -/// use dioxus_desktop::Config; -/// -/// fn main() { -/// dioxus_desktop::launch_with_props(app, AppProps { name: "asd" }, Config::default()); -/// } -/// -/// struct AppProps { -/// name: &'static str -/// } -/// -/// fn app(cx: Scope) -> Element { -/// cx.render(rsx!{ -/// h1 {"hello {cx.props.name}!"} -/// }) -/// } -/// ``` -pub fn launch_with_props(root: Component

, props: P, cfg: Config) { - // We start the tokio runtime *on this thread* - // Any future we poll later will use this runtime to spawn tasks and for IO - // I would love to just allow dioxus to work with any runtime... but tokio is weird - let rt = &Builder::new_multi_thread().enable_all().build().unwrap(); - let _guard = rt.enter(); - - let (event_loop, mut app) = app::App::new(cfg, props, root); - - event_loop.run(move |window_event, event_loop, control_flow| { - app.tick(&window_event, event_loop); - - match window_event { - Event::NewEvents(StartCause::Init) => app.handle_start_cause_init(event_loop), - Event::WindowEvent { - event, window_id, .. - } => match event { - WindowEvent::CloseRequested => app.handle_close_requested(window_id), - WindowEvent::Destroyed { .. } => app.window_destroyed(window_id), - _ => {} - }, - Event::UserEvent(UserWindowEvent(event, id)) => match event { - EventData::Poll => app.poll_vdom(id), - EventData::NewWindow => app.handle_new_window(), - EventData::CloseWindow => app.handle_close_msg(id), - EventData::HotReloadEvent(msg) => app.handle_hot_reload_msg(msg), - EventData::Ipc(msg) => match msg.method() { - IpcMethod::FileDialog => app.handle_file_dialog_msg(msg, id), - IpcMethod::UserEvent => app.handle_user_event_msg(msg, id), - IpcMethod::Query => app.handle_query_msg(msg, id), - IpcMethod::BrowserOpen => app.handle_browser_open(msg), - IpcMethod::Initialize => app.handle_initialize_msg(id), - IpcMethod::Other(_) => {} - }, - }, - _ => {} - } - - *control_flow = app.control_flow; - }) -}