mirror of
https://github.com/bevyengine/bevy
synced 2024-11-25 22:20:20 +00:00
Simplify sending empty events (#2935)
# Objective When using empty events, it can feel redundant to have to specify the type of the event when sending it. ## Solution Add a new `fire()` function that sends the default value of the event. This requires that the event derives Default. Co-authored-by: Carter Anderson <mcanders1@gmail.com>
This commit is contained in:
parent
6f111136b9
commit
7d712406fe
4 changed files with 62 additions and 12 deletions
|
@ -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;
|
||||
|
|
|
@ -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<T> {
|
||||
events_a: Vec<EventInstance<T>>,
|
||||
|
@ -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<Item = T>) {
|
||||
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<T> {
|
||||
|
@ -296,6 +310,14 @@ impl<T: Resource> Events<T> {
|
|||
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<T> {
|
||||
ManualEventReader {
|
||||
|
@ -540,11 +562,11 @@ mod tests {
|
|||
);
|
||||
}
|
||||
|
||||
fn get_events(
|
||||
events: &Events<TestEvent>,
|
||||
reader: &mut ManualEventReader<TestEvent>,
|
||||
) -> Vec<TestEvent> {
|
||||
reader.iter(events).cloned().collect::<Vec<TestEvent>>()
|
||||
fn get_events<T: Resource + Clone>(
|
||||
events: &Events<T>,
|
||||
reader: &mut ManualEventReader<T>,
|
||||
) -> Vec<T> {
|
||||
reader.iter(events).cloned().collect::<Vec<T>>()
|
||||
}
|
||||
|
||||
#[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::<EmptyTestEvent>::default();
|
||||
events.send_default();
|
||||
|
||||
let mut reader = events.get_reader();
|
||||
assert_eq!(
|
||||
get_events(&events, &mut reader),
|
||||
vec![EmptyTestEvent::default()]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,9 +6,11 @@ fn main() {
|
|||
App::new()
|
||||
.add_plugins(DefaultPlugins)
|
||||
.add_event::<MyEvent>()
|
||||
.add_event::<PlaySound>()
|
||||
.init_resource::<EventTriggerState>()
|
||||
.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<Time>,
|
||||
mut state: ResMut<EventTriggerState>,
|
||||
mut my_events: EventWriter<MyEvent>,
|
||||
mut play_sound_events: EventWriter<PlaySound>,
|
||||
) {
|
||||
if state.event_timer.tick(time.delta()).finished() {
|
||||
my_events.send(MyEvent {
|
||||
message: "MyEvent just happened!".to_string(),
|
||||
});
|
||||
play_sound_events.send_default();
|
||||
}
|
||||
}
|
||||
|
||||
// prints events as they come in
|
||||
fn event_listener_system(mut events: EventReader<MyEvent>) {
|
||||
fn event_listener(mut events: EventReader<MyEvent>) {
|
||||
for my_event in events.iter() {
|
||||
info!("{}", my_event.message);
|
||||
}
|
||||
}
|
||||
|
||||
fn sound_player(mut play_sound_events: EventReader<PlaySound>) {
|
||||
for _ in play_sound_events.iter() {
|
||||
info!("Playing a sound");
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue