use crate as bevy_ecs; use bevy_ecs::event::{ Event, EventIterator, EventIteratorWithId, EventMutIterator, EventMutIteratorWithId, Events, }; #[cfg(feature = "multi_threaded")] use bevy_ecs::event::{EventMutParIter, EventParIter}; use std::marker::PhantomData; // Deprecated in favor of `EventCursor`, there is no nice way to deprecate this // because generic constraints are not allowed in type aliases, so this will always // 'dead code'. Hence the `#[allow(dead_code)]`. #[deprecated( since = "0.14.0", note = "`ManualEventReader` has been replaced. Please use `EventCursor` instead." )] #[doc(alias = "EventCursor")] #[allow(dead_code)] pub type ManualEventReader = EventCursor; /// Stores the state for an [`EventReader`] or [`EventMutator`]. /// /// Access to the [`Events`] resource is required to read any incoming events. /// /// In almost all cases, you should just use an [`EventReader`] or [`EventMutator`], /// which will automatically manage the state for you. /// /// However, this type can be useful if you need to manually track events, /// such as when you're attempting to send and receive events of the same type in the same system. /// /// # Example /// /// ``` /// use bevy_ecs::prelude::*; /// use bevy_ecs::event::{Event, Events, EventCursor}; /// /// #[derive(Event, Clone, Debug)] /// struct MyEvent; /// /// /// A system that both sends and receives events using a [`Local`] [`EventCursor`]. /// fn send_and_receive_events( /// // The `Local` `SystemParam` stores state inside the system itself, rather than in the world. /// // `EventCursor` is the internal state of `EventMutator`, which tracks which events have been seen. /// mut local_event_reader: Local>, /// // We can access the `Events` resource mutably, allowing us to both read and write its contents. /// mut events: ResMut>, /// ) { /// // We must collect the events to resend, because we can't mutate events while we're iterating over the events. /// let mut events_to_resend = Vec::new(); /// /// for event in local_event_reader.read(&mut events) { /// events_to_resend.push(event.clone()); /// } /// /// for event in events_to_resend { /// events.send(MyEvent); /// } /// } /// /// # bevy_ecs::system::assert_is_system(send_and_receive_events); /// ``` /// /// [`EventReader`]: super::EventReader /// [`EventMutator`]: super::EventMutator #[derive(Debug)] pub struct EventCursor { pub(super) last_event_count: usize, pub(super) _marker: PhantomData, } impl Default for EventCursor { fn default() -> Self { EventCursor { last_event_count: 0, _marker: Default::default(), } } } impl Clone for EventCursor { fn clone(&self) -> Self { EventCursor { last_event_count: self.last_event_count, _marker: PhantomData, } } } #[allow(clippy::len_without_is_empty)] // Check fails since the is_empty implementation has a signature other than `(&self) -> bool` impl EventCursor { /// See [`EventReader::read`](super::EventReader::read) pub fn read<'a>(&'a mut self, events: &'a Events) -> EventIterator<'a, E> { self.read_with_id(events).without_id() } /// See [`EventMutator::read`](super::EventMutator::read) pub fn read_mut<'a>(&'a mut self, events: &'a mut Events) -> EventMutIterator<'a, E> { self.read_mut_with_id(events).without_id() } /// See [`EventReader::read_with_id`](super::EventReader::read_with_id) pub fn read_with_id<'a>(&'a mut self, events: &'a Events) -> EventIteratorWithId<'a, E> { EventIteratorWithId::new(self, events) } /// See [`EventMutator::read_with_id`](super::EventMutator::read_with_id) pub fn read_mut_with_id<'a>( &'a mut self, events: &'a mut Events, ) -> EventMutIteratorWithId<'a, E> { EventMutIteratorWithId::new(self, events) } /// See [`EventReader::par_read`](super::EventReader::par_read) #[cfg(feature = "multi_threaded")] pub fn par_read<'a>(&'a mut self, events: &'a Events) -> EventParIter<'a, E> { EventParIter::new(self, events) } /// See [`EventMutator::par_read`](super::EventMutator::par_read) #[cfg(feature = "multi_threaded")] pub fn par_read_mut<'a>(&'a mut self, events: &'a mut Events) -> EventMutParIter<'a, E> { EventMutParIter::new(self, events) } /// See [`EventReader::len`](super::EventReader::len) pub fn len(&self, events: &Events) -> usize { // The number of events in this reader is the difference between the most recent event // and the last event seen by it. This will be at most the number of events contained // with the events (any others have already been dropped) // TODO: Warn when there are dropped events, or return e.g. a `Result` events .event_count .saturating_sub(self.last_event_count) .min(events.len()) } /// Amount of events we missed. pub fn missed_events(&self, events: &Events) -> usize { events .oldest_event_count() .saturating_sub(self.last_event_count) } /// See [`EventReader::is_empty()`](super::EventReader::is_empty) pub fn is_empty(&self, events: &Events) -> bool { self.len(events) == 0 } /// See [`EventReader::clear()`](super::EventReader::clear) pub fn clear(&mut self, events: &Events) { self.last_event_count = events.event_count; } }