Make the tokio runtime optional
This commit is contained in:
8 files changed
+60
-28
No files matched your search
+3
-2
@@ -1,7 +1,8 @@
|
|||||||
use dioxus::prelude::*;
|
use dioxus::prelude::*;
|
||||||
use dioxus_signals::use_signal;
|
use dioxus_signals::use_signal;
|
||||||
|
|
||||||
fn main() {
|
#[tokio::main]
|
||||||
|
async fn main() {
|
||||||
dioxus_desktop::launch(app);
|
dioxus_desktop::launch(app);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -10,7 +11,7 @@ fn app(cx: Scope) -> Element {
|
|||||||
|
|
||||||
use_future!(cx, || async move {
|
use_future!(cx, || async move {
|
||||||
loop {
|
loop {
|
||||||
tokio::time::sleep(std::time::Duration::from_millis(100)).await;
|
tokio::time::sleep(std::time::Duration::from_millis(10)).await;
|
||||||
count += 1;
|
count += 1;
|
||||||
println!("current: {count}");
|
println!("current: {count}");
|
||||||
}
|
}
|
||||||
|
|||||||
+11
-13
@@ -3,30 +3,28 @@ use crate::{
|
|||||||
desktop_context::{EventData, UserWindowEvent, WindowEventHandlers},
|
desktop_context::{EventData, UserWindowEvent, WindowEventHandlers},
|
||||||
edits::WebviewQueue,
|
edits::WebviewQueue,
|
||||||
element::DesktopElement,
|
element::DesktopElement,
|
||||||
events::IpcMessage,
|
|
||||||
file_upload::FileDialogRequest,
|
file_upload::FileDialogRequest,
|
||||||
|
ipc::IpcMessage,
|
||||||
query::QueryResult,
|
query::QueryResult,
|
||||||
shortcut::{GlobalHotKeyEvent, ShortcutRegistry},
|
shortcut::{GlobalHotKeyEvent, ShortcutRegistry},
|
||||||
webview::WebviewHandler,
|
webview::WebviewHandler,
|
||||||
};
|
};
|
||||||
use dioxus_core::{Component, ElementId, VirtualDom};
|
use dioxus_core::{Component, ElementId, VirtualDom};
|
||||||
use dioxus_html::MountedData;
|
use dioxus_html::{native_bind::NativeFileEngine, FormData, HtmlEvent, MountedData};
|
||||||
use dioxus_html::{native_bind::NativeFileEngine, FormData, HtmlEvent};
|
|
||||||
use futures_util::{pin_mut, FutureExt};
|
use futures_util::{pin_mut, FutureExt};
|
||||||
use std::cell::Cell;
|
use std::{cell::Cell, collections::HashMap, rc::Rc, sync::Arc};
|
||||||
use std::rc::Rc;
|
use tao::{
|
||||||
use std::{collections::HashMap, sync::Arc};
|
event::Event,
|
||||||
use tao::event_loop::EventLoopBuilder;
|
event_loop::{ControlFlow, EventLoop, EventLoopBuilder, EventLoopProxy, EventLoopWindowTarget},
|
||||||
use tao::event_loop::{EventLoop, EventLoopProxy, EventLoopWindowTarget};
|
window::WindowId,
|
||||||
use tao::window::WindowId;
|
};
|
||||||
use tao::{event::Event, event_loop::ControlFlow};
|
|
||||||
use wry::WebView;
|
|
||||||
|
|
||||||
pub struct App<P> {
|
pub(crate) struct App<P> {
|
||||||
// move the props into a cell so we can pop it out later to create the first window
|
// move the props into a cell so we can pop it out later to create the first window
|
||||||
// iOS panics if we create a window before the event loop is started
|
// iOS panics if we create a window before the event loop is started
|
||||||
pub(crate) props: Rc<Cell<Option<P>>>,
|
pub(crate) props: Rc<Cell<Option<P>>>,
|
||||||
pub(crate) cfg: Rc<Cell<Option<Config>>>,
|
pub(crate) cfg: Rc<Cell<Option<Config>>>,
|
||||||
|
|
||||||
pub(crate) root: Component<P>,
|
pub(crate) root: Component<P>,
|
||||||
pub(crate) webviews: HashMap<WindowId, WebviewHandler>,
|
pub(crate) webviews: HashMap<WindowId, WebviewHandler>,
|
||||||
pub(crate) event_handlers: WindowEventHandlers,
|
pub(crate) event_handlers: WindowEventHandlers,
|
||||||
@@ -310,7 +308,7 @@ impl<P: 'static> App<P> {
|
|||||||
|
|
||||||
/// Different hide implementations per platform
|
/// Different hide implementations per platform
|
||||||
#[allow(unused)]
|
#[allow(unused)]
|
||||||
pub fn hide_app_window(webview: &WebView) {
|
pub fn hide_app_window(webview: &wry::WebView) {
|
||||||
#[cfg(target_os = "windows")]
|
#[cfg(target_os = "windows")]
|
||||||
{
|
{
|
||||||
use wry::application::platform::windows::WindowExtWindows;
|
use wry::application::platform::windows::WindowExtWindows;
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|
||||||
|
use dioxus_core::prelude::Component;
|
||||||
use tao::window::{Icon, WindowBuilder, WindowId};
|
use tao::window::{Icon, WindowBuilder, WindowId};
|
||||||
use wry::{
|
use wry::{
|
||||||
http::{Request as HttpRequest, Response as HttpResponse},
|
http::{Request as HttpRequest, Response as HttpResponse},
|
||||||
@@ -68,6 +69,20 @@ impl Config {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Launch a Dioxus app using the given component and config
|
||||||
|
///
|
||||||
|
/// See the [`crate::launch::launch`] function for more details.
|
||||||
|
pub fn launch(self, root: Component<()>) {
|
||||||
|
crate::launch::launch_cfg(root, self)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Launch a Dioxus app using the given component, config, and props
|
||||||
|
///
|
||||||
|
/// See the [`crate::launch::launch_with_props`] function for more details.
|
||||||
|
pub fn launch_with_props<P: 'static>(self, root: Component<P>, props: P) {
|
||||||
|
crate::launch::launch_with_props(root, props, self)
|
||||||
|
}
|
||||||
|
|
||||||
/// Set whether the default menu bar should be enabled.
|
/// Set whether the default menu bar should be enabled.
|
||||||
///
|
///
|
||||||
/// > Note: `enable` is `true` by default. To disable the default menu bar pass `false`.
|
/// > Note: `enable` is `true` by default. To disable the default menu bar pass `false`.
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
use crate::events::IpcMessage;
|
use crate::ipc::IpcMessage;
|
||||||
use crate::query::QueryEngine;
|
use crate::query::QueryEngine;
|
||||||
use crate::shortcut::{HotKey, ShortcutId, ShortcutRegistry, ShortcutRegistryError};
|
use crate::shortcut::{HotKey, ShortcutId, ShortcutRegistry, ShortcutRegistryError};
|
||||||
use crate::AssetHandler;
|
use crate::AssetHandler;
|
||||||
|
|||||||
File renamed without changes.
@@ -1,12 +1,11 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
app::App,
|
app::App,
|
||||||
desktop_context::{EventData, UserWindowEvent},
|
desktop_context::{EventData, UserWindowEvent},
|
||||||
events::IpcMethod,
|
ipc::IpcMethod,
|
||||||
Config,
|
Config,
|
||||||
};
|
};
|
||||||
use dioxus_core::*;
|
use dioxus_core::*;
|
||||||
use tao::event::{Event, StartCause, WindowEvent};
|
use tao::event::{Event, StartCause, WindowEvent};
|
||||||
use tokio::runtime::Builder;
|
|
||||||
|
|
||||||
/// Launch the WebView and run the event loop.
|
/// Launch the WebView and run the event loop.
|
||||||
///
|
///
|
||||||
@@ -55,6 +54,7 @@ pub fn launch_cfg(root: Component, config_builder: Config) {
|
|||||||
|
|
||||||
/// Launch the WebView and run the event loop, with configuration and root props.
|
/// Launch the WebView and run the event loop, with configuration and root props.
|
||||||
///
|
///
|
||||||
|
/// If the [`tokio`] feature is enabled, this will also startup and block a tokio runtime using the unconstrained task.
|
||||||
/// This function will start a multithreaded Tokio runtime as well the WebView event loop. This will block the current thread.
|
/// 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
|
/// You can configure the WebView window with a configuration closure
|
||||||
@@ -78,12 +78,24 @@ pub fn launch_cfg(root: Component, config_builder: Config) {
|
|||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
pub fn launch_with_props<P: 'static>(root: Component<P>, props: P, cfg: Config) {
|
pub fn launch_with_props<P: 'static>(root: Component<P>, props: P, cfg: Config) {
|
||||||
// We start the tokio runtime *on this thread*
|
#[cfg(feature = "tokio")]
|
||||||
// Any future we poll later will use this runtime to spawn tasks and for IO
|
tokio::runtime::Builder::new_multi_thread()
|
||||||
// I would love to just allow dioxus to work with any runtime... but tokio is weird
|
.enable_all()
|
||||||
let rt = Builder::new_multi_thread().enable_all().build().unwrap();
|
.build()
|
||||||
let _guard = rt.enter();
|
.unwrap()
|
||||||
|
.block_on(tokio::task::unconstrained(async move {
|
||||||
|
launch_with_props_blocking(root, props, cfg);
|
||||||
|
}));
|
||||||
|
|
||||||
|
#[cfg(not(feature = "tokio"))]
|
||||||
|
launch_with_props_blocking(root, props, cfg);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Launch the WebView and run the event loop, with configuration and root props.
|
||||||
|
///
|
||||||
|
/// This will block the main thread, and *must* be spawned on the main thread. This function does not assume any runtime
|
||||||
|
/// and is equivalent to calling launch_with_props with the tokio feature disabled.
|
||||||
|
pub fn launch_with_props_blocking<P: 'static>(root: Component<P>, props: P, cfg: Config) {
|
||||||
let (event_loop, mut app) = App::new(cfg, props, root);
|
let (event_loop, mut app) = App::new(cfg, props, root);
|
||||||
|
|
||||||
event_loop.run(move |window_event, event_loop, control_flow| {
|
event_loop.run(move |window_event, event_loop, control_flow| {
|
||||||
|
|||||||
@@ -11,18 +11,19 @@ mod edits;
|
|||||||
mod element;
|
mod element;
|
||||||
mod escape;
|
mod escape;
|
||||||
mod eval;
|
mod eval;
|
||||||
mod events;
|
|
||||||
mod file_upload;
|
mod file_upload;
|
||||||
mod hooks;
|
mod hooks;
|
||||||
|
mod ipc;
|
||||||
mod menubar;
|
mod menubar;
|
||||||
#[cfg(any(target_os = "ios", target_os = "android"))]
|
|
||||||
mod mobile_shortcut;
|
|
||||||
mod protocol;
|
mod protocol;
|
||||||
mod query;
|
mod query;
|
||||||
mod shortcut;
|
mod shortcut;
|
||||||
mod waker;
|
mod waker;
|
||||||
mod webview;
|
mod webview;
|
||||||
|
|
||||||
|
#[cfg(any(target_os = "ios", target_os = "android"))]
|
||||||
|
mod mobile_shortcut;
|
||||||
|
|
||||||
// The main entrypoint for this crate
|
// The main entrypoint for this crate
|
||||||
pub use launch::*;
|
pub use launch::*;
|
||||||
mod launch;
|
mod launch;
|
||||||
|
|||||||
@@ -57,7 +57,8 @@ pub(super) async fn desktop_handler(
|
|||||||
.body(Cow::from(body))
|
.body(Cow::from(body))
|
||||||
{
|
{
|
||||||
Ok(response) => {
|
Ok(response) => {
|
||||||
return responder.respond(response);
|
responder.respond(response);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
Err(err) => tracing::error!("error building response: {}", err),
|
Err(err) => tracing::error!("error building response: {}", err),
|
||||||
}
|
}
|
||||||
@@ -103,7 +104,10 @@ pub(super) async fn desktop_handler(
|
|||||||
.header("Content-Type", content_type)
|
.header("Content-Type", content_type)
|
||||||
.body(Cow::from(asset))
|
.body(Cow::from(asset))
|
||||||
{
|
{
|
||||||
Ok(response) => return responder.respond(response),
|
Ok(response) => {
|
||||||
|
responder.respond(response);
|
||||||
|
return;
|
||||||
|
}
|
||||||
Err(err) => tracing::error!("error building response: {}", err),
|
Err(err) => tracing::error!("error building response: {}", err),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -114,6 +118,7 @@ pub(super) async fn desktop_handler(
|
|||||||
{
|
{
|
||||||
Ok(response) => {
|
Ok(response) => {
|
||||||
responder.respond(response);
|
responder.respond(response);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
Err(err) => tracing::error!("error building response: {}", err),
|
Err(err) => tracing::error!("error building response: {}", err),
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in new issue
Block a user