1use crate::ecs::{
2 resources::{Read, Resources, Write},
3 system_param::SystemParam,
4};
5
6pub struct Events<T> {
13 current: Vec<(usize, T)>,
14 previous: Vec<(usize, T)>,
15 next_id: usize,
16}
17
18impl<T> Default for Events<T> {
19 fn default() -> Self {
20 Self { current: Vec::new(), previous: Vec::new(), next_id: 0 }
21 }
22}
23
24impl<T> Events<T> {
25 pub fn send(&mut self, event: T) {
26 self.current.push((self.next_id, event));
27 self.next_id += 1;
28 }
29
30 pub(crate) fn update(&mut self) {
31 self.previous = std::mem::take(&mut self.current);
32 }
33}
34
35pub struct EventReader<'a, T: 'static> {
39 events: Read<'a, Events<T>>,
40 last_seen: &'a mut usize,
41}
42
43impl<'a, T: 'static> EventReader<'a, T> {
44 pub fn iter(&mut self) -> impl Iterator<Item = &T> + '_ {
46 let seen = *self.last_seen;
47 let unread: Vec<&T> = self
48 .events
49 .previous
50 .iter()
51 .chain(self.events.current.iter())
52 .filter(|(id, _)| *id >= seen)
53 .map(|(_, event)| event)
54 .collect();
55 *self.last_seen = self.events.next_id;
56 unread.into_iter()
57 }
58
59 pub fn is_empty(&self) -> bool {
61 let seen = *self.last_seen;
62 !self.events.previous.iter().chain(self.events.current.iter()).any(|(id, _)| *id >= seen)
63 }
64}
65
66impl<T: 'static> SystemParam for EventReader<'static, T> {
67 type Item<'a> = EventReader<'a, T>;
68 type State = usize;
69
70 fn fetch<'a>(_world: &'a hecs::World, resources: &'a Resources, state: &'a mut Self::State) -> Self::Item<'a> {
71 EventReader { events: Read { inner: resources.get::<Events<T>>() }, last_seen: state }
72 }
73}
74
75impl<T> SystemParam for Option<EventReader<'static, T>>
76where
77 T: 'static + Sync + Send,
78{
79 type Item<'a> = Option<EventReader<'a, T>>;
80 type State = usize;
81
82 fn fetch<'a>(world: &'a hecs::World, resources: &'a Resources, state: &'a mut Self::State) -> Self::Item<'a> {
83 resources.contains::<Events<T>>().then(|| EventReader::fetch(world, resources, state))
84 }
85}
86
87pub struct EventWriter<'a, T: 'static> {
89 events: Write<'a, Events<T>>,
90}
91
92impl<'a, T: 'static> EventWriter<'a, T> {
93 pub fn send(&mut self, event: T) {
96 self.events.send(event);
97 }
98}
99
100impl<T: 'static> SystemParam for EventWriter<'static, T> {
101 type Item<'a> = EventWriter<'a, T>;
102 type State = ();
103
104 fn fetch<'a>(_world: &'a hecs::World, resources: &'a Resources, _state: &'a mut Self::State) -> Self::Item<'a> {
105 EventWriter { events: Write { inner: resources.get_mut::<Events<T>>() } }
106 }
107}
108
109impl<T> SystemParam for Option<EventWriter<'static, T>>
110where
111 T: 'static + Sync + Send,
112{
113 type Item<'a> = Option<EventWriter<'a, T>>;
114 type State = ();
115
116 fn fetch<'a>(world: &'a hecs::World, resources: &'a Resources, state: &'a mut Self::State) -> Self::Item<'a> {
117 resources.contains::<Events<T>>().then(|| EventWriter::fetch(world, resources, state))
118 }
119}
120
121pub(crate) fn age_events<T: Send + Sync + 'static>(mut events: Write<Events<T>>) {
122 events.update();
123}