From b5b17ed4d800c03beb3ad535d1069a7784e8dc1d Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Sun, 19 Jan 2020 10:17:08 +0100 Subject: Create `iced_futures` and wire everything up --- futures/src/runtime.rs | 79 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) create mode 100644 futures/src/runtime.rs (limited to 'futures/src/runtime.rs') diff --git a/futures/src/runtime.rs b/futures/src/runtime.rs new file mode 100644 index 00000000..bc1ad8ac --- /dev/null +++ b/futures/src/runtime.rs @@ -0,0 +1,79 @@ +//! Run commands and subscriptions. +mod executor; + +pub use executor::Executor; + +use crate::{subscription, Command, Subscription}; + +use futures::Sink; +use std::marker::PhantomData; + +#[derive(Debug)] +pub struct Runtime { + executor: Executor, + receiver: Receiver, + subscriptions: subscription::Tracker, + _message: PhantomData, +} + +impl + Runtime +where + Hasher: std::hash::Hasher + Default, + Event: Send + Clone + 'static, + Executor: self::Executor, + Receiver: Sink + + Unpin + + Send + + Clone + + 'static, + Message: Send + 'static, +{ + pub fn new(executor: Executor, receiver: Receiver) -> Self { + Self { + executor, + receiver, + subscriptions: subscription::Tracker::new(), + _message: PhantomData, + } + } + + pub fn enter(&self, f: impl FnOnce() -> R) -> R { + self.executor.enter(f) + } + + pub fn spawn(&mut self, command: Command) { + use futures::{FutureExt, SinkExt}; + + let futures = command.futures(); + + for future in futures { + let mut receiver = self.receiver.clone(); + + self.executor.spawn(future.then(|message| { + async move { + let _ = receiver.send(message).await; + + () + } + })); + } + } + + pub fn track( + &mut self, + subscription: Subscription, + ) { + let futures = self + .subscriptions + .update(subscription, self.receiver.clone()); + + for future in futures { + self.executor.spawn(future); + } + } + + pub fn broadcast(&mut self, event: Event) { + self.subscriptions.broadcast(event); + } +} -- cgit From b8b0d97525aaa2641d8493aa65e3108d70c1560a Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Sun, 19 Jan 2020 11:08:32 +0100 Subject: Rename `Receiver` to `Sender` in `Runtime` --- futures/src/runtime.rs | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) (limited to 'futures/src/runtime.rs') diff --git a/futures/src/runtime.rs b/futures/src/runtime.rs index bc1ad8ac..37905c61 100644 --- a/futures/src/runtime.rs +++ b/futures/src/runtime.rs @@ -9,30 +9,30 @@ use futures::Sink; use std::marker::PhantomData; #[derive(Debug)] -pub struct Runtime { +pub struct Runtime { executor: Executor, - receiver: Receiver, + sender: Sender, subscriptions: subscription::Tracker, _message: PhantomData, } -impl - Runtime +impl + Runtime where Hasher: std::hash::Hasher + Default, Event: Send + Clone + 'static, Executor: self::Executor, - Receiver: Sink + Sender: Sink + Unpin + Send + Clone + 'static, Message: Send + 'static, { - pub fn new(executor: Executor, receiver: Receiver) -> Self { + pub fn new(executor: Executor, sender: Sender) -> Self { Self { executor, - receiver, + sender, subscriptions: subscription::Tracker::new(), _message: PhantomData, } @@ -48,11 +48,11 @@ where let futures = command.futures(); for future in futures { - let mut receiver = self.receiver.clone(); + let mut sender = self.sender.clone(); self.executor.spawn(future.then(|message| { async move { - let _ = receiver.send(message).await; + let _ = sender.send(message).await; () } @@ -64,9 +64,8 @@ where &mut self, subscription: Subscription, ) { - let futures = self - .subscriptions - .update(subscription, self.receiver.clone()); + let futures = + self.subscriptions.update(subscription, self.sender.clone()); for future in futures { self.executor.spawn(future); -- cgit From 90690702e1e4abab804ec91e8ff4183824bec436 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Mon, 20 Jan 2020 04:47:36 +0100 Subject: Add `Application::Executor` associated type --- futures/src/runtime.rs | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) (limited to 'futures/src/runtime.rs') diff --git a/futures/src/runtime.rs b/futures/src/runtime.rs index 37905c61..a508c46e 100644 --- a/futures/src/runtime.rs +++ b/futures/src/runtime.rs @@ -1,9 +1,5 @@ -//! Run commands and subscriptions. -mod executor; - -pub use executor::Executor; - -use crate::{subscription, Command, Subscription}; +//! Run commands and keep track of subscriptions. +use crate::{subscription, Command, Executor, Subscription}; use futures::Sink; use std::marker::PhantomData; -- cgit From f14009601e270e43bdf29b8f4842cf136fbbd8b9 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Mon, 20 Jan 2020 09:49:17 +0100 Subject: Write documentation for `iced_futures` --- futures/src/runtime.rs | 45 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) (limited to 'futures/src/runtime.rs') diff --git a/futures/src/runtime.rs b/futures/src/runtime.rs index a508c46e..9fd9899a 100644 --- a/futures/src/runtime.rs +++ b/futures/src/runtime.rs @@ -4,6 +4,15 @@ use crate::{subscription, Command, Executor, Subscription}; use futures::Sink; use std::marker::PhantomData; +/// A batteries-included runtime of commands and subscriptions. +/// +/// If you have an [`Executor`], a [`Runtime`] can be leveraged to run any +/// [`Command`] or [`Subscription`] and get notified of the results! +/// +/// [`Runtime`]: struct.Runtime.html +/// [`Executor`]: executor/trait.Executor.html +/// [`Command`]: struct.Command.html +/// [`Subscription`]: subscription/struct.Subscription.html #[derive(Debug)] pub struct Runtime { executor: Executor, @@ -25,6 +34,13 @@ where + 'static, Message: Send + 'static, { + /// Creates a new empty [`Runtime`]. + /// + /// You need to provide: + /// - an [`Executor`] to spawn futures + /// - a `Sender` implementing `Sink` to receive the results + /// + /// [`Runtime`]: struct.Runtime.html pub fn new(executor: Executor, sender: Sender) -> Self { Self { executor, @@ -34,10 +50,24 @@ where } } + /// Runs the given closure inside the [`Executor`] of the [`Runtime`]. + /// + /// See [`Executor::enter`] to learn more. + /// + /// [`Executor`]: executor/trait.Executor.html + /// [`Runtime`]: struct.Runtime.html + /// [`Executor::enter`]: executor/trait.Executor.html#method.enter pub fn enter(&self, f: impl FnOnce() -> R) -> R { self.executor.enter(f) } + /// Spawns a [`Command`] in the [`Runtime`]. + /// + /// The resulting `Message` will be forwarded to the `Sender` of the + /// [`Runtime`]. + /// + /// [`Command`]: struct.Command.html + /// [`Runtime`]: struct.Runtime.html pub fn spawn(&mut self, command: Command) { use futures::{FutureExt, SinkExt}; @@ -56,6 +86,14 @@ where } } + /// Tracks a [`Subscription`] in the [`Runtime`]. + /// + /// It will spawn new streams or close old ones as necessary! See + /// [`Tracker::update`] to learn more about this! + /// + /// [`Subscription`]: subscription/struct.Subscription.html + /// [`Runtime`]: struct.Runtime.html + /// [`Tracker::update`]: subscription/struct.Tracker.html#method.update pub fn track( &mut self, subscription: Subscription, @@ -68,6 +106,13 @@ where } } + /// Broadcasts an event to all the subscriptions currently alive in the + /// [`Runtime`]. + /// + /// See [`Tracker::broadcast`] to learn more. + /// + /// [`Runtime`]: struct.Runtime.html + /// [`Tracker::broadcast`]: subscription/struct.Tracker.html#method.broadcast pub fn broadcast(&mut self, event: Event) { self.subscriptions.broadcast(event); } -- cgit