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
@ -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 }
|
||||
|
@ -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;
|
||||
|
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,
|
||||
subscription: Subscription<Hasher, Event, Message>,
|
||||
sink: S,
|
||||
receiver: Receiver,
|
||||
) -> Vec<BoxFuture<'static, ()>>
|
||||
where
|
||||
Message: 'static + Send,
|
||||
S: 'static
|
||||
Receiver: 'static
|
||||
+ Sink<Message, Error = core::convert::Infallible>
|
||||
+ 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(|_| ());
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user