1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108
use crate::widget::WidgetId; use std::{any::Any, sync::mpsc::Sender}; pub trait MessageData: std::fmt::Debug + Send + Sync { fn clone_message(&self) -> Box<dyn MessageData>; fn as_any(&self) -> &dyn Any; } impl Clone for Box<dyn MessageData> { fn clone(&self) -> Self { self.clone_message() } } pub type Message = Box<dyn MessageData>; pub type Messages = Vec<Message>; #[derive(Clone)] pub struct MessageSender(Sender<(WidgetId, Message)>); impl MessageSender { pub fn new(sender: Sender<(WidgetId, Message)>) -> Self { Self(sender) } pub fn write<T>(&self, id: WidgetId, message: T) -> bool where T: 'static + MessageData, { self.0.send((id, Box::new(message))).is_ok() } pub fn write_raw(&self, id: WidgetId, message: Message) -> bool { self.0.send((id, message)).is_ok() } pub fn write_raw_all<I>(&self, messages: I) where I: IntoIterator<Item = (WidgetId, Message)>, { for data in messages { let _ = self.0.send(data); } } } pub struct Messenger<'a> { sender: MessageSender, pub messages: &'a [Message], } impl<'a> Messenger<'a> { pub fn new(sender: MessageSender, messages: &'a [Message]) -> Self { Self { sender, messages } } pub fn write<T>(&self, id: WidgetId, message: T) -> bool where T: 'static + MessageData, { self.sender.write(id, message) } pub fn write_raw(&self, id: WidgetId, message: Message) -> bool { self.sender.write_raw(id, message) } pub fn write_raw_all<I>(&self, messages: I) where I: IntoIterator<Item = (WidgetId, Message)>, { self.sender.write_raw_all(messages); } } #[macro_export] macro_rules! implement_message_data { ($type_name:ty) => { impl $crate::messenger::MessageData for $type_name where Self: Clone, { fn clone_message(&self) -> Box<dyn $crate::messenger::MessageData> { Box::new(self.clone()) } fn as_any(&self) -> &dyn std::any::Any { self } } }; } implement_message_data!(()); implement_message_data!(i8); implement_message_data!(i16); implement_message_data!(i32); implement_message_data!(i64); implement_message_data!(i128); implement_message_data!(u8); implement_message_data!(u16); implement_message_data!(u32); implement_message_data!(u64); implement_message_data!(u128); implement_message_data!(f32); implement_message_data!(f64); implement_message_data!(bool); implement_message_data!(String);