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}