bevy_ecs/event/
event_cursor.rs

1use crate as bevy_ecs;
2use bevy_ecs::event::{
3    Event, EventIterator, EventIteratorWithId, EventMutIterator, EventMutIteratorWithId, Events,
4};
5#[cfg(feature = "multi_threaded")]
6use bevy_ecs::event::{EventMutParIter, EventParIter};
7use core::marker::PhantomData;
8
9// Deprecated in favor of `EventCursor`, there is no nice way to deprecate this
10// because generic constraints are not allowed in type aliases, so this will always
11// 'dead code'. Hence the `#[allow(dead_code)]`.
12#[deprecated(
13    since = "0.14.0",
14    note = "`ManualEventReader` has been replaced. Please use `EventCursor` instead."
15)]
16#[doc(alias = "EventCursor")]
17#[allow(dead_code)]
18pub type ManualEventReader<E> = EventCursor<E>;
19
20/// Stores the state for an [`EventReader`] or [`EventMutator`].
21///
22/// Access to the [`Events<E>`] resource is required to read any incoming events.
23///
24/// In almost all cases, you should just use an [`EventReader`] or [`EventMutator`],
25/// which will automatically manage the state for you.
26///
27/// However, this type can be useful if you need to manually track events,
28/// such as when you're attempting to send and receive events of the same type in the same system.
29///
30/// # Example
31///
32/// ```
33/// use bevy_ecs::prelude::*;
34/// use bevy_ecs::event::{Event, Events, EventCursor};
35///
36/// #[derive(Event, Clone, Debug)]
37/// struct MyEvent;
38///
39/// /// A system that both sends and receives events using a [`Local`] [`EventCursor`].
40/// fn send_and_receive_events(
41///     // The `Local` `SystemParam` stores state inside the system itself, rather than in the world.
42///     // `EventCursor<T>` is the internal state of `EventMutator<T>`, which tracks which events have been seen.
43///     mut local_event_reader: Local<EventCursor<MyEvent>>,
44///     // We can access the `Events` resource mutably, allowing us to both read and write its contents.
45///     mut events: ResMut<Events<MyEvent>>,
46/// ) {
47///     // We must collect the events to resend, because we can't mutate events while we're iterating over the events.
48///     let mut events_to_resend = Vec::new();
49///
50///     for event in local_event_reader.read(&mut events) {
51///          events_to_resend.push(event.clone());
52///     }
53///
54///     for event in events_to_resend {
55///         events.send(MyEvent);
56///     }
57/// }
58///
59/// # bevy_ecs::system::assert_is_system(send_and_receive_events);
60/// ```
61///
62/// [`EventReader`]: super::EventReader
63/// [`EventMutator`]: super::EventMutator
64#[derive(Debug)]
65pub struct EventCursor<E: Event> {
66    pub(super) last_event_count: usize,
67    pub(super) _marker: PhantomData<E>,
68}
69
70impl<E: Event> Default for EventCursor<E> {
71    fn default() -> Self {
72        EventCursor {
73            last_event_count: 0,
74            _marker: Default::default(),
75        }
76    }
77}
78
79impl<E: Event> Clone for EventCursor<E> {
80    fn clone(&self) -> Self {
81        EventCursor {
82            last_event_count: self.last_event_count,
83            _marker: PhantomData,
84        }
85    }
86}
87
88#[allow(clippy::len_without_is_empty)] // Check fails since the is_empty implementation has a signature other than `(&self) -> bool`
89impl<E: Event> EventCursor<E> {
90    /// See [`EventReader::read`](super::EventReader::read)
91    pub fn read<'a>(&'a mut self, events: &'a Events<E>) -> EventIterator<'a, E> {
92        self.read_with_id(events).without_id()
93    }
94
95    /// See [`EventMutator::read`](super::EventMutator::read)
96    pub fn read_mut<'a>(&'a mut self, events: &'a mut Events<E>) -> EventMutIterator<'a, E> {
97        self.read_mut_with_id(events).without_id()
98    }
99
100    /// See [`EventReader::read_with_id`](super::EventReader::read_with_id)
101    pub fn read_with_id<'a>(&'a mut self, events: &'a Events<E>) -> EventIteratorWithId<'a, E> {
102        EventIteratorWithId::new(self, events)
103    }
104
105    /// See [`EventMutator::read_with_id`](super::EventMutator::read_with_id)
106    pub fn read_mut_with_id<'a>(
107        &'a mut self,
108        events: &'a mut Events<E>,
109    ) -> EventMutIteratorWithId<'a, E> {
110        EventMutIteratorWithId::new(self, events)
111    }
112
113    /// See [`EventReader::par_read`](super::EventReader::par_read)
114    #[cfg(feature = "multi_threaded")]
115    pub fn par_read<'a>(&'a mut self, events: &'a Events<E>) -> EventParIter<'a, E> {
116        EventParIter::new(self, events)
117    }
118
119    /// See [`EventMutator::par_read`](super::EventMutator::par_read)
120    #[cfg(feature = "multi_threaded")]
121    pub fn par_read_mut<'a>(&'a mut self, events: &'a mut Events<E>) -> EventMutParIter<'a, E> {
122        EventMutParIter::new(self, events)
123    }
124
125    /// See [`EventReader::len`](super::EventReader::len)
126    pub fn len(&self, events: &Events<E>) -> usize {
127        // The number of events in this reader is the difference between the most recent event
128        // and the last event seen by it. This will be at most the number of events contained
129        // with the events (any others have already been dropped)
130        // TODO: Warn when there are dropped events, or return e.g. a `Result<usize, (usize, usize)>`
131        events
132            .event_count
133            .saturating_sub(self.last_event_count)
134            .min(events.len())
135    }
136
137    /// Amount of events we missed.
138    pub fn missed_events(&self, events: &Events<E>) -> usize {
139        events
140            .oldest_event_count()
141            .saturating_sub(self.last_event_count)
142    }
143
144    /// See [`EventReader::is_empty()`](super::EventReader::is_empty)
145    pub fn is_empty(&self, events: &Events<E>) -> bool {
146        self.len(events) == 0
147    }
148
149    /// See [`EventReader::clear()`](super::EventReader::clear)
150    pub fn clear(&mut self, events: &Events<E>) {
151        self.last_event_count = events.event_count;
152    }
153}