Skip to content

Commit a4fa818

Browse files
Added EventConsumer
Also added handy drain_with_id method
1 parent b454712 commit a4fa818

File tree

1 file changed

+41
-14
lines changed

1 file changed

+41
-14
lines changed

crates/bevy_ecs/src/event.rs

Lines changed: 41 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -213,20 +213,21 @@ impl<T: Component> Events<T> {
213213
}
214214

215215
/// Creates a draining iterator that removes all events.
216-
pub fn drain(&mut self) -> impl Iterator<Item = T> + '_ {
217-
let map = |i: EventInstance<T>| i.event;
218-
match self.state {
219-
BufferState::A => self
220-
.events_b
221-
.drain(..)
222-
.map(map)
223-
.chain(self.events_a.drain(..).map(map)),
224-
BufferState::B => self
225-
.events_a
226-
.drain(..)
227-
.map(map)
228-
.chain(self.events_b.drain(..).map(map)),
229-
}
216+
pub fn drain(&mut self) -> impl DoubleEndedIterator<Item = T> + '_ {
217+
self.drain_with_id().map(|(e, _)| e)
218+
}
219+
220+
/// Creates a draining iterator that returns both events and their ids
221+
pub fn drain_with_id(&mut self) -> impl DoubleEndedIterator<Item = (T, EventId<T>)> + '_ {
222+
let event_instances = match self.state {
223+
BufferState::A => self.events_b.drain(..).chain(self.events_a.drain(..)),
224+
BufferState::B => self.events_a.drain(..).chain(self.events_b.drain(..)),
225+
};
226+
227+
event_instances.map(|ei| {
228+
trace!("Events::drain_with_id -> {}", ei.event_id);
229+
(ei.event, ei.event_id)
230+
})
230231
}
231232

232233
pub fn extend<I>(&mut self, events: I)
@@ -374,6 +375,32 @@ impl<'a, T: Component> EventReader<'a, T> {
374375
}
375376
}
376377

378+
/// Reads and consumes all events of type T
379+
///
380+
/// Useful for manual event cleanup when [AppBuilder::add_event::<T>] is omitted,
381+
/// allowing events to accumulate on your components or resources until consumed.
382+
/// Note: due to the draining nature of this reader, you probably only want one
383+
/// EventConsumer per event storage location + event type combination.
384+
pub struct EventConsumer<'a, T: Component> {
385+
events: &'a mut Events<T>,
386+
}
387+
388+
impl<'a, T: Component> SystemParam for EventConsumer<'a, T> {
389+
type Fetch = ResMutState<Events<T>>;
390+
}
391+
392+
impl<'a, T: Component> EventConsumer<'a, T> {
393+
/// Drains all available events this EventConsumer has access to into an iterator
394+
pub fn drain(self) -> impl DoubleEndedIterator<Item = T> + 'a {
395+
self.events.drain()
396+
}
397+
398+
/// Drains all available events this EventConsumer has access to into an iterator and returns the id
399+
pub fn drain_with_id(self) -> impl DoubleEndedIterator<Item = (T, EventId<T>)> + 'a {
400+
self.events.drain_with_id()
401+
}
402+
}
403+
377404
pub struct ManualEventReader<T> {
378405
last_event_count: usize,
379406
_marker: PhantomData<T>,

0 commit comments

Comments
 (0)