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