diff --git a/crates/bevy_app/src/app.rs b/crates/bevy_app/src/app.rs index 6dc3ef9bcf9c2..adf7bcf239a9c 100644 --- a/crates/bevy_app/src/app.rs +++ b/crates/bevy_app/src/app.rs @@ -915,5 +915,5 @@ fn run_once(mut app: App) { } /// An event that indicates the app should exit. This will fully exit the app process. -#[derive(Debug, Clone)] +#[derive(Debug, Clone, Default)] pub struct AppExit; diff --git a/crates/bevy_ecs/src/event.rs b/crates/bevy_ecs/src/event.rs index a7e5d1b319c34..1b78f2229f9bc 100644 --- a/crates/bevy_ecs/src/event.rs +++ b/crates/bevy_ecs/src/event.rs @@ -122,6 +122,10 @@ enum State { /// This complicates consumption and risks ever-expanding memory usage if not cleaned up, /// but can be done by adding your event as a resource instead of using /// [`add_event`](https://docs.rs/bevy/*/bevy/app/struct.App.html#method.add_event). +/// +/// [Example usage.](https://github.com/bevyengine/bevy/blob/latest/examples/ecs/event.rs) +/// [Example usage standalone.](https://github.com/bevyengine/bevy/blob/latest/bevy_ecs/examples/events.rs) +/// #[derive(Debug)] pub struct Events { events_a: Vec>, @@ -169,6 +173,8 @@ pub struct EventWriter<'w, 's, T: Resource> { } impl<'w, 's, T: Resource> EventWriter<'w, 's, T> { + /// Sends an `event`. [`EventReader`]s can then read the event. + /// See [`Events`] for details. pub fn send(&mut self, event: T) { self.events.send(event); } @@ -176,6 +182,14 @@ impl<'w, 's, T: Resource> EventWriter<'w, 's, T> { pub fn send_batch(&mut self, events: impl Iterator) { self.events.extend(events); } + + /// Sends the default value of the event. Useful when the event is an empty struct. + pub fn send_default(&mut self) + where + T: Default, + { + self.events.send_default(); + } } pub struct ManualEventReader { @@ -296,6 +310,14 @@ impl Events { self.event_count += 1; } + /// Sends the default value of the event. Useful when the event is an empty struct. + pub fn send_default(&mut self) + where + T: Default, + { + self.send(Default::default()); + } + /// Gets a new [`ManualEventReader`]. This will include all events already in the event buffers. pub fn get_reader(&self) -> ManualEventReader { ManualEventReader { @@ -540,11 +562,11 @@ mod tests { ); } - fn get_events( - events: &Events, - reader: &mut ManualEventReader, - ) -> Vec { - reader.iter(events).cloned().collect::>() + fn get_events( + events: &Events, + reader: &mut ManualEventReader, + ) -> Vec { + reader.iter(events).cloned().collect::>() } #[derive(PartialEq, Eq, Debug)] @@ -652,4 +674,19 @@ mod tests { events.update(); assert!(reader.is_empty(&events)); } + + #[derive(Clone, PartialEq, Debug, Default)] + struct EmptyTestEvent; + + #[test] + fn test_firing_empty_event() { + let mut events = Events::::default(); + events.send_default(); + + let mut reader = events.get_reader(); + assert_eq!( + get_events(&events, &mut reader), + vec![EmptyTestEvent::default()] + ); + } } diff --git a/crates/bevy_input/src/system.rs b/crates/bevy_input/src/system.rs index a5270eb83f7c7..018c47794b4e1 100644 --- a/crates/bevy_input/src/system.rs +++ b/crates/bevy_input/src/system.rs @@ -13,7 +13,7 @@ pub fn exit_on_esc_system( for event in keyboard_input_events.iter() { if let Some(key_code) = event.key_code { if event.state == ElementState::Pressed && key_code == KeyCode::Escape { - app_exit_events.send(AppExit); + app_exit_events.send_default(); } } } diff --git a/examples/ecs/event.rs b/examples/ecs/event.rs index cc913f45f2bb7..bb04b14004529 100644 --- a/examples/ecs/event.rs +++ b/examples/ecs/event.rs @@ -6,9 +6,11 @@ fn main() { App::new() .add_plugins(DefaultPlugins) .add_event::() + .add_event::() .init_resource::() - .add_system(event_trigger_system) - .add_system(event_listener_system) + .add_system(event_trigger) + .add_system(event_listener) + .add_system(sound_player) .run(); } @@ -16,6 +18,9 @@ struct MyEvent { pub message: String, } +#[derive(Default)] +struct PlaySound; + struct EventTriggerState { event_timer: Timer, } @@ -28,22 +33,30 @@ impl Default for EventTriggerState { } } -// sends MyEvent every second -fn event_trigger_system( +// sends MyEvent and PlaySound every second +fn event_trigger( time: Res