Skip to content

Commit 1da3c34

Browse files
Add event_consumer example
1 parent 51b6195 commit 1da3c34

File tree

4 files changed

+71
-1
lines changed

4 files changed

+71
-1
lines changed

Cargo.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -259,6 +259,10 @@ path = "examples/ecs/change_detection.rs"
259259
name = "event"
260260
path = "examples/ecs/event.rs"
261261

262+
[[example]]
263+
name = "event_consumer"
264+
path = "examples/ecs/event_consumer.rs"
265+
262266
[[example]]
263267
name = "fixed_timestep"
264268
path = "examples/ecs/fixed_timestep.rs"

crates/bevy_ecs/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ pub mod prelude {
1919
pub use crate::{
2020
bundle::Bundle,
2121
entity::Entity,
22-
event::{EventReader, EventWriter},
22+
event::{EventConsumer, EventReader, EventWriter},
2323
query::{Added, ChangeTrackers, Changed, Or, QueryState, With, WithBundle, Without},
2424
schedule::{
2525
AmbiguitySetLabel, ExclusiveSystemDescriptorCoercion, ParallelSystemDescriptorCoercion,

examples/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,7 @@ Example | File | Description
151151
`ecs_guide` | [`ecs/ecs_guide.rs`](./ecs/ecs_guide.rs) | Full guide to Bevy's ECS
152152
`change_detection` | [`ecs/change_detection.rs`](./ecs/change_detection.rs) | Change detection on components
153153
`event` | [`ecs/event.rs`](./ecs/event.rs) | Illustrates event creation, activation, and reception
154+
`event_consumer` | [`ecs/event_consumer.rs`](./ecs/event_consumer.rs) | Shows how to consume events and avoid automatic event cleanup when skipping systems
154155
`fixed_timestep` | [`ecs/fixed_timestep.rs`](./ecs/fixed_timestep.rs) | Shows how to create systems that run every fixed timestep, rather than every tick
155156
`hierarchy` | [`ecs/hierarchy.rs`](./ecs/hierarchy.rs) | Creates a hierarchy of parents and children entities
156157
`parallel_query` | [`ecs/parallel_query.rs`](./ecs/parallel_query.rs) | Illustrates parallel queries with `ParallelIterator`

examples/ecs/event_consumer.rs

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
use bevy::core::FixedTimestep;
2+
use bevy::prelude::*;
3+
4+
/// Events are automatically cleaned up after two frames when intialized via `.add_event`.
5+
/// To bypass this, you can simply add the Events::<T> resource manually.
6+
/// This is critical when working with systems that read events but do not run every tick,
7+
/// such as those that operate with a FixedTimeStep run criteria.
8+
///
9+
/// When you do so though, you need to be careful to clean up these events eventually,
10+
/// otherwise the size of your vector of events will grow in an unbounded fashion.
11+
///
12+
/// `EventConsumer::<T>` provides a simple interface to do so, clearing all events that it reads
13+
/// by draining them into a new vector.
14+
/// You can combine it with other `EventReader`s as long as they read events before ,
15+
/// but only one `EventConsumer` system should be used per event type in most cases
16+
/// as they will compete for events.
17+
fn main() {
18+
App::build()
19+
.add_plugins(DefaultPlugins)
20+
.add_event::<MyEvent>()
21+
.add_system(
22+
event_trigger_system
23+
.system()
24+
.with_run_criteria(FixedTimestep::step(1.0)),
25+
)
26+
.add_system(event_listener_system.system().label("listening"))
27+
.add_system(
28+
event_devourer_system
29+
.system()
30+
// Must occur after event_listener_system or some events may be missed
31+
.after("listening")
32+
.with_run_criteria(FixedTimestep::step(5.0)),
33+
)
34+
.run();
35+
}
36+
37+
struct MyEvent {
38+
pub message: String,
39+
}
40+
41+
// sends MyEvent every second
42+
fn event_trigger_system(time: Res<Time>, mut my_events: EventWriter<MyEvent>) {
43+
my_events.send(MyEvent {
44+
message: format!(
45+
"This event was sent at {}",
46+
time.time_since_startup().as_millis()
47+
)
48+
.to_string(),
49+
});
50+
}
51+
52+
// reads events as soon as they come in
53+
fn event_listener_system(mut events: EventReader<MyEvent>) {
54+
for _ in events.iter() {
55+
info!("I heard an event!");
56+
}
57+
}
58+
59+
// reports events once every 5 seconds
60+
fn event_devourer_system(events: EventConsumer<MyEvent>) {
61+
// Events are only consumed when .drain() is called
62+
for my_event in events.drain() {
63+
info!("{}", my_event.message);
64+
}
65+
}

0 commit comments

Comments
 (0)