data_router/
multi_exposed.rs

1#![allow(unused)]
2
3use counted_map::ReassignableCountedMap;
4
5pub trait MultiExpose<I: ?Sized> {
6    fn get_viewers(&self) -> &ReassignableCountedMap<usize, Box<I>>;
7    fn add_viewer(&mut self, other: Box<I>) -> Result<usize, counted_map::HashMapFull>;
8    fn remove_viewer(&mut self, id: usize) -> Option<Box<I>>;
9}
10
11macro_rules! multi_exposed_trait {
12    ($vis:vis $I:ident for $($E:ty)|*) => {
13        $vis trait $I: $($crate::event_horizon::view::View<$E>+)* {}
14        impl<I: $($crate::event_horizon::view::View<$E>+)*> $I for I {}
15    };
16}
17
18macro_rules! multi_exposed {
19    (#[derive($($attr:ident),*)] $vis:vis $Name:ident { $($viewers:ident as $I:ident for $($E:ty => $Output:ty)|*),* } else { $($P:ty => $POutput:ty),* }) => {
20        #[derive($($attr),*)]
21        $vis struct $Name<R> {
22            $($viewers: $crate::event_horizon::counted_map::ReassignableCountedMap<usize, Box<dyn $I>>,)*
23            receiver: R,
24        }
25
26        #[allow(unused)]
27        impl<R> $Name<R> {
28            pub fn new(receiver: R) -> Self {
29                Self { receiver, $($viewers: $crate::event_horizon::counted_map::ReassignableCountedMap::new(),)* }
30            }
31
32            pub fn get_receiver(&self) -> &R {
33                &self.receiver
34            }
35
36            pub fn get_receiver_mut(&mut self) -> &mut R {
37                &mut self.receiver
38            }
39
40            $(pub fn $viewers(&self) -> &$crate::event_horizon::counted_map::ReassignableCountedMap<usize, Box<dyn $I>> {
41                &self.$viewers
42            })*
43        }
44
45        $($(impl<R: $crate::event_horizon::receive::Receive<$E, Output = $Output>> $crate::event_horizon::receive::Receive<$E> for $Name<R> {
46            type Output = $Output;
47
48            fn send(&mut self, event: $E) -> $crate::event_horizon::receive::ReceiverResult<$E, Self::Output> {
49                let mut deleted = Vec::new();
50
51                for (id, viewer) in self.$viewers.iter_mut() {
52                    if viewer.view(&event).is_some() {
53                        deleted.push(*id);
54                    }
55                }
56
57                for id in deleted {
58                    self.$viewers.remove(id);
59                }
60
61                self.receiver.send(event)
62            }
63        })*)*
64
65        $(impl<R: $crate::event_horizon::receive::Receive<$P, Output = $POutput>> $crate::event_horizon::receive::Receive<$P> for $Name<R> {
66            type Output = $POutput;
67
68            fn send(&mut self, event: $P) -> $crate::event_horizon::receive::ReceiverResult<$P, Self::Output> {
69                self.receiver.send(event)
70            }
71        })*
72
73        $(impl<R> $crate::event_horizon::multi_exposed::MultiExpose<dyn $I> for $Name<R> {
74            fn get_viewers(&self) -> &$crate::event_horizon::counted_map::ReassignableCountedMap<usize, Box<dyn $I>> {
75                &self.$viewers
76            }
77            fn add_viewer(&mut self, other: Box<dyn $I>) -> Result<usize, $crate::event_horizon::counted_map::HashMapFull> {
78                self.$viewers.push(other)
79            }
80            fn remove_viewer(&mut self, id: usize) -> Option<Box<dyn $I>> {
81                self.$viewers.remove(id)
82            }
83        })*
84
85        impl<R> Default for $Name<R> where R: Default {
86            fn default() -> Self {
87                Self::new(R::default())
88            }
89        }
90
91        impl<R> std::fmt::Debug for $Name<R> where R: std::fmt::Debug {
92            fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
93                write!(f, "{{[")?;
94                $crate::event_horizon::multi_router::list_helper!(f, $($viewers, self.$viewers.len()),*);
95                write!(f, "], ")?;
96                write!(f, "{:?}}}", self.receiver)
97            }
98        }
99
100        impl<R> std::fmt::Display for $Name<R> where R: std::fmt::Display {
101            fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
102                self.receiver.fmt(f)
103            }
104        }
105    };
106}
107
108pub(crate) use multi_exposed;
109pub(crate) use multi_exposed_trait;