summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/application.rs2
-rw-r--r--src/sandbox.rs2
-rw-r--r--web/Cargo.toml2
-rw-r--r--web/src/bus.rs2
-rw-r--r--web/src/element.rs8
-rw-r--r--web/src/lib.rs38
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,