From 9481a2c8a713bdd1cace3dc7442807b7eb2d7dce Mon Sep 17 00:00:00 2001 From: ira Date: Fri, 3 Feb 2023 01:03:56 +0000 Subject: [PATCH] Optimise `EventReader::clear()` and improve documentation (#7471) # Objective Clearing the reader doesn't require iterating the events. Updating the `last_event_count` of the reader is enough. I rewrote part of the documentation as some of it was incorrect or harder to understand than necessary. ## Changelog Added `ManualEventReader::clear()` Co-authored-by: devil-ira --- crates/bevy_ecs/src/event.rs | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/crates/bevy_ecs/src/event.rs b/crates/bevy_ecs/src/event.rs index 2b641bf482..3c0b278e00 100644 --- a/crates/bevy_ecs/src/event.rs +++ b/crates/bevy_ecs/src/event.rs @@ -207,17 +207,15 @@ impl<'w, 's, E: Event> EventReader<'w, 's, E> { self.reader.len(&self.events) } - /// Determines if no events are available to be read without consuming any. - /// If you need to consume the iterator you can use [`EventReader::clear`]. + /// Returns `true` if there are no events available to read. /// /// # Example /// - /// The following example shows a common pattern of this function in conjunction with `clear` - /// to avoid leaking events to the next schedule iteration while also checking if it was emitted. + /// The following example shows a useful pattern where some behaviour is triggered if new events are available. + /// [`EventReader::clear()`] is used so the same events don't re-trigger the behaviour the next time the system runs. /// /// ``` /// # use bevy_ecs::prelude::*; - /// # /// struct CollisionEvent; /// /// fn play_collision_sound(mut events: EventReader) { @@ -229,19 +227,17 @@ impl<'w, 's, E: Event> EventReader<'w, 's, E> { /// # bevy_ecs::system::assert_is_system(play_collision_sound); /// ``` pub fn is_empty(&self) -> bool { - self.len() == 0 + self.reader.is_empty(&self.events) } - /// Consumes the iterator. + /// Consumes all available events. /// - /// This means all currently available events will be removed before the next frame. - /// This is useful when multiple events are sent in a single frame and you want - /// to react to one or more events without needing to know how many were sent. - /// In those situations you generally want to consume those events to make sure they don't appear in the next frame. + /// This means these events will not appear in calls to [`EventReader::iter()`] or + /// [`EventReader::iter_with_id()`] and [`EventReader::is_empty()`] will return `true`. /// - /// For more information see [`EventReader::is_empty()`]. + /// For usage, see [`EventReader::is_empty()`]. pub fn clear(&mut self) { - self.iter().last(); + self.reader.clear(&self.events); } } @@ -362,10 +358,15 @@ impl ManualEventReader { .saturating_sub(self.last_event_count) } - /// See [`EventReader::is_empty`] + /// See [`EventReader::is_empty()`] pub fn is_empty(&self, events: &Events) -> bool { self.len(events) == 0 } + + /// See [`EventReader::clear()`] + pub fn clear(&mut self, events: &Events) { + self.last_event_count = events.event_count; + } } pub struct ManualEventIterator<'a, E: Event> {