use async_broadcast::{broadcast, InactiveReceiver, Receiver, SendError, Sender, TrySendError};
use dioxus::prelude::ScopeState;
use uuid::Uuid;
#[derive(Debug, Clone)]
pub struct UseChannel<MessageType: Clone> {
id: Uuid,
sender: Sender<MessageType>,
inactive_receiver: InactiveReceiver<MessageType>,
}
impl<T: Clone> PartialEq for UseChannel<T> {
fn eq(&self, other: &Self) -> bool {
self.id == other.id
}
}
impl<MessageType: Clone> UseChannel<MessageType> {
pub fn try_send(&self, msg: impl Into<MessageType>) -> Result<(), TrySendError<MessageType>> {
self.sender.try_broadcast(msg.into()).map(|_| ())
}
pub async fn send(&self, msg: impl Into<MessageType>) -> Result<(), SendError<MessageType>> {
self.sender.broadcast(msg.into()).await.map(|_| ())
}
pub fn receiver(&mut self) -> Receiver<MessageType> {
self.inactive_receiver.clone().activate()
}
}
pub fn use_channel<MessageType: Clone + 'static>(
cx: &ScopeState,
size: usize,
) -> UseChannel<MessageType> {
let id = cx.use_hook(Uuid::new_v4);
let (sender, inactive_receiver) = cx.use_hook(|| {
let (sender, receiver) = broadcast::<MessageType>(size);
(sender, receiver.deactivate())
});
UseChannel {
id: *id,
sender: sender.clone(),
inactive_receiver: inactive_receiver.clone(),
}
}