Implement Runtime and Executor in iced_core
They can be leveraged by shells to easily execute commands and track subscriptions.
This commit is contained in:
parent
32f7ca261f
commit
d50ff9b5d9
5 changed files with 97 additions and 4 deletions
|
|
@ -12,6 +12,8 @@ repository = "https://github.com/hecrj/iced"
|
||||||
command = ["futures"]
|
command = ["futures"]
|
||||||
# Exposes a future-based `Subscription` type
|
# Exposes a future-based `Subscription` type
|
||||||
subscription = ["futures", "log"]
|
subscription = ["futures", "log"]
|
||||||
|
# Exposes a `runtime` module meant to abstract over different future executors
|
||||||
|
runtime = ["command", "subscription"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
futures = { version = "0.3", optional = true }
|
futures = { version = "0.3", optional = true }
|
||||||
|
|
|
||||||
|
|
@ -44,3 +44,9 @@ pub mod subscription;
|
||||||
|
|
||||||
#[cfg(feature = "subscription")]
|
#[cfg(feature = "subscription")]
|
||||||
pub use subscription::Subscription;
|
pub use subscription::Subscription;
|
||||||
|
|
||||||
|
#[cfg(feature = "runtime")]
|
||||||
|
mod runtime;
|
||||||
|
|
||||||
|
#[cfg(feature = "runtime")]
|
||||||
|
pub use runtime::Runtime;
|
||||||
|
|
|
||||||
74
core/src/runtime.rs
Normal file
74
core/src/runtime.rs
Normal file
|
|
@ -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<Hasher, Event, Executor, Receiver, Message> {
|
||||||
|
executor: Executor,
|
||||||
|
subscriptions: subscription::Tracker<Hasher, Event>,
|
||||||
|
receiver: Receiver,
|
||||||
|
_message: PhantomData<Message>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<Hasher, Event, Executor, Receiver, Message>
|
||||||
|
Runtime<Hasher, Event, Executor, Receiver, Message>
|
||||||
|
where
|
||||||
|
Hasher: std::hash::Hasher + Default,
|
||||||
|
Event: Send + Clone + 'static,
|
||||||
|
Executor: self::Executor,
|
||||||
|
Receiver: Sink<Message, Error = core::convert::Infallible>
|
||||||
|
+ 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<Message>) {
|
||||||
|
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<Hasher, Event, Message>,
|
||||||
|
) {
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
11
core/src/runtime/executor.rs
Normal file
11
core/src/runtime/executor.rs
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
use futures::Future;
|
||||||
|
|
||||||
|
pub trait Executor {
|
||||||
|
fn new() -> Self;
|
||||||
|
|
||||||
|
fn spawn(&self, future: impl Future<Output = ()> + Send + 'static);
|
||||||
|
|
||||||
|
fn enter<R>(&self, f: impl FnOnce() -> R) -> R {
|
||||||
|
f()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -28,14 +28,14 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn update<Message, S>(
|
pub fn update<Message, Receiver>(
|
||||||
&mut self,
|
&mut self,
|
||||||
subscription: Subscription<Hasher, Event, Message>,
|
subscription: Subscription<Hasher, Event, Message>,
|
||||||
sink: S,
|
receiver: Receiver,
|
||||||
) -> Vec<BoxFuture<'static, ()>>
|
) -> Vec<BoxFuture<'static, ()>>
|
||||||
where
|
where
|
||||||
Message: 'static + Send,
|
Message: 'static + Send,
|
||||||
S: 'static
|
Receiver: 'static
|
||||||
+ Sink<Message, Error = core::convert::Infallible>
|
+ Sink<Message, Error = core::convert::Infallible>
|
||||||
+ Unpin
|
+ Unpin
|
||||||
+ Send
|
+ Send
|
||||||
|
|
@ -72,7 +72,7 @@ where
|
||||||
|
|
||||||
let future = futures::future::select(
|
let future = futures::future::select(
|
||||||
cancelled,
|
cancelled,
|
||||||
stream.map(Ok).forward(sink.clone()),
|
stream.map(Ok).forward(receiver.clone()),
|
||||||
)
|
)
|
||||||
.map(|_| ());
|
.map(|_| ());
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue