dioxus_std/utils/channel/
use_channel.rs

1use async_broadcast::{broadcast, InactiveReceiver, Receiver, SendError, Sender, TrySendError};
2use dioxus::prelude::*;
3use uuid::Uuid;
4
5/// Send and listen for messages between multiple components.
6#[derive(Clone, Copy)]
7pub struct UseChannel<MessageType: Clone + 'static> {
8    id: Uuid,
9    sender: Signal<Sender<MessageType>>,
10    inactive_receiver: Signal<InactiveReceiver<MessageType>>,
11}
12
13impl<T: Clone> PartialEq for UseChannel<T> {
14    fn eq(&self, other: &Self) -> bool {
15        self.id == other.id
16    }
17}
18
19impl<MessageType: Clone + 'static> UseChannel<MessageType> {
20    /// Tries to send a message to all listeners of the channel.
21    pub fn try_send(&self, msg: impl Into<MessageType>) -> Result<(), TrySendError<MessageType>> {
22        self.sender.peek().try_broadcast(msg.into()).map(|_| ())
23    }
24
25    /// Sends a message to all listeners of the channel.
26    pub async fn send(&self, msg: impl Into<MessageType>) -> Result<(), SendError<MessageType>> {
27        self.sender.peek().broadcast(msg.into()).await.map(|_| ())
28    }
29
30    /// Create a receiver for the channel.
31    /// You probably want to use [`super::use_listen_channel()`].
32    pub fn receiver(&mut self) -> Receiver<MessageType> {
33        self.inactive_receiver.peek().clone().activate()
34    }
35}
36
37/// Send and listen for messages between multiple components.
38pub fn use_channel<MessageType: Clone + 'static>(size: usize) -> UseChannel<MessageType> {
39    use_hook(|| {
40        let id = Uuid::new_v4();
41        let (sender, receiver) = broadcast::<MessageType>(size);
42        UseChannel {
43            id,
44            sender: Signal::new(sender),
45            inactive_receiver: Signal::new(receiver.deactivate()),
46        }
47    })
48}