1
- use bevy:: app:: Events ;
1
+ use bevy:: app:: { Events , ManualEventReader } ;
2
2
use bevy:: prelude:: * ;
3
3
4
4
/// In this example, we show how to store events of a given type
@@ -212,12 +212,14 @@ fn scale_selected(
212
212
/// Note that we can store several events at once!
213
213
/// Try pressing both "1" and "3" to add 4 to the selected display
214
214
fn input_dispatch (
215
+ // You could also access the &Events<T> component directly
216
+ // then send events to that component with `Events::send`
215
217
mut query : Query <
216
218
( & mut Events < CycleColorAction > , & mut Events < AddNumberAction > ) ,
217
219
With < Selectable > ,
218
220
> ,
219
221
selected : Res < Selected > ,
220
- mut keyboard_input : ResMut < Input < KeyCode > > ,
222
+ keyboard_input : ResMut < Input < KeyCode > > ,
221
223
) {
222
224
let ( mut cycle_actions, mut add_actions) = query. get_mut ( selected. entity ) . unwrap ( ) ;
223
225
@@ -256,7 +258,7 @@ fn input_dispatch(
256
258
}
257
259
}
258
260
259
- // FIXME: make this work using `EventReader<T>` syntax and specialized behavior
261
+ // FIXME: make this work without duplication using `EventReader<T>` syntax and specialized behavior
260
262
fn cycle_color ( mut query : Query < ( & mut Rainbow , & mut Events < CycleColorAction > ) > ) {
261
263
for ( mut rainbow, action_queue) in query. iter_mut ( ) {
262
264
let mut reader = action_queue. get_reader ( ) ;
@@ -274,16 +276,25 @@ fn update_text_color(mut query: Query<(&mut Text, &Rainbow), Changed<Rainbow>>)
274
276
275
277
// Just as when using Events as a resource, you can work with `Events<T>` directly instead
276
278
// EventReader and EventWriter are just convenient wrappers that better communicate intent
277
- // FIXME: Prevent event duplication by storing a Local resource
278
- fn add_number ( mut query : Query < ( & mut Text , & Events < AddNumberAction > ) > ) {
279
- // To add events manually, use events.send(MyEvent::new())
280
- for ( mut text, action_queue) in query. iter_mut ( ) {
281
- let mut reader = action_queue. get_reader ( ) ;
282
- for action in reader. iter ( & action_queue) {
283
- let current_number: u8 = text. sections [ 0 ] . value . clone ( ) . parse ( ) . unwrap ( ) ;
284
- // Wrap addition, rather than overflowing
285
- let new_number = ( ( current_number + action. number ) as u16 ) % std:: u8:: MAX as u16 ;
286
- text. sections [ 0 ] . value = new_number. to_string ( ) ;
287
- }
279
+ // And store state automatically for you
280
+ fn add_number (
281
+ mut query : Query < ( & mut Text , & Events < AddNumberAction > ) > ,
282
+ mut reader : Local < ManualEventReader < AddNumberAction > > ,
283
+ selected : Res < Selected > ,
284
+ ) {
285
+ let ( mut text, action_queue) = query. get_mut ( selected. entity ) . unwrap ( ) ;
286
+ // Because we only care about one entity at a time, we can store the event reader manually
287
+ // in a Local resource as part of the system's data
288
+ // This logic is handled for you, storing one EventReader per entity when you query for an EventReader
289
+ if selected. is_changed ( ) {
290
+ // If the resource selected is changed, we need to rebuild a new event reader
291
+ * reader = action_queue. get_reader ( ) ;
292
+ }
293
+
294
+ for action in reader. iter ( & action_queue) {
295
+ let current_number: u8 = text. sections [ 0 ] . value . clone ( ) . parse ( ) . unwrap ( ) ;
296
+ // Wrap addition, rather than overflowing
297
+ let new_number = ( ( current_number + action. number ) as u16 ) % std:: u8:: MAX as u16 ;
298
+ text. sections [ 0 ] . value = new_number. to_string ( ) ;
288
299
}
289
300
}
0 commit comments