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