Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Only run event systems if they have tangible work to do #7728

Merged
merged 11 commits into from
Sep 24, 2023
11 changes: 8 additions & 3 deletions crates/bevy_app/src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -424,7 +424,7 @@ impl App {
/// Setup the application to manage events of type `T`.
///
/// This is done by adding a [`Resource`] of type [`Events::<T>`],
/// and inserting an [`update_system`](Events::update_system) into [`First`].
/// and inserting an [`event_update_system`] into [`First`].
///
/// See [`Events`] for defining events.
///
Expand All @@ -440,13 +440,18 @@ impl App {
/// #
/// app.add_event::<MyEvent>();
/// ```
///
/// [`event_update_system`]: bevy_ecs::event::event_update_system
pub fn add_event<T>(&mut self) -> &mut Self
where
T: Event,
{
if !self.world.contains_resource::<Events<T>>() {
self.init_resource::<Events<T>>()
.add_systems(First, Events::<T>::update_system);
self.init_resource::<Events<T>>().add_systems(
First,
bevy_ecs::event::event_update_system::<T>
.run_if(bevy_ecs::event::event_update_condition::<T>),
);
}
self
}
Expand Down
2 changes: 1 addition & 1 deletion crates/bevy_ecs/examples/events.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ fn main() {
#[derive(SystemSet, Debug, Clone, PartialEq, Eq, Hash)]
pub struct FlushEvents;

schedule.add_systems(Events::<MyEvent>::update_system.in_set(FlushEvents));
schedule.add_systems(bevy_ecs::event::event_update_system::<MyEvent>.in_set(FlushEvents));

// Add systems sending and receiving events after the events are flushed.
schedule.add_systems((
Expand Down
18 changes: 12 additions & 6 deletions crates/bevy_ecs/src/event.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ struct EventInstance<E: Event> {
/// This collection is meant to be paired with a system that calls
/// [`Events::update`] exactly once per update/frame.
///
/// [`Events::update_system`] is a system that does this, typically initialized automatically using
/// [`event_update_system`] is a system that does this, typically initialized automatically using
/// [`add_event`](https://docs.rs/bevy/*/bevy/app/struct.App.html#method.add_event).
/// [`EventReader`]s are expected to read events from this collection at least once per loop/frame.
/// Events will persist across a single frame boundary and so ordering of event producers and
Expand Down Expand Up @@ -251,11 +251,6 @@ impl<E: Event> Events<E> {
iter.map(|e| e.event)
}

/// A system that calls [`Events::update`] once per frame.
pub fn update_system(mut events: ResMut<Self>) {
events.update();
}

#[inline]
fn reset_start_event_count(&mut self) {
self.events_a.start_event_count = self.event_count;
Expand Down Expand Up @@ -754,6 +749,17 @@ impl<'a, E: Event> ExactSizeIterator for EventIteratorWithId<'a, E> {
}
}

/// A system that calls [`Events::update`] once per frame.
pub fn event_update_system<T: Event>(mut events: ResMut<Events<T>>) {
events.update();
}

/// A run condition that checks if the event's [`event_update_system`]
/// needs to run or not.
pub fn event_update_condition<T: Event>(events: Res<Events<T>>) -> bool {
!events.events_a.is_empty() || !events.events_b.is_empty()
}

#[cfg(test)]
mod tests {
use crate::system::assert_is_read_only_system;
Expand Down
2 changes: 1 addition & 1 deletion crates/bevy_ecs/src/schedule/condition.rs
Original file line number Diff line number Diff line change
Expand Up @@ -867,7 +867,7 @@ pub mod common_conditions {
/// # let mut world = World::new();
/// # world.init_resource::<Counter>();
/// # world.init_resource::<Events<MyEvent>>();
/// # app.add_systems(Events::<MyEvent>::update_system.before(my_system));
/// # app.add_systems(bevy_ecs::event::event_update_system::<MyEvent>.before(my_system));
///
/// app.add_systems(
/// my_system.run_if(on_event::<MyEvent>()),
Expand Down