Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
bevyengine
GitHub Repository: bevyengine/bevy
Path: blob/main/crates/bevy_ecs/src/event/mod.rs
9372 views
1
//! [`Event`] functionality.
2
mod trigger;
3
4
pub use bevy_ecs_macros::{EntityEvent, Event};
5
pub use trigger::*;
6
7
use crate::{
8
component::{Component, ComponentId},
9
entity::Entity,
10
world::World,
11
};
12
use core::marker::PhantomData;
13
14
/// An [`Event`] is something that "happens" at a given moment.
15
///
16
/// To make an [`Event`] "happen", you "trigger" it on a [`World`] using [`World::trigger`] or via a [`Command`](crate::system::Command)
17
/// using [`Commands::trigger`](crate::system::Commands::trigger). This causes any [`Observer`](crate::observer::Observer) watching for that
18
/// [`Event`] to run _immediately_, as part of the [`World::trigger`] call.
19
///
20
/// First, we create an [`Event`] type, typically by deriving the trait.
21
///
22
/// ```
23
/// # use bevy_ecs::prelude::*;
24
/// #
25
/// #[derive(Event)]
26
/// struct Speak {
27
/// message: String,
28
/// }
29
/// ```
30
///
31
/// Then, we add an [`Observer`](crate::observer::Observer) to watch for this event type:
32
///
33
/// ```
34
/// # use bevy_ecs::prelude::*;
35
/// #
36
/// # #[derive(Event)]
37
/// # struct Speak {
38
/// # message: String,
39
/// # }
40
/// #
41
/// # let mut world = World::new();
42
/// #
43
/// world.add_observer(|speak: On<Speak>| {
44
/// println!("{}", speak.message);
45
/// });
46
/// ```
47
///
48
/// Finally, we trigger the event by calling [`World::trigger`](World::trigger):
49
///
50
/// ```
51
/// # use bevy_ecs::prelude::*;
52
/// #
53
/// # #[derive(Event)]
54
/// # struct Speak {
55
/// # message: String,
56
/// # }
57
/// #
58
/// # let mut world = World::new();
59
/// #
60
/// # world.add_observer(|speak: On<Speak>| {
61
/// # println!("{}", speak.message);
62
/// # });
63
/// #
64
/// # world.flush();
65
/// #
66
/// world.trigger(Speak {
67
/// message: "Hello!".to_string(),
68
/// });
69
/// ```
70
///
71
/// # Triggers
72
///
73
/// Every [`Event`] has an associated [`Trigger`] implementation (set via [`Event::Trigger`]), which defines which observers will run,
74
/// what data will be passed to them, and the order they will be run in. Unless you are an internals developer or you have very specific
75
/// needs, you don't need to worry too much about [`Trigger`]. When you derive [`Event`] (or a more specific event trait like [`EntityEvent`]),
76
/// a [`Trigger`] will be provided for you.
77
///
78
/// The [`Event`] derive defaults [`Event::Trigger`] to [`GlobalTrigger`], which will run all observers that watch for the [`Event`].
79
///
80
/// # Entity Events
81
///
82
/// For events that "target" a specific [`Entity`], see [`EntityEvent`].
83
#[diagnostic::on_unimplemented(
84
message = "`{Self}` is not an `Event`",
85
label = "invalid `Event`",
86
note = "consider annotating `{Self}` with `#[derive(Event)]`"
87
)]
88
pub trait Event: Send + Sync + Sized + 'static {
89
/// Defines which observers will run, what data will be passed to them, and the order they will be run in. See [`Trigger`] for more info.
90
type Trigger<'a>: Trigger<Self>;
91
}
92
93
/// An [`EntityEvent`] is an [`Event`] that is triggered for a specific [`EntityEvent::event_target`] entity:
94
///
95
/// ```
96
/// # use bevy_ecs::prelude::*;
97
/// # let mut world = World::default();
98
/// # let entity = world.spawn_empty().id();
99
/// #[derive(EntityEvent)]
100
/// struct Explode {
101
/// entity: Entity,
102
/// }
103
///
104
/// world.add_observer(|event: On<Explode>, mut commands: Commands| {
105
/// println!("Entity {} goes BOOM!", event.entity);
106
/// commands.entity(event.entity).despawn();
107
/// });
108
///
109
/// world.trigger(Explode { entity });
110
/// ```
111
///
112
/// [`EntityEvent`] will set [`EntityEvent::event_target`] automatically for named structs with an `entity` field name (as seen above). It also works for tuple structs
113
/// whose only field is [`Entity`]:
114
///
115
/// ```
116
/// # use bevy_ecs::prelude::*;
117
/// #[derive(EntityEvent)]
118
/// struct Explode(Entity);
119
/// ```
120
///
121
/// The [`EntityEvent::event_target`] can also be manually set using the `#[event_target]` field attribute:
122
///
123
/// ```
124
/// # use bevy_ecs::prelude::*;
125
/// #[derive(EntityEvent)]
126
/// struct Explode {
127
/// #[event_target]
128
/// exploded_entity: Entity,
129
/// }
130
/// ```
131
///
132
/// ```
133
/// # use bevy_ecs::prelude::*;
134
/// #[derive(EntityEvent)]
135
/// struct Explode(#[event_target] Entity);
136
/// ```
137
///
138
/// You may also use any type which implements [`ContainsEntity`](crate::entity::ContainsEntity) as the event target:
139
///
140
/// ```
141
/// # use bevy_ecs::prelude::*;
142
/// struct Bomb(Entity);
143
///
144
/// impl ContainsEntity for Bomb {
145
/// fn entity(&self) -> Entity {
146
/// self.0
147
/// }
148
/// }
149
///
150
/// #[derive(EntityEvent)]
151
/// struct Explode(Bomb);
152
/// ```
153
///
154
/// By default, an [`EntityEvent`] is immutable. This means the event data, including the target, does not change while the event
155
/// is triggered. However, to support event propagation, your event must also implement the [`SetEntityEventTarget`] trait.
156
///
157
/// This trait is automatically implemented for you if you enable event propagation:
158
/// ```
159
/// # use bevy_ecs::prelude::*;
160
/// #[derive(EntityEvent)]
161
/// #[entity_event(propagate)]
162
/// struct Explode(Entity);
163
/// ```
164
///
165
/// ## Trigger Behavior
166
///
167
/// When derived, [`EntityEvent`] defaults to setting [`Event::Trigger`] to [`EntityTrigger`], which will run all normal "untargeted"
168
/// observers added via [`World::add_observer`], just like a default [`Event`] would (see the example above).
169
///
170
/// However it will _also_ run all observers that watch _specific_ entities, which enables you to assign entity-specific logic:
171
///
172
/// ```
173
/// # use bevy_ecs::prelude::*;
174
/// # #[derive(Component, Debug)]
175
/// # struct Name(String);
176
/// # let mut world = World::default();
177
/// # let e1 = world.spawn_empty().id();
178
/// # let e2 = world.spawn_empty().id();
179
/// # #[derive(EntityEvent)]
180
/// # struct Explode {
181
/// # entity: Entity,
182
/// # }
183
/// world.entity_mut(e1).observe(|event: On<Explode>, mut commands: Commands| {
184
/// println!("Boom!");
185
/// commands.entity(event.entity).despawn();
186
/// });
187
///
188
/// world.entity_mut(e2).observe(|event: On<Explode>, mut commands: Commands| {
189
/// println!("The explosion fizzles! This entity is immune!");
190
/// });
191
/// ```
192
///
193
/// ## [`EntityEvent`] Propagation
194
///
195
/// When deriving [`EntityEvent`], you can enable "event propagation" (also known as "event bubbling") by
196
/// specifying the `#[entity_event(propagate)]` attribute:
197
///
198
/// ```
199
/// # use bevy_ecs::prelude::*;
200
/// #[derive(EntityEvent)]
201
/// #[entity_event(propagate)]
202
/// struct Click {
203
/// entity: Entity,
204
/// }
205
/// ```
206
///
207
/// This will default to using the [`ChildOf`](crate::hierarchy::ChildOf) component to propagate the [`Event`] "up"
208
/// the hierarchy (from child to parent).
209
///
210
/// You can also specify your own [`Traversal`](crate::traversal::Traversal) implementation. A common pattern is to use
211
/// [`Relationship`](crate::relationship::Relationship) components, which will follow the relationships to their root
212
/// (just be sure to avoid cycles ... these aren't detected for performance reasons):
213
///
214
/// ```
215
/// # use bevy_ecs::prelude::*;
216
/// #[derive(Component)]
217
/// #[relationship(relationship_target = ClickableBy)]
218
/// struct Clickable(Entity);
219
///
220
/// #[derive(Component)]
221
/// #[relationship_target(relationship = Clickable)]
222
/// struct ClickableBy(Vec<Entity>);
223
///
224
/// #[derive(EntityEvent)]
225
/// #[entity_event(propagate = &'static Clickable)]
226
/// struct Click {
227
/// entity: Entity,
228
/// }
229
/// ```
230
///
231
/// By default, propagation requires observers to opt-in:
232
///
233
/// ```
234
/// # use bevy_ecs::prelude::*;
235
/// #[derive(EntityEvent)]
236
/// #[entity_event(propagate)]
237
/// struct Click {
238
/// entity: Entity,
239
/// }
240
///
241
/// # let mut world = World::default();
242
/// world.add_observer(|mut click: On<Click>| {
243
/// // this will propagate the event up to the parent, using `ChildOf`
244
/// click.propagate(true);
245
/// });
246
/// ```
247
///
248
/// But you can enable auto propagation using the `#[entity_event(auto_propagate)]` attribute:
249
/// ```
250
/// # use bevy_ecs::prelude::*;
251
/// #[derive(EntityEvent)]
252
/// #[entity_event(propagate, auto_propagate)]
253
/// struct Click {
254
/// entity: Entity,
255
/// }
256
/// ```
257
///
258
/// You can also _stop_ propagation like this:
259
/// ```
260
/// # use bevy_ecs::prelude::*;
261
/// # #[derive(EntityEvent)]
262
/// # #[entity_event(propagate)]
263
/// # struct Click {
264
/// # entity: Entity,
265
/// # }
266
/// # fn is_finished_propagating() -> bool { true }
267
/// # let mut world = World::default();
268
/// world.add_observer(|mut click: On<Click>| {
269
/// if is_finished_propagating() {
270
/// click.propagate(false);
271
/// }
272
/// });
273
/// ```
274
///
275
/// ## Naming and Usage Conventions
276
///
277
/// In most cases, it is recommended to use a named struct field for the "event target" entity, and to use
278
/// a name that is descriptive as possible, as this makes events easier to understand and read.
279
///
280
/// For events with only one [`Entity`] field, `entity` is often a reasonable name. But if there are multiple
281
/// [`Entity`] fields, it is often a good idea to use a more descriptive name.
282
///
283
/// It is also generally recommended to _consume_ "event target" entities directly via their named field, as this
284
/// can make the context clearer, allows for more specific documentation hints in IDEs, and it generally reads better.
285
///
286
/// ## Manually spawning [`EntityEvent`] observers
287
///
288
/// The examples above that call [`EntityWorldMut::observe`] to add entity-specific observer logic are
289
/// just shorthand for spawning an [`Observer`] directly and manually watching the entity:
290
///
291
/// ```
292
/// # use bevy_ecs::prelude::*;
293
/// # let mut world = World::default();
294
/// # let entity = world.spawn_empty().id();
295
/// # #[derive(EntityEvent)]
296
/// # struct Explode(Entity);
297
/// let mut observer = Observer::new(|event: On<Explode>| {});
298
/// observer.watch_entity(entity);
299
/// world.spawn(observer);
300
/// ```
301
///
302
/// Note that the [`Observer`] component is not added to the entity it is observing. Observers should always be their own entities, as there
303
/// can be multiple observers of the same entity!
304
///
305
/// You can call [`Observer::watch_entity`] more than once or [`Observer::watch_entities`] to watch multiple entities with the same [`Observer`].
306
///
307
/// [`EntityWorldMut::observe`]: crate::world::EntityWorldMut::observe
308
/// [`Observer`]: crate::observer::Observer
309
/// [`Observer::watch_entity`]: crate::observer::Observer::watch_entity
310
/// [`Observer::watch_entities`]: crate::observer::Observer::watch_entities
311
pub trait EntityEvent: Event {
312
/// The [`Entity`] "target" of this [`EntityEvent`]. When triggered, this will run observers that watch for this specific entity.
313
fn event_target(&self) -> Entity;
314
}
315
316
/// A trait which is used to set the target of an [`EntityEvent`].
317
///
318
/// By default, entity events are immutable; meaning their target does not change during the lifetime of the event. However, some events
319
/// may require mutable access to provide features such as event propagation.
320
///
321
/// You should never need to implement this trait manually if you use `#[derive(EntityEvent)]`. It is automatically implemented for you if you
322
/// use `#[entity_event(propagate)]`.
323
pub trait SetEntityEventTarget: EntityEvent {
324
/// Sets the [`Entity`] "target" of this [`EntityEvent`]. When triggered, this will run observers that watch for this specific entity.
325
///
326
/// Note: In general, this should not be called from within an [`Observer`](crate::observer::Observer), as this will not "retarget"
327
/// the event in any of Bevy's built-in [`Trigger`] implementations.
328
fn set_event_target(&mut self, entity: Entity);
329
}
330
331
impl World {
332
/// Generates the [`EventKey`] for this event type.
333
///
334
/// If this type has already been registered,
335
/// this will return the existing [`EventKey`].
336
///
337
/// This is used by various dynamically typed observer APIs,
338
/// such as [`DeferredWorld::trigger_raw`](crate::world::DeferredWorld::trigger_raw).
339
pub fn register_event_key<E: Event>(&mut self) -> EventKey {
340
EventKey(self.register_component::<EventWrapperComponent<E>>())
341
}
342
343
/// Fetches the [`EventKey`] for this event type,
344
/// if it has already been generated.
345
///
346
/// This is used by various dynamically typed observer APIs,
347
/// such as [`DeferredWorld::trigger_raw`](crate::world::DeferredWorld::trigger_raw).
348
pub fn event_key<E: Event>(&self) -> Option<EventKey> {
349
self.component_id::<EventWrapperComponent<E>>()
350
.map(EventKey)
351
}
352
}
353
354
/// An internal type that implements [`Component`] for a given [`Event`] type.
355
///
356
/// This exists so we can easily get access to a unique [`ComponentId`] for each [`Event`] type,
357
/// without requiring that [`Event`] types implement [`Component`] directly.
358
/// [`ComponentId`] is used internally as a unique identifier for events because they are:
359
///
360
/// - Unique to each event type.
361
/// - Can be quickly generated and looked up.
362
/// - Are compatible with dynamic event types, which aren't backed by a Rust type.
363
///
364
/// This type is an implementation detail and should never be made public.
365
// TODO: refactor events to store their metadata on distinct entities, rather than using `ComponentId`
366
#[derive(Component)]
367
struct EventWrapperComponent<E: Event>(PhantomData<E>);
368
369
/// A unique identifier for an [`Event`], used by [observers].
370
///
371
/// You can look up the key for your event by calling the [`World::event_key`] method.
372
///
373
/// [observers]: crate::observer
374
#[derive(Debug, Copy, Clone, Hash, Ord, PartialOrd, Eq, PartialEq)]
375
pub struct EventKey(pub(crate) ComponentId);
376
377
#[cfg(test)]
378
mod tests {
379
use alloc::{vec, vec::Vec};
380
use bevy_ecs::{message::*, system::assert_is_read_only_system};
381
use bevy_ecs_macros::Message;
382
383
#[derive(Message, Copy, Clone, PartialEq, Eq, Debug)]
384
struct TestEvent {
385
i: usize,
386
}
387
388
#[derive(Message, Clone, PartialEq, Debug, Default)]
389
struct EmptyTestEvent;
390
391
fn get_events<E: Message + Clone>(
392
events: &Messages<E>,
393
cursor: &mut MessageCursor<E>,
394
) -> Vec<E> {
395
cursor.read(events).cloned().collect::<Vec<E>>()
396
}
397
398
#[test]
399
fn test_events() {
400
let mut events = Messages::<TestEvent>::default();
401
let event_0 = TestEvent { i: 0 };
402
let event_1 = TestEvent { i: 1 };
403
let event_2 = TestEvent { i: 2 };
404
405
// this reader will miss event_0 and event_1 because it wont read them over the course of
406
// two updates
407
let mut reader_missed: MessageCursor<TestEvent> = events.get_cursor();
408
409
let mut reader_a: MessageCursor<TestEvent> = events.get_cursor();
410
411
events.write(event_0);
412
413
assert_eq!(
414
get_events(&events, &mut reader_a),
415
vec![event_0],
416
"reader_a created before event receives event"
417
);
418
assert_eq!(
419
get_events(&events, &mut reader_a),
420
vec![],
421
"second iteration of reader_a created before event results in zero events"
422
);
423
424
let mut reader_b: MessageCursor<TestEvent> = events.get_cursor();
425
426
assert_eq!(
427
get_events(&events, &mut reader_b),
428
vec![event_0],
429
"reader_b created after event receives event"
430
);
431
assert_eq!(
432
get_events(&events, &mut reader_b),
433
vec![],
434
"second iteration of reader_b created after event results in zero events"
435
);
436
437
events.write(event_1);
438
439
let mut reader_c = events.get_cursor();
440
441
assert_eq!(
442
get_events(&events, &mut reader_c),
443
vec![event_0, event_1],
444
"reader_c created after two events receives both events"
445
);
446
assert_eq!(
447
get_events(&events, &mut reader_c),
448
vec![],
449
"second iteration of reader_c created after two event results in zero events"
450
);
451
452
assert_eq!(
453
get_events(&events, &mut reader_a),
454
vec![event_1],
455
"reader_a receives next unread event"
456
);
457
458
events.update();
459
460
let mut reader_d = events.get_cursor();
461
462
events.write(event_2);
463
464
assert_eq!(
465
get_events(&events, &mut reader_a),
466
vec![event_2],
467
"reader_a receives event created after update"
468
);
469
assert_eq!(
470
get_events(&events, &mut reader_b),
471
vec![event_1, event_2],
472
"reader_b receives events created before and after update"
473
);
474
assert_eq!(
475
get_events(&events, &mut reader_d),
476
vec![event_0, event_1, event_2],
477
"reader_d receives all events created before and after update"
478
);
479
480
events.update();
481
482
assert_eq!(
483
get_events(&events, &mut reader_missed),
484
vec![event_2],
485
"reader_missed missed events unread after two update() calls"
486
);
487
}
488
489
// Events Collection
490
fn events_clear_and_read_impl(clear_func: impl FnOnce(&mut Messages<TestEvent>)) {
491
let mut events = Messages::<TestEvent>::default();
492
let mut reader = events.get_cursor();
493
494
assert!(reader.read(&events).next().is_none());
495
496
events.write(TestEvent { i: 0 });
497
assert_eq!(*reader.read(&events).next().unwrap(), TestEvent { i: 0 });
498
assert_eq!(reader.read(&events).next(), None);
499
500
events.write(TestEvent { i: 1 });
501
clear_func(&mut events);
502
assert!(reader.read(&events).next().is_none());
503
504
events.write(TestEvent { i: 2 });
505
events.update();
506
events.write(TestEvent { i: 3 });
507
508
assert!(reader
509
.read(&events)
510
.eq([TestEvent { i: 2 }, TestEvent { i: 3 }].iter()));
511
}
512
513
#[test]
514
fn test_events_clear_and_read() {
515
events_clear_and_read_impl(Messages::clear);
516
}
517
518
#[test]
519
fn test_events_drain_and_read() {
520
events_clear_and_read_impl(|events| {
521
assert!(events
522
.drain()
523
.eq(vec![TestEvent { i: 0 }, TestEvent { i: 1 }].into_iter()));
524
});
525
}
526
527
#[test]
528
fn test_events_write_default() {
529
let mut events = Messages::<EmptyTestEvent>::default();
530
events.write_default();
531
532
let mut reader = events.get_cursor();
533
assert_eq!(get_events(&events, &mut reader), vec![EmptyTestEvent]);
534
}
535
536
#[test]
537
fn test_write_events_ids() {
538
let mut events = Messages::<TestEvent>::default();
539
let event_0 = TestEvent { i: 0 };
540
let event_1 = TestEvent { i: 1 };
541
let event_2 = TestEvent { i: 2 };
542
543
let event_0_id = events.write(event_0);
544
545
assert_eq!(
546
events.get_message(event_0_id.id),
547
Some((&event_0, event_0_id)),
548
"Getting a sent event by ID should return the original event"
549
);
550
551
let mut event_ids = events.write_batch([event_1, event_2]);
552
553
let event_id = event_ids.next().expect("Event 1 must have been sent");
554
555
assert_eq!(
556
events.get_message(event_id.id),
557
Some((&event_1, event_id)),
558
"Getting a sent event by ID should return the original event"
559
);
560
561
let event_id = event_ids.next().expect("Event 2 must have been sent");
562
563
assert_eq!(
564
events.get_message(event_id.id),
565
Some((&event_2, event_id)),
566
"Getting a sent event by ID should return the original event"
567
);
568
569
assert!(
570
event_ids.next().is_none(),
571
"Only sent two events; got more than two IDs"
572
);
573
}
574
575
#[test]
576
fn test_event_registry_can_add_and_remove_events_to_world() {
577
use bevy_ecs::prelude::*;
578
579
let mut world = World::new();
580
MessageRegistry::register_message::<TestEvent>(&mut world);
581
582
let has_events = world.get_resource::<Messages<TestEvent>>().is_some();
583
assert!(has_events, "Should have the events resource");
584
585
MessageRegistry::deregister_messages::<TestEvent>(&mut world);
586
587
let has_events = world.get_resource::<Messages<TestEvent>>().is_some();
588
assert!(!has_events, "Should not have the events resource");
589
}
590
591
#[test]
592
fn test_events_update_drain() {
593
let mut events = Messages::<TestEvent>::default();
594
let mut reader = events.get_cursor();
595
596
events.write(TestEvent { i: 0 });
597
events.write(TestEvent { i: 1 });
598
assert_eq!(reader.read(&events).count(), 2);
599
600
let mut old_events = Vec::from_iter(events.update_drain());
601
assert!(old_events.is_empty());
602
603
events.write(TestEvent { i: 2 });
604
assert_eq!(reader.read(&events).count(), 1);
605
606
old_events.extend(events.update_drain());
607
assert_eq!(old_events.len(), 2);
608
609
old_events.extend(events.update_drain());
610
assert_eq!(
611
old_events,
612
&[TestEvent { i: 0 }, TestEvent { i: 1 }, TestEvent { i: 2 }]
613
);
614
}
615
616
#[test]
617
fn test_events_empty() {
618
let mut events = Messages::<TestEvent>::default();
619
assert!(events.is_empty());
620
621
events.write(TestEvent { i: 0 });
622
assert!(!events.is_empty());
623
624
events.update();
625
assert!(!events.is_empty());
626
627
// events are only empty after the second call to update
628
// due to double buffering.
629
events.update();
630
assert!(events.is_empty());
631
}
632
633
#[test]
634
fn test_events_extend_impl() {
635
let mut events = Messages::<TestEvent>::default();
636
let mut reader = events.get_cursor();
637
638
events.extend(vec![TestEvent { i: 0 }, TestEvent { i: 1 }]);
639
assert!(reader
640
.read(&events)
641
.eq([TestEvent { i: 0 }, TestEvent { i: 1 }].iter()));
642
}
643
644
// Cursor
645
#[test]
646
fn test_event_cursor_read() {
647
let mut events = Messages::<TestEvent>::default();
648
let mut cursor = events.get_cursor();
649
assert!(cursor.read(&events).next().is_none());
650
651
events.write(TestEvent { i: 0 });
652
let sent_event = cursor.read(&events).next().unwrap();
653
assert_eq!(sent_event, &TestEvent { i: 0 });
654
assert!(cursor.read(&events).next().is_none());
655
656
events.write(TestEvent { i: 2 });
657
let sent_event = cursor.read(&events).next().unwrap();
658
assert_eq!(sent_event, &TestEvent { i: 2 });
659
assert!(cursor.read(&events).next().is_none());
660
661
events.clear();
662
assert!(cursor.read(&events).next().is_none());
663
}
664
665
#[test]
666
fn test_event_cursor_read_mut() {
667
let mut events = Messages::<TestEvent>::default();
668
let mut write_cursor = events.get_cursor();
669
let mut read_cursor = events.get_cursor();
670
assert!(write_cursor.read_mut(&mut events).next().is_none());
671
assert!(read_cursor.read(&events).next().is_none());
672
673
events.write(TestEvent { i: 0 });
674
let sent_event = write_cursor.read_mut(&mut events).next().unwrap();
675
assert_eq!(sent_event, &mut TestEvent { i: 0 });
676
*sent_event = TestEvent { i: 1 }; // Mutate whole event
677
assert_eq!(
678
read_cursor.read(&events).next().unwrap(),
679
&TestEvent { i: 1 }
680
);
681
assert!(read_cursor.read(&events).next().is_none());
682
683
events.write(TestEvent { i: 2 });
684
let sent_event = write_cursor.read_mut(&mut events).next().unwrap();
685
assert_eq!(sent_event, &mut TestEvent { i: 2 });
686
sent_event.i = 3; // Mutate sub value
687
assert_eq!(
688
read_cursor.read(&events).next().unwrap(),
689
&TestEvent { i: 3 }
690
);
691
assert!(read_cursor.read(&events).next().is_none());
692
693
events.clear();
694
assert!(write_cursor.read(&events).next().is_none());
695
assert!(read_cursor.read(&events).next().is_none());
696
}
697
698
#[test]
699
fn test_event_cursor_clear() {
700
let mut events = Messages::<TestEvent>::default();
701
let mut reader = events.get_cursor();
702
703
events.write(TestEvent { i: 0 });
704
assert_eq!(reader.len(&events), 1);
705
reader.clear(&events);
706
assert_eq!(reader.len(&events), 0);
707
}
708
709
#[test]
710
fn test_event_cursor_len_update() {
711
let mut events = Messages::<TestEvent>::default();
712
events.write(TestEvent { i: 0 });
713
events.write(TestEvent { i: 0 });
714
let reader = events.get_cursor();
715
assert_eq!(reader.len(&events), 2);
716
events.update();
717
events.write(TestEvent { i: 0 });
718
assert_eq!(reader.len(&events), 3);
719
events.update();
720
assert_eq!(reader.len(&events), 1);
721
events.update();
722
assert!(reader.is_empty(&events));
723
}
724
725
#[test]
726
fn test_event_cursor_len_current() {
727
let mut events = Messages::<TestEvent>::default();
728
events.write(TestEvent { i: 0 });
729
let reader = events.get_cursor_current();
730
assert!(reader.is_empty(&events));
731
events.write(TestEvent { i: 0 });
732
assert_eq!(reader.len(&events), 1);
733
assert!(!reader.is_empty(&events));
734
}
735
736
#[test]
737
fn test_event_cursor_iter_len_updated() {
738
let mut events = Messages::<TestEvent>::default();
739
events.write(TestEvent { i: 0 });
740
events.write(TestEvent { i: 1 });
741
events.write(TestEvent { i: 2 });
742
let mut reader = events.get_cursor();
743
let mut iter = reader.read(&events);
744
assert_eq!(iter.len(), 3);
745
iter.next();
746
assert_eq!(iter.len(), 2);
747
iter.next();
748
assert_eq!(iter.len(), 1);
749
iter.next();
750
assert_eq!(iter.len(), 0);
751
}
752
753
#[test]
754
fn test_event_cursor_len_empty() {
755
let events = Messages::<TestEvent>::default();
756
assert_eq!(events.get_cursor().len(&events), 0);
757
assert!(events.get_cursor().is_empty(&events));
758
}
759
760
#[test]
761
fn test_event_cursor_len_filled() {
762
let mut events = Messages::<TestEvent>::default();
763
events.write(TestEvent { i: 0 });
764
assert_eq!(events.get_cursor().len(&events), 1);
765
assert!(!events.get_cursor().is_empty(&events));
766
}
767
768
#[cfg(feature = "multi_threaded")]
769
#[test]
770
fn test_event_cursor_par_read() {
771
use crate::prelude::*;
772
use core::sync::atomic::{AtomicUsize, Ordering};
773
774
#[derive(Resource)]
775
struct Counter(AtomicUsize);
776
777
let mut world = World::new();
778
world.init_resource::<Messages<TestEvent>>();
779
for _ in 0..100 {
780
world.write_message(TestEvent { i: 1 });
781
}
782
783
let mut schedule = Schedule::default();
784
785
schedule.add_systems(
786
|mut cursor: Local<MessageCursor<TestEvent>>,
787
events: Res<Messages<TestEvent>>,
788
counter: ResMut<Counter>| {
789
cursor.par_read(&events).for_each(|event| {
790
counter.0.fetch_add(event.i, Ordering::Relaxed);
791
});
792
},
793
);
794
795
world.insert_resource(Counter(AtomicUsize::new(0)));
796
schedule.run(&mut world);
797
let counter = world.remove_resource::<Counter>().unwrap();
798
assert_eq!(counter.0.into_inner(), 100);
799
800
world.insert_resource(Counter(AtomicUsize::new(0)));
801
schedule.run(&mut world);
802
let counter = world.remove_resource::<Counter>().unwrap();
803
assert_eq!(
804
counter.0.into_inner(),
805
0,
806
"par_read should have consumed events but didn't"
807
);
808
}
809
810
#[cfg(feature = "multi_threaded")]
811
#[test]
812
fn test_event_cursor_par_read_mut() {
813
use crate::prelude::*;
814
use core::sync::atomic::{AtomicUsize, Ordering};
815
816
#[derive(Resource)]
817
struct Counter(AtomicUsize);
818
819
let mut world = World::new();
820
world.init_resource::<Messages<TestEvent>>();
821
for _ in 0..100 {
822
world.write_message(TestEvent { i: 1 });
823
}
824
let mut schedule = Schedule::default();
825
schedule.add_systems(
826
|mut cursor: Local<MessageCursor<TestEvent>>,
827
mut events: ResMut<Messages<TestEvent>>,
828
counter: ResMut<Counter>| {
829
cursor.par_read_mut(&mut events).for_each(|event| {
830
event.i += 1;
831
counter.0.fetch_add(event.i, Ordering::Relaxed);
832
});
833
},
834
);
835
world.insert_resource(Counter(AtomicUsize::new(0)));
836
schedule.run(&mut world);
837
let counter = world.remove_resource::<Counter>().unwrap();
838
assert_eq!(counter.0.into_inner(), 200, "Initial run failed");
839
840
world.insert_resource(Counter(AtomicUsize::new(0)));
841
schedule.run(&mut world);
842
let counter = world.remove_resource::<Counter>().unwrap();
843
assert_eq!(
844
counter.0.into_inner(),
845
0,
846
"par_read_mut should have consumed events but didn't"
847
);
848
}
849
850
// Reader & Mutator
851
#[test]
852
fn ensure_reader_readonly() {
853
fn reader_system(_: MessageReader<EmptyTestEvent>) {}
854
855
assert_is_read_only_system(reader_system);
856
}
857
858
#[test]
859
fn test_event_reader_iter_last() {
860
use bevy_ecs::prelude::*;
861
862
let mut world = World::new();
863
world.init_resource::<Messages<TestEvent>>();
864
865
let mut reader = IntoSystem::into_system(
866
|mut events: MessageReader<TestEvent>| -> Option<TestEvent> {
867
events.read().last().copied()
868
},
869
);
870
reader.initialize(&mut world);
871
872
let last = reader.run((), &mut world).unwrap();
873
assert!(last.is_none(), "MessageReader should be empty");
874
875
world.write_message(TestEvent { i: 0 });
876
let last = reader.run((), &mut world).unwrap();
877
assert_eq!(last, Some(TestEvent { i: 0 }));
878
879
world.write_message(TestEvent { i: 1 });
880
world.write_message(TestEvent { i: 2 });
881
world.write_message(TestEvent { i: 3 });
882
let last = reader.run((), &mut world).unwrap();
883
assert_eq!(last, Some(TestEvent { i: 3 }));
884
885
let last = reader.run((), &mut world).unwrap();
886
assert!(last.is_none(), "MessageReader should be empty");
887
}
888
889
#[test]
890
fn test_event_mutator_iter_last() {
891
use bevy_ecs::prelude::*;
892
893
let mut world = World::new();
894
world.init_resource::<Messages<TestEvent>>();
895
896
let mut mutator = IntoSystem::into_system(
897
|mut events: MessageMutator<TestEvent>| -> Option<TestEvent> {
898
events.read().last().copied()
899
},
900
);
901
mutator.initialize(&mut world);
902
903
let last = mutator.run((), &mut world).unwrap();
904
assert!(last.is_none(), "EventMutator should be empty");
905
906
world.write_message(TestEvent { i: 0 });
907
let last = mutator.run((), &mut world).unwrap();
908
assert_eq!(last, Some(TestEvent { i: 0 }));
909
910
world.write_message(TestEvent { i: 1 });
911
world.write_message(TestEvent { i: 2 });
912
world.write_message(TestEvent { i: 3 });
913
let last = mutator.run((), &mut world).unwrap();
914
assert_eq!(last, Some(TestEvent { i: 3 }));
915
916
let last = mutator.run((), &mut world).unwrap();
917
assert!(last.is_none(), "EventMutator should be empty");
918
}
919
920
#[test]
921
fn test_event_reader_iter_nth() {
922
use bevy_ecs::prelude::*;
923
924
let mut world = World::new();
925
world.init_resource::<Messages<TestEvent>>();
926
927
world.write_message(TestEvent { i: 0 });
928
world.write_message(TestEvent { i: 1 });
929
world.write_message(TestEvent { i: 2 });
930
world.write_message(TestEvent { i: 3 });
931
world.write_message(TestEvent { i: 4 });
932
933
let mut schedule = Schedule::default();
934
schedule.add_systems(|mut events: MessageReader<TestEvent>| {
935
let mut iter = events.read();
936
937
assert_eq!(iter.next(), Some(&TestEvent { i: 0 }));
938
assert_eq!(iter.nth(2), Some(&TestEvent { i: 3 }));
939
assert_eq!(iter.nth(1), None);
940
941
assert!(events.is_empty());
942
});
943
schedule.run(&mut world);
944
}
945
946
#[test]
947
fn test_event_mutator_iter_nth() {
948
use bevy_ecs::prelude::*;
949
950
let mut world = World::new();
951
world.init_resource::<Messages<TestEvent>>();
952
953
world.write_message(TestEvent { i: 0 });
954
world.write_message(TestEvent { i: 1 });
955
world.write_message(TestEvent { i: 2 });
956
world.write_message(TestEvent { i: 3 });
957
world.write_message(TestEvent { i: 4 });
958
959
let mut schedule = Schedule::default();
960
schedule.add_systems(|mut events: MessageReader<TestEvent>| {
961
let mut iter = events.read();
962
963
assert_eq!(iter.next(), Some(&TestEvent { i: 0 }));
964
assert_eq!(iter.nth(2), Some(&TestEvent { i: 3 }));
965
assert_eq!(iter.nth(1), None);
966
967
assert!(events.is_empty());
968
});
969
schedule.run(&mut world);
970
}
971
972
#[test]
973
fn test_derive_entity_event() {
974
use bevy_ecs::prelude::*;
975
976
struct Entitoid(Entity);
977
978
impl ContainsEntity for Entitoid {
979
fn entity(&self) -> Entity {
980
self.0
981
}
982
}
983
984
struct MutableEntitoid(Entity);
985
986
impl ContainsEntity for MutableEntitoid {
987
fn entity(&self) -> Entity {
988
self.0
989
}
990
}
991
992
impl From<Entity> for MutableEntitoid {
993
fn from(value: Entity) -> Self {
994
Self(value)
995
}
996
}
997
998
#[derive(EntityEvent)]
999
struct A(Entity);
1000
1001
#[derive(EntityEvent)]
1002
#[entity_event(propagate)]
1003
struct AP(Entity);
1004
1005
#[derive(EntityEvent)]
1006
struct B {
1007
entity: Entity,
1008
}
1009
1010
#[derive(EntityEvent)]
1011
#[entity_event(propagate)]
1012
struct BP {
1013
entity: Entity,
1014
}
1015
1016
#[derive(EntityEvent)]
1017
struct C {
1018
#[event_target]
1019
target: Entity,
1020
}
1021
1022
#[derive(EntityEvent)]
1023
#[entity_event(propagate)]
1024
struct CP {
1025
#[event_target]
1026
target: Entity,
1027
}
1028
1029
#[derive(EntityEvent)]
1030
struct D(Entitoid);
1031
1032
// SHOULD NOT COMPILE:
1033
// #[derive(EntityEvent)]
1034
// #[entity_event(propagate)]
1035
// struct DP(Entitoid);
1036
1037
#[derive(EntityEvent)]
1038
struct E {
1039
entity: Entitoid,
1040
}
1041
1042
// SHOULD NOT COMPILE:
1043
// #[derive(EntityEvent)]
1044
// #[entity_event(propagate)]
1045
// struct EP {
1046
// entity: Entitoid,
1047
// }
1048
1049
#[derive(EntityEvent)]
1050
struct F {
1051
#[event_target]
1052
target: Entitoid,
1053
}
1054
1055
// SHOULD NOT COMPILE:
1056
// #[derive(EntityEvent)]
1057
// #[entity_event(propagate)]
1058
// struct FP {
1059
// #[event_target]
1060
// target: Entitoid,
1061
// }
1062
1063
#[derive(EntityEvent)]
1064
#[entity_event(propagate)]
1065
struct G(MutableEntitoid);
1066
1067
impl From<Entity> for G {
1068
fn from(value: Entity) -> Self {
1069
Self(value.into())
1070
}
1071
}
1072
1073
let mut world = World::new();
1074
let entity = world.spawn_empty().id();
1075
1076
world.entity_mut(entity).trigger(A);
1077
world.entity_mut(entity).trigger(AP);
1078
world.trigger(B { entity });
1079
world.trigger(BP { entity });
1080
world.trigger(C { target: entity });
1081
world.trigger(CP { target: entity });
1082
world.trigger(D(Entitoid(entity)));
1083
world.trigger(E {
1084
entity: Entitoid(entity),
1085
});
1086
world.trigger(F {
1087
target: Entitoid(entity),
1088
});
1089
world.trigger(G(MutableEntitoid(entity)));
1090
world.entity_mut(entity).trigger(G::from);
1091
1092
// No asserts; test just needs to compile
1093
}
1094
}
1095
1096