From d50ff9b5d97d9c3d6c6c70a9b4efe764b6126c86 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Sun, 19 Jan 2020 09:06:48 +0100 Subject: Implement `Runtime` and `Executor` in `iced_core` They can be leveraged by shells to easily execute commands and track subscriptions. --- core/Cargo.toml | 2 ++ core/src/lib.rs | 6 ++++ core/src/runtime.rs | 74 ++++++++++++++++++++++++++++++++++++++++ core/src/runtime/executor.rs | 11 ++++++ core/src/subscription/tracker.rs | 8 ++--- 5 files changed, 97 insertions(+), 4 deletions(-) create mode 100644 core/src/runtime.rs create mode 100644 core/src/runtime/executor.rs (limited to 'core') diff --git a/core/Cargo.toml b/core/Cargo.toml index 4e019ba9..5e1a5532 100644 --- a/core/Cargo.toml +++ b/core/Cargo.toml @@ -12,6 +12,8 @@ repository = "https://github.com/hecrj/iced" command = ["futures"] # Exposes a future-based `Subscription` type subscription = ["futures", "log"] +# Exposes a `runtime` module meant to abstract over different future executors +runtime = ["command", "subscription"] [dependencies] futures = { version = "0.3", optional = true } diff --git a/core/src/lib.rs b/core/src/lib.rs index 6f13c310..760acefe 100644 --- a/core/src/lib.rs +++ b/core/src/lib.rs @@ -44,3 +44,9 @@ pub mod subscription; #[cfg(feature = "subscription")] pub use subscription::Subscription; + +#[cfg(feature = "runtime")] +mod runtime; + +#[cfg(feature = "runtime")] +pub use runtime::Runtime; diff --git a/core/src/runtime.rs b/core/src/runtime.rs new file mode 100644 index 00000000..31234d11 --- /dev/null +++ b/core/src/runtime.rs @@ -0,0 +1,74 @@ +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, + subscriptions: subscription::Tracker, + receiver: Receiver, + _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(receiver: Receiver) -> Self { + Self { + executor: Executor::new(), + subscriptions: subscription::Tracker::new(), + receiver, + _message: PhantomData, + } + } + + 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); + } +} diff --git a/core/src/runtime/executor.rs b/core/src/runtime/executor.rs new file mode 100644 index 00000000..d171c6d5 --- /dev/null +++ b/core/src/runtime/executor.rs @@ -0,0 +1,11 @@ +use futures::Future; + +pub trait Executor { + fn new() -> Self; + + fn spawn(&self, future: impl Future + Send + 'static); + + fn enter(&self, f: impl FnOnce() -> R) -> R { + f() + } +} diff --git a/core/src/subscription/tracker.rs b/core/src/subscription/tracker.rs index 826f60c0..a942b619 100644 --- a/core/src/subscription/tracker.rs +++ b/core/src/subscription/tracker.rs @@ -28,14 +28,14 @@ where } } - pub fn update( + pub fn update( &mut self, subscription: Subscription, - sink: S, + receiver: Receiver, ) -> Vec> where Message: 'static + Send, - S: 'static + Receiver: 'static + Sink + Unpin + Send @@ -72,7 +72,7 @@ where let future = futures::future::select( cancelled, - stream.map(Ok).forward(sink.clone()), + stream.map(Ok).forward(receiver.clone()), ) .map(|_| ()); -- cgit