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