Function iced::subscription::channel
source · pub fn channel<I, Fut, Message>(
id: I,
size: usize,
f: impl FnOnce(Sender<Message>) -> Fut + MaybeSend + 'static
) -> Subscription<Message>where
I: Hash + 'static,
Fut: Future<Output = Infallible> + MaybeSend + 'static,
Message: 'static + MaybeSend,
Expand description
Creates a Subscription
that publishes the events sent from a Future
to an [mpsc::Sender
] with the given bounds.
Creating an asynchronous worker with bidirectional communication
You can leverage this helper to create a Subscription
that spawns
an asynchronous worker in the background and establish a channel of
communication with an iced
application.
You can achieve this by creating an mpsc
channel inside the closure
and returning the Sender
as a Message
for the Application
:
use iced_futures::subscription::{self, Subscription};
use iced_futures::futures::channel::mpsc;
use iced_futures::futures::sink::SinkExt;
pub enum Event {
Ready(mpsc::Sender<Input>),
WorkFinished,
// ...
}
enum Input {
DoSomeWork,
// ...
}
enum State {
Starting,
Ready(mpsc::Receiver<Input>),
}
fn some_worker() -> Subscription<Event> {
struct SomeWorker;
subscription::channel(std::any::TypeId::of::<SomeWorker>(), 100, |mut output| async move {
let mut state = State::Starting;
loop {
match &mut state {
State::Starting => {
// Create channel
let (sender, receiver) = mpsc::channel(100);
// Send the sender back to the application
output.send(Event::Ready(sender)).await;
// We are ready to receive messages
state = State::Ready(receiver);
}
State::Ready(receiver) => {
use iced_futures::futures::StreamExt;
// Read next input sent from `Application`
let input = receiver.select_next_some().await;
match input {
Input::DoSomeWork => {
// Do some async work...
// Finally, we can optionally produce a message to tell the
// `Application` the work is done
output.send(Event::WorkFinished).await;
}
}
}
}
}
})
}
Check out the websocket
example, which showcases this pattern to maintain a WebSocket
connection open.