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