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> crate::system::sealed::Sealed for EventReader<'static, T> {}
124impl<T: 'static> SystemParam for EventReader<'static, T> {
125 type Item<'w> = EventReader<'w, T>;
126 fn fetch<'w>(world: &'w World, _dt: f32) -> Result<Self::Item<'w>, SystemParamFetchError> {
127 let events = Res::<Events<T>>::fetch(world, _dt)?;
128 Ok(EventReader { events })
129 }
130 fn get_access_info(info: &mut AccessInfo) {
131 Res::<'static, Events<T>>::get_access_info(info);
132 }
133}
134
135pub struct EventWriter<'w, T: 'static> {
140 events: ResMut<'w, Events<T>>,
141}
142
143impl<'w, T: 'static> EventWriter<'w, T> {
144 pub fn send(&mut self, event: T) {
146 self.events.send(event);
147 }
148
149 pub fn send_batch(&mut self, events: impl IntoIterator<Item = T>) {
151 for event in events {
152 self.events.send(event);
153 }
154 }
155}
156
157impl<T: 'static> crate::system::sealed::Sealed for EventWriter<'static, T> {}
158impl<T: 'static> SystemParam for EventWriter<'static, T> {
159 type Item<'w> = EventWriter<'w, T>;
160 fn fetch<'w>(world: &'w World, _dt: f32) -> Result<Self::Item<'w>, SystemParamFetchError> {
161 let events = ResMut::<Events<T>>::fetch(world, _dt)?;
162 Ok(EventWriter { events })
163 }
164 fn get_access_info(info: &mut AccessInfo) {
165 ResMut::<'static, Events<T>>::get_access_info(info);
166 }
167}
168
169#[cfg(test)]
170mod tests {
171 use super::*;
172
173 #[test]
174 fn test_send_and_iter() {
175 let mut events = Events::new();
176 events.send(1);
177 events.send(2);
178 events.send(3);
179
180 assert!(events.iter().next().is_none());
182 assert!(events.is_empty());
183
184 events.update();
186
187 let collected: Vec<&i32> = events.iter().collect();
189 assert_eq!(collected, vec![&1, &2, &3]);
190 assert_eq!(events.len(), 3);
191 }
192
193 #[test]
194 fn test_non_destructive_iter() {
195 let mut events = Events::new();
196 events.send(42);
197 events.update();
198
199 assert_eq!(events.iter().next(), Some(&42));
201 assert_eq!(events.iter().next(), Some(&42));
203 }
204
205 #[test]
206 fn test_double_buffer_isolation() {
207 let mut events = Events::new();
208
209 events.send(1);
211 events.update();
212
213 events.send(2);
215 let frame1_events: Vec<&i32> = events.iter().collect();
216 assert_eq!(frame1_events, vec![&1]); events.update();
219
220 let frame2_events: Vec<&i32> = events.iter().collect();
222 assert_eq!(frame2_events, vec![&2]);
223 }
224
225 #[test]
226 fn test_update_clears_previous() {
227 let mut events = Events::new();
228 events.send(1);
229 events.update();
230 assert_eq!(events.len(), 1);
231
232 events.update();
234 assert!(events.is_empty());
235 assert_eq!(events.len(), 0);
236 }
237
238 #[test]
239 fn test_push_backward_compat() {
240 let mut events = Events::new();
241 events.push(99); events.update();
243 assert_eq!(events.iter().next(), Some(&99));
244 }
245
246 #[test]
247 fn test_clear() {
248 let mut events = Events::new();
249 events.send(1);
250 events.update();
251 events.send(2);
252
253 events.clear();
254 assert!(events.is_empty());
255
256 events.update();
257 assert!(events.is_empty());
258 }
259
260 #[test]
261 fn test_drain_consumes() {
262 let mut events = Events::new();
263 events.send(10);
264 events.send(20);
265 events.update();
266
267 let drained: Vec<i32> = events.drain().collect();
268 assert_eq!(drained, vec![10, 20]);
269
270 assert!(events.is_empty());
272 }
273
274 #[test]
275 fn test_no_static_bound() {
276 struct Ephemeral<'a>(&'a str);
278 let mut events = Events::new();
279 let msg = String::from("test");
280 events.send(Ephemeral(&msg));
281 events.update();
282 assert_eq!(events.iter().next().unwrap().0, "test");
283 }
284}