1mod 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 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 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.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 #[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 }; 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; 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 #[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}