bevy_ecs/event/
collections.rs

1use crate as bevy_ecs;
2use bevy_ecs::{
3    event::{Event, EventCursor, EventId, EventInstance},
4    system::Resource,
5};
6use bevy_utils::detailed_trace;
7use core::{
8    marker::PhantomData,
9    ops::{Deref, DerefMut},
10};
11#[cfg(feature = "bevy_reflect")]
12use {
13    bevy_ecs::reflect::ReflectResource,
14    bevy_reflect::{std_traits::ReflectDefault, Reflect},
15};
16
17/// An event collection that represents the events that occurred within the last two
18/// [`Events::update`] calls.
19/// Events can be written to using an [`EventWriter`]
20/// and are typically cheaply read using an [`EventReader`].
21///
22/// Each event can be consumed by multiple systems, in parallel,
23/// with consumption tracked by the [`EventReader`] on a per-system basis.
24///
25/// If no [ordering](https://github.com/bevyengine/bevy/blob/main/examples/ecs/ecs_guide.rs)
26/// is applied between writing and reading systems, there is a risk of a race condition.
27/// This means that whether the events arrive before or after the next [`Events::update`] is unpredictable.
28///
29/// This collection is meant to be paired with a system that calls
30/// [`Events::update`] exactly once per update/frame.
31///
32/// [`event_update_system`] is a system that does this, typically initialized automatically using
33/// [`add_event`](https://docs.rs/bevy/*/bevy/app/struct.App.html#method.add_event).
34/// [`EventReader`]s are expected to read events from this collection at least once per loop/frame.
35/// Events will persist across a single frame boundary and so ordering of event producers and
36/// consumers is not critical (although poorly-planned ordering may cause accumulating lag).
37/// If events are not handled by the end of the frame after they are updated, they will be
38/// dropped silently.
39///
40/// # Example
41/// ```
42/// use bevy_ecs::event::{Event, Events};
43///
44/// #[derive(Event)]
45/// struct MyEvent {
46///     value: usize
47/// }
48///
49/// // setup
50/// let mut events = Events::<MyEvent>::default();
51/// let mut cursor = events.get_cursor();
52///
53/// // run this once per update/frame
54/// events.update();
55///
56/// // somewhere else: send an event
57/// events.send(MyEvent { value: 1 });
58///
59/// // somewhere else: read the events
60/// for event in cursor.read(&events) {
61///     assert_eq!(event.value, 1)
62/// }
63///
64/// // events are only processed once per reader
65/// assert_eq!(cursor.read(&events).count(), 0);
66/// ```
67///
68/// # Details
69///
70/// [`Events`] is implemented using a variation of a double buffer strategy.
71/// Each call to [`update`](Events::update) swaps buffers and clears out the oldest one.
72/// - [`EventReader`]s will read events from both buffers.
73/// - [`EventReader`]s that read at least once per update will never drop events.
74/// - [`EventReader`]s that read once within two updates might still receive some events
75/// - [`EventReader`]s that read after two updates are guaranteed to drop all events that occurred
76///     before those updates.
77///
78/// The buffers in [`Events`] will grow indefinitely if [`update`](Events::update) is never called.
79///
80/// An alternative call pattern would be to call [`update`](Events::update)
81/// manually across frames to control when events are cleared.
82/// This complicates consumption and risks ever-expanding memory usage if not cleaned up,
83/// but can be done by adding your event as a resource instead of using
84/// [`add_event`](https://docs.rs/bevy/*/bevy/app/struct.App.html#method.add_event).
85///
86/// [Example usage.](https://github.com/bevyengine/bevy/blob/latest/examples/ecs/event.rs)
87/// [Example usage standalone.](https://github.com/bevyengine/bevy/blob/latest/crates/bevy_ecs/examples/events.rs)
88///
89/// [`EventReader`]: super::EventReader
90/// [`EventWriter`]: super::EventWriter
91/// [`event_update_system`]: super::event_update_system
92#[derive(Debug, Resource)]
93#[cfg_attr(feature = "bevy_reflect", derive(Reflect), reflect(Resource, Default))]
94pub struct Events<E: Event> {
95    /// Holds the oldest still active events.
96    /// Note that `a.start_event_count + a.len()` should always be equal to `events_b.start_event_count`.
97    pub(crate) events_a: EventSequence<E>,
98    /// Holds the newer events.
99    pub(crate) events_b: EventSequence<E>,
100    pub(crate) event_count: usize,
101}
102
103// Derived Default impl would incorrectly require E: Default
104impl<E: Event> Default for Events<E> {
105    fn default() -> Self {
106        Self {
107            events_a: Default::default(),
108            events_b: Default::default(),
109            event_count: Default::default(),
110        }
111    }
112}
113
114impl<E: Event> Events<E> {
115    /// Returns the index of the oldest event stored in the event buffer.
116    pub fn oldest_event_count(&self) -> usize {
117        self.events_a.start_event_count
118    }
119
120    /// "Sends" an `event` by writing it to the current event buffer.
121    /// [`EventReader`](super::EventReader)s can then read the event.
122    /// This method returns the [ID](`EventId`) of the sent `event`.
123    pub fn send(&mut self, event: E) -> EventId<E> {
124        let event_id = EventId {
125            id: self.event_count,
126            _marker: PhantomData,
127        };
128        detailed_trace!("Events::send() -> id: {}", event_id);
129
130        let event_instance = EventInstance { event_id, event };
131
132        self.events_b.push(event_instance);
133        self.event_count += 1;
134
135        event_id
136    }
137
138    /// Sends a list of `events` all at once, which can later be read by [`EventReader`](super::EventReader)s.
139    /// This is more efficient than sending each event individually.
140    /// This method returns the [IDs](`EventId`) of the sent `events`.
141    pub fn send_batch(&mut self, events: impl IntoIterator<Item = E>) -> SendBatchIds<E> {
142        let last_count = self.event_count;
143
144        self.extend(events);
145
146        SendBatchIds {
147            last_count,
148            event_count: self.event_count,
149            _marker: PhantomData,
150        }
151    }
152
153    /// Sends the default value of the event. Useful when the event is an empty struct.
154    /// This method returns the [ID](`EventId`) of the sent `event`.
155    pub fn send_default(&mut self) -> EventId<E>
156    where
157        E: Default,
158    {
159        self.send(Default::default())
160    }
161
162    /// Gets a new [`EventCursor`]. This will include all events already in the event buffers.
163    pub fn get_cursor(&self) -> EventCursor<E> {
164        EventCursor::default()
165    }
166
167    /// Gets a new [`EventCursor`]. This will ignore all events already in the event buffers.
168    /// It will read all future events.
169    pub fn get_cursor_current(&self) -> EventCursor<E> {
170        EventCursor {
171            last_event_count: self.event_count,
172            ..Default::default()
173        }
174    }
175
176    #[deprecated(
177        since = "0.14.0",
178        note = "`get_reader` has been deprecated. Please use `get_cursor` instead."
179    )]
180    /// Gets a new [`EventCursor`]. This will include all events already in the event buffers.
181    pub fn get_reader(&self) -> EventCursor<E> {
182        EventCursor::default()
183    }
184
185    #[deprecated(
186        since = "0.14.0",
187        note = "`get_reader_current` has been replaced. Please use `get_cursor_current` instead."
188    )]
189    /// Gets a new [`EventCursor`]. This will ignore all events already in the event buffers.
190    /// It will read all future events.
191    pub fn get_reader_current(&self) -> EventCursor<E> {
192        EventCursor {
193            last_event_count: self.event_count,
194            ..Default::default()
195        }
196    }
197
198    /// Swaps the event buffers and clears the oldest event buffer. In general, this should be
199    /// called once per frame/update.
200    ///
201    /// If you need access to the events that were removed, consider using [`Events::update_drain`].
202    pub fn update(&mut self) {
203        core::mem::swap(&mut self.events_a, &mut self.events_b);
204        self.events_b.clear();
205        self.events_b.start_event_count = self.event_count;
206        debug_assert_eq!(
207            self.events_a.start_event_count + self.events_a.len(),
208            self.events_b.start_event_count
209        );
210    }
211
212    /// Swaps the event buffers and drains the oldest event buffer, returning an iterator
213    /// of all events that were removed. In general, this should be called once per frame/update.
214    ///
215    /// If you do not need to take ownership of the removed events, use [`Events::update`] instead.
216    #[must_use = "If you do not need the returned events, call .update() instead."]
217    pub fn update_drain(&mut self) -> impl Iterator<Item = E> + '_ {
218        core::mem::swap(&mut self.events_a, &mut self.events_b);
219        let iter = self.events_b.events.drain(..);
220        self.events_b.start_event_count = self.event_count;
221        debug_assert_eq!(
222            self.events_a.start_event_count + self.events_a.len(),
223            self.events_b.start_event_count
224        );
225
226        iter.map(|e| e.event)
227    }
228
229    #[inline]
230    fn reset_start_event_count(&mut self) {
231        self.events_a.start_event_count = self.event_count;
232        self.events_b.start_event_count = self.event_count;
233    }
234
235    /// Removes all events.
236    #[inline]
237    pub fn clear(&mut self) {
238        self.reset_start_event_count();
239        self.events_a.clear();
240        self.events_b.clear();
241    }
242
243    /// Returns the number of events currently stored in the event buffer.
244    #[inline]
245    pub fn len(&self) -> usize {
246        self.events_a.len() + self.events_b.len()
247    }
248
249    /// Returns true if there are no events currently stored in the event buffer.
250    #[inline]
251    pub fn is_empty(&self) -> bool {
252        self.len() == 0
253    }
254
255    /// Creates a draining iterator that removes all events.
256    pub fn drain(&mut self) -> impl Iterator<Item = E> + '_ {
257        self.reset_start_event_count();
258
259        // Drain the oldest events first, then the newest
260        self.events_a
261            .drain(..)
262            .chain(self.events_b.drain(..))
263            .map(|i| i.event)
264    }
265
266    /// Iterates over events that happened since the last "update" call.
267    /// WARNING: You probably don't want to use this call. In most cases you should use an
268    /// [`EventReader`]. You should only use this if you know you only need to consume events
269    /// between the last `update()` call and your call to `iter_current_update_events`.
270    /// If events happen outside that window, they will not be handled. For example, any events that
271    /// happen after this call and before the next `update()` call will be dropped.
272    ///
273    /// [`EventReader`]: super::EventReader
274    pub fn iter_current_update_events(&self) -> impl ExactSizeIterator<Item = &E> {
275        self.events_b.iter().map(|i| &i.event)
276    }
277
278    /// Get a specific event by id if it still exists in the events buffer.
279    pub fn get_event(&self, id: usize) -> Option<(&E, EventId<E>)> {
280        if id < self.oldest_event_count() {
281            return None;
282        }
283
284        let sequence = self.sequence(id);
285        let index = id.saturating_sub(sequence.start_event_count);
286
287        sequence
288            .get(index)
289            .map(|instance| (&instance.event, instance.event_id))
290    }
291
292    /// Which event buffer is this event id a part of.
293    fn sequence(&self, id: usize) -> &EventSequence<E> {
294        if id < self.events_b.start_event_count {
295            &self.events_a
296        } else {
297            &self.events_b
298        }
299    }
300}
301
302impl<E: Event> Extend<E> for Events<E> {
303    fn extend<I>(&mut self, iter: I)
304    where
305        I: IntoIterator<Item = E>,
306    {
307        let old_count = self.event_count;
308        let mut event_count = self.event_count;
309        let events = iter.into_iter().map(|event| {
310            let event_id = EventId {
311                id: event_count,
312                _marker: PhantomData,
313            };
314            event_count += 1;
315            EventInstance { event_id, event }
316        });
317
318        self.events_b.extend(events);
319
320        if old_count != event_count {
321            detailed_trace!(
322                "Events::extend() -> ids: ({}..{})",
323                self.event_count,
324                event_count
325            );
326        }
327
328        self.event_count = event_count;
329    }
330}
331
332#[derive(Debug)]
333#[cfg_attr(feature = "bevy_reflect", derive(Reflect))]
334pub(crate) struct EventSequence<E: Event> {
335    pub(crate) events: Vec<EventInstance<E>>,
336    pub(crate) start_event_count: usize,
337}
338
339// Derived Default impl would incorrectly require E: Default
340impl<E: Event> Default for EventSequence<E> {
341    fn default() -> Self {
342        Self {
343            events: Default::default(),
344            start_event_count: Default::default(),
345        }
346    }
347}
348
349impl<E: Event> Deref for EventSequence<E> {
350    type Target = Vec<EventInstance<E>>;
351
352    fn deref(&self) -> &Self::Target {
353        &self.events
354    }
355}
356
357impl<E: Event> DerefMut for EventSequence<E> {
358    fn deref_mut(&mut self) -> &mut Self::Target {
359        &mut self.events
360    }
361}
362
363/// [`Iterator`] over sent [`EventIds`](`EventId`) from a batch.
364pub struct SendBatchIds<E> {
365    last_count: usize,
366    event_count: usize,
367    _marker: PhantomData<E>,
368}
369
370impl<E: Event> Iterator for SendBatchIds<E> {
371    type Item = EventId<E>;
372
373    fn next(&mut self) -> Option<Self::Item> {
374        if self.last_count >= self.event_count {
375            return None;
376        }
377
378        let result = Some(EventId {
379            id: self.last_count,
380            _marker: PhantomData,
381        });
382
383        self.last_count += 1;
384
385        result
386    }
387}
388
389impl<E: Event> ExactSizeIterator for SendBatchIds<E> {
390    fn len(&self) -> usize {
391        self.event_count.saturating_sub(self.last_count)
392    }
393}
394
395#[cfg(test)]
396mod tests {
397    use crate::{self as bevy_ecs, event::Events};
398    use bevy_ecs_macros::Event;
399
400    #[test]
401    fn iter_current_update_events_iterates_over_current_events() {
402        #[derive(Event, Clone)]
403        struct TestEvent;
404
405        let mut test_events = Events::<TestEvent>::default();
406
407        // Starting empty
408        assert_eq!(test_events.len(), 0);
409        assert_eq!(test_events.iter_current_update_events().count(), 0);
410        test_events.update();
411
412        // Sending one event
413        test_events.send(TestEvent);
414
415        assert_eq!(test_events.len(), 1);
416        assert_eq!(test_events.iter_current_update_events().count(), 1);
417        test_events.update();
418
419        // Sending two events on the next frame
420        test_events.send(TestEvent);
421        test_events.send(TestEvent);
422
423        assert_eq!(test_events.len(), 3); // Events are double-buffered, so we see 1 + 2 = 3
424        assert_eq!(test_events.iter_current_update_events().count(), 2);
425        test_events.update();
426
427        // Sending zero events
428        assert_eq!(test_events.len(), 2); // Events are double-buffered, so we see 2 + 0 = 2
429        assert_eq!(test_events.iter_current_update_events().count(), 0);
430    }
431}