Skip to content

Commit 88052f3

Browse files
Added EventConsumer example
1 parent a4fa818 commit 88052f3

File tree

1 file changed

+57
-8
lines changed

1 file changed

+57
-8
lines changed

examples/ecs/per_entity_events.rs

Lines changed: 57 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
1-
use bevy::app::{Events, ManualEventReader};
21
use bevy::prelude::*;
2+
use bevy::{
3+
app::{Events, ManualEventReader},
4+
core::FixedTimestep,
5+
};
36

47
/// In this example, we show how to store events of a given type
58
/// as a component on individual entities rather than in a single resource.
@@ -39,6 +42,11 @@ fn main() {
3942
.add_system(add_number.system().label("action_handling"))
4043
.add_system(scale_selected.system().after("action_handling"))
4144
.add_system(update_text_color.system().after("action_handling"))
45+
.add_system(
46+
move_text
47+
.system()
48+
.with_run_criteria(FixedTimestep::step(TIME_STEP)),
49+
)
4250
.run()
4351
}
4452

@@ -55,6 +63,7 @@ struct InteractableBundle {
5563
selectable: Selectable,
5664
rainbow: ColorChoices,
5765
cycle_color_events: Events<CycleColorAction>,
66+
move_events: Events<MoveAction>,
5867
add_number_events: Events<AddNumberAction>,
5968
}
6069

@@ -81,6 +90,7 @@ impl InteractableBundle {
8190
selectable: Selectable,
8291
rainbow: ColorChoices::Red,
8392
cycle_color_events: Events::<CycleColorAction>::default(),
93+
move_events: Events<MoveAction>::default(),
8494
add_number_events: Events::<AddNumberAction>::default(),
8595
}
8696
}
@@ -201,7 +211,11 @@ fn input_dispatch(
201211
// You could also access the &Events<T> component directly
202212
// then send events to that component with `Events::send`
203213
mut query: Query<
204-
(EventWriter<CycleColorAction>, EventWriter<AddNumberAction>),
214+
(
215+
EventWriter<CycleColorAction>,
216+
EventWriter<MoveAction>,
217+
EventWriter<AddNumberAction>,
218+
),
205219
With<Selectable>,
206220
>,
207221
selected: Res<Selected>,
@@ -211,13 +225,27 @@ fn input_dispatch(
211225

212226
let (mut cycle_actions, mut add_actions) = query.get_mut(selected.entity).unwrap();
213227

214-
// Inputs for cycling colors
215-
if keyboard_input.just_pressed(Space) {
216-
cycle_actions.send(CycleColorAction);
217-
}
218-
219-
// Inputs for sending numbers to be added
220228
for key_code in keyboard_input.get_just_pressed() {
229+
match key_code {
230+
// Color changing
231+
Space => cycle_actions.send(CycleColorAction),
232+
// Movement
233+
Left => move_actions.send(MoveAction {
234+
transform: Transform::from_xyz(-MOVE_DISTANCE, 0.0, 0.0),
235+
}),
236+
Right => move_actions.send(MoveAction {
237+
transform: Transform::from_xyz(MOVE_DISTANCE, 0.0, 0.0),
238+
}),
239+
Down => move_actions.send(MoveAction {
240+
transform: Transform::from_xyz(0.0, -MOVE_DISTANCE, 0.0),
241+
}),
242+
Up => move_actions.send(MoveAction {
243+
transform: Transform::from_xyz(0.0, MOVE_DISTANCE, 0.0),
244+
}),
245+
_ => (),
246+
}
247+
248+
// Inputs for sending numbers to be added
221249
if (key_code as u8) < 10 {
222250
add_actions.send(AddNumberAction {
223251
// The keycode for KeyCode::Key1 is 0
@@ -265,3 +293,24 @@ fn add_number(
265293
text.sections[0].value = new_number.to_string();
266294
}
267295
}
296+
297+
const MOVE_DISTANCE: f32 = 100.0;
298+
const TIME_STEP: f32 = 2;
299+
#[derive(Default)]
300+
struct MoveAction {
301+
transform: Transform,
302+
}
303+
304+
// When events are registered in the AppBuilder using .add_event(),
305+
// a system will automatically be created to clean them up after two frames.
306+
// This can be problematic if your event-consuming systems ever skip frames (such as due to a fixed timestep run criteria).
307+
// We can get around this by not registering them, and instead handling clean-up by consuming them when read.
308+
// Be careful though: once consumed, other systems will not be able to read them!
309+
fn move_text(query: Query<(&mut Transform, EventConsumer<MoveAction>)>) {
310+
for (mut transform, events) in query.iter() {
311+
// Unlike EventReaders which simply iterate, EventConsumers drain the events they read
312+
for move_action in events.drain() {
313+
*transform += move_action.transform * TIME_STEP;
314+
}
315+
}
316+
}

0 commit comments

Comments
 (0)