1use crate::system::{AccessInfo, Res, ResMut, SystemParam, SystemParamFetchError};
2use crate::world::World;
3
4pub struct Events<T> {
27 current: Vec<T>,
29 previous: Vec<T>,
31}
32
33impl<T> Events<T> {
34 pub fn new() -> Self {
35 Self {
36 current: Vec::new(),
37 previous: Vec::new(),
38 }
39 }
40
41 #[inline]
43 pub fn send(&mut self, event: T) {
44 self.current.push(event);
45 }
46
47 #[inline]
49 pub fn push(&mut self, event: T) {
50 self.send(event);
51 }
52
53 pub fn update(&mut self) {
58 self.previous.clear();
59 std::mem::swap(&mut self.current, &mut self.previous);
60 }
61
62 pub fn iter(&self) -> impl Iterator<Item = &T> {
65 self.previous.iter()
66 }
67
68 #[inline]
70 pub fn len(&self) -> usize {
71 self.previous.len()
72 }
73
74 #[inline]
76 pub fn is_empty(&self) -> bool {
77 self.previous.is_empty()
78 }
79
80 pub fn clear(&mut self) {
82 self.current.clear();
83 self.previous.clear();
84 }
85
86 pub fn drain(&mut self) -> std::vec::IntoIter<T> {
90 self.previous.drain(..).collect::<Vec<_>>().into_iter()
91 }
92}
93
94impl<T> Default for Events<T> {
95 fn default() -> Self {
96 Self::new()
97 }
98}
99
100pub struct EventReader<'w, T: 'static> {
105 events: Res<'w, Events<T>>,
106}
107
108impl<'w, T: 'static> EventReader<'w, T> {
109 pub fn iter(&self) -> impl Iterator<Item = &T> {
111 self.events.iter()
112 }
113
114 pub fn len(&self) -> usize {
115 self.events.len()
116 }
117
118 pub fn is_empty(&self) -> bool {
119 self.events.is_empty()
120 }
121}
122
123impl<T: 'static> SystemParam for EventReader<'static, T> {
124 type Item<'w> = EventReader<'w, T>;
125 fn fetch<'w>(world: &'w World, _dt: f32) -> Result<Self::Item<'w>, SystemParamFetchError> {
126 let events = Res::<Events<T>>::fetch(world, _dt)?;
127 Ok(EventReader { events })
128 }
129 fn get_access_info(info: &mut AccessInfo) {
130 Res::<'static, Events<T>>::get_access_info(info);
131 }
132}
133
134pub struct EventWriter<'w, T: 'static> {
139 events: ResMut<'w, Events<T>>,
140}
141
142impl<'w, T: 'static> EventWriter<'w, T> {
143 pub fn send(&mut self, event: T) {
145 self.events.send(event);
146 }
147
148 pub fn send_batch(&mut self, events: impl IntoIterator<Item = T>) {
150 for event in events {
151 self.events.send(event);
152 }
153 }
154}
155
156impl<T: 'static> SystemParam for EventWriter<'static, T> {
157 type Item<'w> = EventWriter<'w, T>;
158 fn fetch<'w>(world: &'w World, _dt: f32) -> Result<Self::Item<'w>, SystemParamFetchError> {
159 let events = ResMut::<Events<T>>::fetch(world, _dt)?;
160 Ok(EventWriter { events })
161 }
162 fn get_access_info(info: &mut AccessInfo) {
163 ResMut::<'static, Events<T>>::get_access_info(info);
164 }
165}
166
167#[cfg(test)]
168mod tests {
169 use super::*;
170
171 #[test]
172 fn test_send_and_iter() {
173 let mut events = Events::new();
174 events.send(1);
175 events.send(2);
176 events.send(3);
177
178 assert!(events.iter().next().is_none());
180 assert!(events.is_empty());
181
182 events.update();
184
185 let collected: Vec<&i32> = events.iter().collect();
187 assert_eq!(collected, vec![&1, &2, &3]);
188 assert_eq!(events.len(), 3);
189 }
190
191 #[test]
192 fn test_non_destructive_iter() {
193 let mut events = Events::new();
194 events.send(42);
195 events.update();
196
197 assert_eq!(events.iter().next(), Some(&42));
199 assert_eq!(events.iter().next(), Some(&42));
201 }
202
203 #[test]
204 fn test_double_buffer_isolation() {
205 let mut events = Events::new();
206
207 events.send(1);
209 events.update();
210
211 events.send(2);
213 let frame1_events: Vec<&i32> = events.iter().collect();
214 assert_eq!(frame1_events, vec![&1]); events.update();
217
218 let frame2_events: Vec<&i32> = events.iter().collect();
220 assert_eq!(frame2_events, vec![&2]);
221 }
222
223 #[test]
224 fn test_update_clears_previous() {
225 let mut events = Events::new();
226 events.send(1);
227 events.update();
228 assert_eq!(events.len(), 1);
229
230 events.update();
232 assert!(events.is_empty());
233 assert_eq!(events.len(), 0);
234 }
235
236 #[test]
237 fn test_push_backward_compat() {
238 let mut events = Events::new();
239 events.push(99); events.update();
241 assert_eq!(events.iter().next(), Some(&99));
242 }
243
244 #[test]
245 fn test_clear() {
246 let mut events = Events::new();
247 events.send(1);
248 events.update();
249 events.send(2);
250
251 events.clear();
252 assert!(events.is_empty());
253
254 events.update();
255 assert!(events.is_empty());
256 }
257
258 #[test]
259 fn test_drain_consumes() {
260 let mut events = Events::new();
261 events.send(10);
262 events.send(20);
263 events.update();
264
265 let drained: Vec<i32> = events.drain().collect();
266 assert_eq!(drained, vec![10, 20]);
267
268 assert!(events.is_empty());
270 }
271
272 #[test]
273 fn test_no_static_bound() {
274 struct Ephemeral<'a>(&'a str);
276 let mut events = Events::new();
277 let msg = String::from("test");
278 events.send(Ephemeral(&msg));
279 events.update();
280 assert_eq!(events.iter().next().unwrap().0, "test");
281 }
282}