bevy_ecs/event/
mod.rs

1//! Event handling types.
2mod base;
3mod collections;
4mod event_cursor;
5mod iterators;
6mod mut_iterators;
7mod mutator;
8mod reader;
9mod registry;
10mod update;
11mod writer;
12
13pub(crate) use base::EventInstance;
14pub use base::{Event, EventId};
15pub use bevy_ecs_macros::Event;
16pub use collections::{Events, SendBatchIds};
17pub use event_cursor::EventCursor;
18#[cfg(feature = "multi_threaded")]
19pub use iterators::EventParIter;
20pub use iterators::{EventIterator, EventIteratorWithId};
21#[cfg(feature = "multi_threaded")]
22pub use mut_iterators::EventMutParIter;
23pub use mut_iterators::{EventMutIterator, EventMutIteratorWithId};
24pub use mutator::EventMutator;
25pub use reader::EventReader;
26pub use registry::{EventRegistry, ShouldUpdateEvents};
27pub use update::{
28    event_update_condition, event_update_system, signal_event_update_system, EventUpdates,
29};
30pub use writer::EventWriter;
31
32#[cfg(test)]
33mod tests {
34    use alloc::{vec, vec::Vec};
35    use bevy_ecs::{event::*, system::assert_is_read_only_system};
36    use bevy_ecs_macros::Event;
37
38    #[derive(Event, Copy, Clone, PartialEq, Eq, Debug)]
39    struct TestEvent {
40        i: usize,
41    }
42
43    #[derive(Event, Clone, PartialEq, Debug, Default)]
44    struct EmptyTestEvent;
45
46    fn get_events<E: Event + Clone>(events: &Events<E>, cursor: &mut EventCursor<E>) -> Vec<E> {
47        cursor.read(events).cloned().collect::<Vec<E>>()
48    }
49
50    #[test]
51    fn test_events() {
52        let mut events = Events::<TestEvent>::default();
53        let event_0 = TestEvent { i: 0 };
54        let event_1 = TestEvent { i: 1 };
55        let event_2 = TestEvent { i: 2 };
56
57        // this reader will miss event_0 and event_1 because it wont read them over the course of
58        // two updates
59        let mut reader_missed: EventCursor<TestEvent> = events.get_cursor();
60
61        let mut reader_a: EventCursor<TestEvent> = events.get_cursor();
62
63        events.send(event_0);
64
65        assert_eq!(
66            get_events(&events, &mut reader_a),
67            vec![event_0],
68            "reader_a created before event receives event"
69        );
70        assert_eq!(
71            get_events(&events, &mut reader_a),
72            vec![],
73            "second iteration of reader_a created before event results in zero events"
74        );
75
76        let mut reader_b: EventCursor<TestEvent> = events.get_cursor();
77
78        assert_eq!(
79            get_events(&events, &mut reader_b),
80            vec![event_0],
81            "reader_b created after event receives event"
82        );
83        assert_eq!(
84            get_events(&events, &mut reader_b),
85            vec![],
86            "second iteration of reader_b created after event results in zero events"
87        );
88
89        events.send(event_1);
90
91        let mut reader_c = events.get_cursor();
92
93        assert_eq!(
94            get_events(&events, &mut reader_c),
95            vec![event_0, event_1],
96            "reader_c created after two events receives both events"
97        );
98        assert_eq!(
99            get_events(&events, &mut reader_c),
100            vec![],
101            "second iteration of reader_c created after two event results in zero events"
102        );
103
104        assert_eq!(
105            get_events(&events, &mut reader_a),
106            vec![event_1],
107            "reader_a receives next unread event"
108        );
109
110        events.update();
111
112        let mut reader_d = events.get_cursor();
113
114        events.send(event_2);
115
116        assert_eq!(
117            get_events(&events, &mut reader_a),
118            vec![event_2],
119            "reader_a receives event created after update"
120        );
121        assert_eq!(
122            get_events(&events, &mut reader_b),
123            vec![event_1, event_2],
124            "reader_b receives events created before and after update"
125        );
126        assert_eq!(
127            get_events(&events, &mut reader_d),
128            vec![event_0, event_1, event_2],
129            "reader_d receives all events created before and after update"
130        );
131
132        events.update();
133
134        assert_eq!(
135            get_events(&events, &mut reader_missed),
136            vec![event_2],
137            "reader_missed missed events unread after two update() calls"
138        );
139    }
140
141    // Events Collection
142    fn events_clear_and_read_impl(clear_func: impl FnOnce(&mut Events<TestEvent>)) {
143        let mut events = Events::<TestEvent>::default();
144        let mut reader = events.get_cursor();
145
146        assert!(reader.read(&events).next().is_none());
147
148        events.send(TestEvent { i: 0 });
149        assert_eq!(*reader.read(&events).next().unwrap(), TestEvent { i: 0 });
150        assert_eq!(reader.read(&events).next(), None);
151
152        events.send(TestEvent { i: 1 });
153        clear_func(&mut events);
154        assert!(reader.read(&events).next().is_none());
155
156        events.send(TestEvent { i: 2 });
157        events.update();
158        events.send(TestEvent { i: 3 });
159
160        assert!(reader
161            .read(&events)
162            .eq([TestEvent { i: 2 }, TestEvent { i: 3 }].iter()));
163    }
164
165    #[test]
166    fn test_events_clear_and_read() {
167        events_clear_and_read_impl(Events::clear);
168    }
169
170    #[test]
171    fn test_events_drain_and_read() {
172        events_clear_and_read_impl(|events| {
173            assert!(events
174                .drain()
175                .eq(vec![TestEvent { i: 0 }, TestEvent { i: 1 }].into_iter()));
176        });
177    }
178
179    #[test]
180    fn test_events_send_default() {
181        let mut events = Events::<EmptyTestEvent>::default();
182        events.send_default();
183
184        let mut reader = events.get_cursor();
185        assert_eq!(get_events(&events, &mut reader), vec![EmptyTestEvent]);
186    }
187
188    #[test]
189    fn test_send_events_ids() {
190        let mut events = Events::<TestEvent>::default();
191        let event_0 = TestEvent { i: 0 };
192        let event_1 = TestEvent { i: 1 };
193        let event_2 = TestEvent { i: 2 };
194
195        let event_0_id = events.send(event_0);
196
197        assert_eq!(
198            events.get_event(event_0_id.id),
199            Some((&event_0, event_0_id)),
200            "Getting a sent event by ID should return the original event"
201        );
202
203        let mut event_ids = events.send_batch([event_1, event_2]);
204
205        let event_id = event_ids.next().expect("Event 1 must have been sent");
206
207        assert_eq!(
208            events.get_event(event_id.id),
209            Some((&event_1, event_id)),
210            "Getting a sent event by ID should return the original event"
211        );
212
213        let event_id = event_ids.next().expect("Event 2 must have been sent");
214
215        assert_eq!(
216            events.get_event(event_id.id),
217            Some((&event_2, event_id)),
218            "Getting a sent event by ID should return the original event"
219        );
220
221        assert!(
222            event_ids.next().is_none(),
223            "Only sent two events; got more than two IDs"
224        );
225    }
226
227    #[test]
228    fn test_event_registry_can_add_and_remove_events_to_world() {
229        use bevy_ecs::prelude::*;
230
231        let mut world = World::new();
232        EventRegistry::register_event::<TestEvent>(&mut world);
233
234        let has_events = world.get_resource::<Events<TestEvent>>().is_some();
235        assert!(has_events, "Should have the events resource");
236
237        EventRegistry::deregister_events::<TestEvent>(&mut world);
238
239        let has_events = world.get_resource::<Events<TestEvent>>().is_some();
240        assert!(!has_events, "Should not have the events resource");
241    }
242
243    #[test]
244    fn test_events_update_drain() {
245        let mut events = Events::<TestEvent>::default();
246        let mut reader = events.get_cursor();
247
248        events.send(TestEvent { i: 0 });
249        events.send(TestEvent { i: 1 });
250        assert_eq!(reader.read(&events).count(), 2);
251
252        let mut old_events = Vec::from_iter(events.update_drain());
253        assert!(old_events.is_empty());
254
255        events.send(TestEvent { i: 2 });
256        assert_eq!(reader.read(&events).count(), 1);
257
258        old_events.extend(events.update_drain());
259        assert_eq!(old_events.len(), 2);
260
261        old_events.extend(events.update_drain());
262        assert_eq!(
263            old_events,
264            &[TestEvent { i: 0 }, TestEvent { i: 1 }, TestEvent { i: 2 }]
265        );
266    }
267
268    #[test]
269    fn test_events_empty() {
270        let mut events = Events::<TestEvent>::default();
271        assert!(events.is_empty());
272
273        events.send(TestEvent { i: 0 });
274        assert!(!events.is_empty());
275
276        events.update();
277        assert!(!events.is_empty());
278
279        // events are only empty after the second call to update
280        // due to double buffering.
281        events.update();
282        assert!(events.is_empty());
283    }
284
285    #[test]
286    fn test_events_extend_impl() {
287        let mut events = Events::<TestEvent>::default();
288        let mut reader = events.get_cursor();
289
290        events.extend(vec![TestEvent { i: 0 }, TestEvent { i: 1 }]);
291        assert!(reader
292            .read(&events)
293            .eq([TestEvent { i: 0 }, TestEvent { i: 1 }].iter()));
294    }
295
296    // Cursor
297    #[test]
298    fn test_event_cursor_read() {
299        let mut events = Events::<TestEvent>::default();
300        let mut cursor = events.get_cursor();
301        assert!(cursor.read(&events).next().is_none());
302
303        events.send(TestEvent { i: 0 });
304        let sent_event = cursor.read(&events).next().unwrap();
305        assert_eq!(sent_event, &TestEvent { i: 0 });
306        assert!(cursor.read(&events).next().is_none());
307
308        events.send(TestEvent { i: 2 });
309        let sent_event = cursor.read(&events).next().unwrap();
310        assert_eq!(sent_event, &TestEvent { i: 2 });
311        assert!(cursor.read(&events).next().is_none());
312
313        events.clear();
314        assert!(cursor.read(&events).next().is_none());
315    }
316
317    #[test]
318    fn test_event_cursor_read_mut() {
319        let mut events = Events::<TestEvent>::default();
320        let mut write_cursor = events.get_cursor();
321        let mut read_cursor = events.get_cursor();
322        assert!(write_cursor.read_mut(&mut events).next().is_none());
323        assert!(read_cursor.read(&events).next().is_none());
324
325        events.send(TestEvent { i: 0 });
326        let sent_event = write_cursor.read_mut(&mut events).next().unwrap();
327        assert_eq!(sent_event, &mut TestEvent { i: 0 });
328        *sent_event = TestEvent { i: 1 }; // Mutate whole event
329        assert_eq!(
330            read_cursor.read(&events).next().unwrap(),
331            &TestEvent { i: 1 }
332        );
333        assert!(read_cursor.read(&events).next().is_none());
334
335        events.send(TestEvent { i: 2 });
336        let sent_event = write_cursor.read_mut(&mut events).next().unwrap();
337        assert_eq!(sent_event, &mut TestEvent { i: 2 });
338        sent_event.i = 3; // Mutate sub value
339        assert_eq!(
340            read_cursor.read(&events).next().unwrap(),
341            &TestEvent { i: 3 }
342        );
343        assert!(read_cursor.read(&events).next().is_none());
344
345        events.clear();
346        assert!(write_cursor.read(&events).next().is_none());
347        assert!(read_cursor.read(&events).next().is_none());
348    }
349
350    #[test]
351    fn test_event_cursor_clear() {
352        let mut events = Events::<TestEvent>::default();
353        let mut reader = events.get_cursor();
354
355        events.send(TestEvent { i: 0 });
356        assert_eq!(reader.len(&events), 1);
357        reader.clear(&events);
358        assert_eq!(reader.len(&events), 0);
359    }
360
361    #[test]
362    fn test_event_cursor_len_update() {
363        let mut events = Events::<TestEvent>::default();
364        events.send(TestEvent { i: 0 });
365        events.send(TestEvent { i: 0 });
366        let reader = events.get_cursor();
367        assert_eq!(reader.len(&events), 2);
368        events.update();
369        events.send(TestEvent { i: 0 });
370        assert_eq!(reader.len(&events), 3);
371        events.update();
372        assert_eq!(reader.len(&events), 1);
373        events.update();
374        assert!(reader.is_empty(&events));
375    }
376
377    #[test]
378    fn test_event_cursor_len_current() {
379        let mut events = Events::<TestEvent>::default();
380        events.send(TestEvent { i: 0 });
381        let reader = events.get_cursor_current();
382        assert!(reader.is_empty(&events));
383        events.send(TestEvent { i: 0 });
384        assert_eq!(reader.len(&events), 1);
385        assert!(!reader.is_empty(&events));
386    }
387
388    #[test]
389    fn test_event_cursor_iter_len_updated() {
390        let mut events = Events::<TestEvent>::default();
391        events.send(TestEvent { i: 0 });
392        events.send(TestEvent { i: 1 });
393        events.send(TestEvent { i: 2 });
394        let mut reader = events.get_cursor();
395        let mut iter = reader.read(&events);
396        assert_eq!(iter.len(), 3);
397        iter.next();
398        assert_eq!(iter.len(), 2);
399        iter.next();
400        assert_eq!(iter.len(), 1);
401        iter.next();
402        assert_eq!(iter.len(), 0);
403    }
404
405    #[test]
406    fn test_event_cursor_len_empty() {
407        let events = Events::<TestEvent>::default();
408        assert_eq!(events.get_cursor().len(&events), 0);
409        assert!(events.get_cursor().is_empty(&events));
410    }
411
412    #[test]
413    fn test_event_cursor_len_filled() {
414        let mut events = Events::<TestEvent>::default();
415        events.send(TestEvent { i: 0 });
416        assert_eq!(events.get_cursor().len(&events), 1);
417        assert!(!events.get_cursor().is_empty(&events));
418    }
419
420    #[cfg(feature = "multi_threaded")]
421    #[test]
422    fn test_event_cursor_par_read() {
423        use crate::prelude::*;
424        use core::sync::atomic::{AtomicUsize, Ordering};
425
426        #[derive(Resource)]
427        struct Counter(AtomicUsize);
428
429        let mut world = World::new();
430        world.init_resource::<Events<TestEvent>>();
431        for _ in 0..100 {
432            world.send_event(TestEvent { i: 1 });
433        }
434
435        let mut schedule = Schedule::default();
436
437        schedule.add_systems(
438            |mut cursor: Local<EventCursor<TestEvent>>,
439             events: Res<Events<TestEvent>>,
440             counter: ResMut<Counter>| {
441                cursor.par_read(&events).for_each(|event| {
442                    counter.0.fetch_add(event.i, Ordering::Relaxed);
443                });
444            },
445        );
446
447        world.insert_resource(Counter(AtomicUsize::new(0)));
448        schedule.run(&mut world);
449        let counter = world.remove_resource::<Counter>().unwrap();
450        assert_eq!(counter.0.into_inner(), 100);
451
452        world.insert_resource(Counter(AtomicUsize::new(0)));
453        schedule.run(&mut world);
454        let counter = world.remove_resource::<Counter>().unwrap();
455        assert_eq!(
456            counter.0.into_inner(),
457            0,
458            "par_read should have consumed events but didn't"
459        );
460    }
461
462    #[cfg(feature = "multi_threaded")]
463    #[test]
464    fn test_event_cursor_par_read_mut() {
465        use crate::prelude::*;
466        use core::sync::atomic::{AtomicUsize, Ordering};
467
468        #[derive(Resource)]
469        struct Counter(AtomicUsize);
470
471        let mut world = World::new();
472        world.init_resource::<Events<TestEvent>>();
473        for _ in 0..100 {
474            world.send_event(TestEvent { i: 1 });
475        }
476        let mut schedule = Schedule::default();
477        schedule.add_systems(
478            |mut cursor: Local<EventCursor<TestEvent>>,
479             mut events: ResMut<Events<TestEvent>>,
480             counter: ResMut<Counter>| {
481                cursor.par_read_mut(&mut events).for_each(|event| {
482                    event.i += 1;
483                    counter.0.fetch_add(event.i, Ordering::Relaxed);
484                });
485            },
486        );
487        world.insert_resource(Counter(AtomicUsize::new(0)));
488        schedule.run(&mut world);
489        let counter = world.remove_resource::<Counter>().unwrap();
490        assert_eq!(counter.0.into_inner(), 200, "Initial run failed");
491
492        world.insert_resource(Counter(AtomicUsize::new(0)));
493        schedule.run(&mut world);
494        let counter = world.remove_resource::<Counter>().unwrap();
495        assert_eq!(
496            counter.0.into_inner(),
497            0,
498            "par_read_mut should have consumed events but didn't"
499        );
500    }
501
502    // Reader & Mutator
503    #[test]
504    fn ensure_reader_readonly() {
505        fn reader_system(_: EventReader<EmptyTestEvent>) {}
506
507        assert_is_read_only_system(reader_system);
508    }
509
510    #[test]
511    fn test_event_reader_iter_last() {
512        use bevy_ecs::prelude::*;
513
514        let mut world = World::new();
515        world.init_resource::<Events<TestEvent>>();
516
517        let mut reader =
518            IntoSystem::into_system(|mut events: EventReader<TestEvent>| -> Option<TestEvent> {
519                events.read().last().copied()
520            });
521        reader.initialize(&mut world);
522
523        let last = reader.run((), &mut world);
524        assert!(last.is_none(), "EventReader should be empty");
525
526        world.send_event(TestEvent { i: 0 });
527        let last = reader.run((), &mut world);
528        assert_eq!(last, Some(TestEvent { i: 0 }));
529
530        world.send_event(TestEvent { i: 1 });
531        world.send_event(TestEvent { i: 2 });
532        world.send_event(TestEvent { i: 3 });
533        let last = reader.run((), &mut world);
534        assert_eq!(last, Some(TestEvent { i: 3 }));
535
536        let last = reader.run((), &mut world);
537        assert!(last.is_none(), "EventReader should be empty");
538    }
539
540    #[test]
541    fn test_event_mutator_iter_last() {
542        use bevy_ecs::prelude::*;
543
544        let mut world = World::new();
545        world.init_resource::<Events<TestEvent>>();
546
547        let mut mutator =
548            IntoSystem::into_system(|mut events: EventMutator<TestEvent>| -> Option<TestEvent> {
549                events.read().last().copied()
550            });
551        mutator.initialize(&mut world);
552
553        let last = mutator.run((), &mut world);
554        assert!(last.is_none(), "EventMutator should be empty");
555
556        world.send_event(TestEvent { i: 0 });
557        let last = mutator.run((), &mut world);
558        assert_eq!(last, Some(TestEvent { i: 0 }));
559
560        world.send_event(TestEvent { i: 1 });
561        world.send_event(TestEvent { i: 2 });
562        world.send_event(TestEvent { i: 3 });
563        let last = mutator.run((), &mut world);
564        assert_eq!(last, Some(TestEvent { i: 3 }));
565
566        let last = mutator.run((), &mut world);
567        assert!(last.is_none(), "EventMutator should be empty");
568    }
569
570    #[test]
571    fn test_event_reader_iter_nth() {
572        use bevy_ecs::prelude::*;
573
574        let mut world = World::new();
575        world.init_resource::<Events<TestEvent>>();
576
577        world.send_event(TestEvent { i: 0 });
578        world.send_event(TestEvent { i: 1 });
579        world.send_event(TestEvent { i: 2 });
580        world.send_event(TestEvent { i: 3 });
581        world.send_event(TestEvent { i: 4 });
582
583        let mut schedule = Schedule::default();
584        schedule.add_systems(|mut events: EventReader<TestEvent>| {
585            let mut iter = events.read();
586
587            assert_eq!(iter.next(), Some(&TestEvent { i: 0 }));
588            assert_eq!(iter.nth(2), Some(&TestEvent { i: 3 }));
589            assert_eq!(iter.nth(1), None);
590
591            assert!(events.is_empty());
592        });
593        schedule.run(&mut world);
594    }
595
596    #[test]
597    fn test_event_mutator_iter_nth() {
598        use bevy_ecs::prelude::*;
599
600        let mut world = World::new();
601        world.init_resource::<Events<TestEvent>>();
602
603        world.send_event(TestEvent { i: 0 });
604        world.send_event(TestEvent { i: 1 });
605        world.send_event(TestEvent { i: 2 });
606        world.send_event(TestEvent { i: 3 });
607        world.send_event(TestEvent { i: 4 });
608
609        let mut schedule = Schedule::default();
610        schedule.add_systems(|mut events: EventReader<TestEvent>| {
611            let mut iter = events.read();
612
613            assert_eq!(iter.next(), Some(&TestEvent { i: 0 }));
614            assert_eq!(iter.nth(2), Some(&TestEvent { i: 3 }));
615            assert_eq!(iter.nth(1), None);
616
617            assert!(events.is_empty());
618        });
619        schedule.run(&mut world);
620    }
621}