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