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