diff options
author | 2019-11-24 11:25:14 +0100 | |
---|---|---|
committer | 2019-11-24 11:26:28 +0100 | |
commit | 9f3abe920271996cc4a9c533ad5e0e75e3d18a3d (patch) | |
tree | 88b04f05a51e61f1a9083e3a63df91665123ea30 | |
parent | 5b8f6948bb8b995b54de66572644da2885b7fcd8 (diff) | |
download | iced-9f3abe920271996cc4a9c533ad5e0e75e3d18a3d.tar.gz iced-9f3abe920271996cc4a9c533ad5e0e75e3d18a3d.tar.bz2 iced-9f3abe920271996cc4a9c533ad5e0e75e3d18a3d.zip |
Spawn `Command` futures in `iced_web`
-rw-r--r-- | src/application.rs | 2 | ||||
-rw-r--r-- | src/sandbox.rs | 2 | ||||
-rw-r--r-- | web/Cargo.toml | 2 | ||||
-rw-r--r-- | web/src/bus.rs | 2 | ||||
-rw-r--r-- | web/src/element.rs | 8 | ||||
-rw-r--r-- | web/src/lib.rs | 38 |
6 files changed, 36 insertions, 18 deletions
diff --git a/src/application.rs b/src/application.rs index d761c990..f6d3fb90 100644 --- a/src/application.rs +++ b/src/application.rs @@ -83,7 +83,7 @@ pub trait Application: Sized { /// The type of __messages__ your [`Application`] will produce. /// /// [`Application`]: trait.Application.html - type Message: std::fmt::Debug + Send; + type Message: std::fmt::Debug + Send + Clone; /// Initializes the [`Application`]. /// diff --git a/src/sandbox.rs b/src/sandbox.rs index 698578f4..60e3be14 100644 --- a/src/sandbox.rs +++ b/src/sandbox.rs @@ -81,7 +81,7 @@ pub trait Sandbox { /// The type of __messages__ your [`Sandbox`] will produce. /// /// [`Sandbox`]: trait.Sandbox.html - type Message: std::fmt::Debug + Send; + type Message: std::fmt::Debug + Send + Clone; /// Initializes the [`Sandbox`]. /// diff --git a/web/Cargo.toml b/web/Cargo.toml index da71c811..1d37e76c 100644 --- a/web/Cargo.toml +++ b/web/Cargo.toml @@ -18,6 +18,8 @@ maintenance = { status = "actively-developed" } iced_core = { version = "0.1.0-alpha", path = "../core", features = ["command"] } dodrio = "0.1.0" wasm-bindgen = "0.2.51" +wasm-bindgen-futures = "0.4" +futures = "0.3" [dependencies.web-sys] version = "0.3.27" diff --git a/web/src/bus.rs b/web/src/bus.rs index 09908679..1b650b28 100644 --- a/web/src/bus.rs +++ b/web/src/bus.rs @@ -15,7 +15,7 @@ pub struct Bus<Message> { impl<Message> Bus<Message> where - Message: 'static, + Message: 'static + Clone, { pub(crate) fn new() -> Self { Self { diff --git a/web/src/element.rs b/web/src/element.rs index 0315d7d6..85fa7c34 100644 --- a/web/src/element.rs +++ b/web/src/element.rs @@ -38,8 +38,8 @@ impl<'a, Message> Element<'a, Message> { /// [`Element`]: struct.Element.html pub fn map<F, B>(self, f: F) -> Element<'a, B> where - Message: 'static, - B: 'static, + Message: 'static + Clone, + B: 'static + Clone, F: 'static + Fn(Message) -> B, { Element { @@ -82,8 +82,8 @@ impl<'a, A, B> Map<'a, A, B> { impl<'a, A, B> Widget<B> for Map<'a, A, B> where - A: 'static, - B: 'static, + A: 'static + Clone, + B: 'static + Clone, { fn node<'b>( &self, diff --git a/web/src/lib.rs b/web/src/lib.rs index ac7f570c..dd401c31 100644 --- a/web/src/lib.rs +++ b/web/src/lib.rs @@ -57,7 +57,7 @@ #![deny(unsafe_code)] #![deny(rust_2018_idioms)] use dodrio::bumpalo; -use std::cell::RefCell; +use std::{cell::RefCell, rc::Rc}; mod bus; mod element; @@ -87,7 +87,7 @@ pub trait Application { /// The type of __messages__ your [`Application`] will produce. /// /// [`Application`]: trait.Application.html - type Message; + type Message: Clone; /// Initializes the [`Application`]. /// @@ -137,10 +137,10 @@ pub trait Application { where Self: 'static + Sized, { - // TODO: Spawn command - let (app, _command) = Self::new(); + let (app, command) = Self::new(); + let mut instance = Instance::new(app); - let instance = Instance::new(app); + instance.spawn(command); let window = web_sys::window().unwrap(); let document = window.document().unwrap(); @@ -151,26 +151,42 @@ pub trait Application { } } +#[derive(Clone)] struct Instance<Message> { - ui: RefCell<Box<dyn Application<Message = Message>>>, + ui: Rc<RefCell<Box<dyn Application<Message = Message>>>>, } -impl<Message> Instance<Message> { +impl<Message> Instance<Message> +where + Message: 'static + Clone, +{ fn new(ui: impl Application<Message = Message> + 'static) -> Self { Self { - ui: RefCell::new(Box::new(ui)), + ui: Rc::new(RefCell::new(Box::new(ui))), } } fn update(&mut self, message: Message) { - // TODO: Spawn command - let _command = self.ui.borrow_mut().update(message); + let command = self.ui.borrow_mut().update(message); + + self.spawn(command); + } + + fn spawn(&mut self, command: Command<Message>) { + use futures::FutureExt; + + for future in command.futures() { + let mut instance = self.clone(); + let future = future.map(move |message| instance.update(message)); + + wasm_bindgen_futures::spawn_local(future); + } } } impl<Message> dodrio::Render for Instance<Message> where - Message: 'static, + Message: 'static + Clone, { fn render<'a, 'bump>( &'a self, |