Skip to content

Commit

Permalink
Reorganize Events and EventSequence code (#9306)
Browse files Browse the repository at this point in the history
# Objective

Make code relating to event more readable.

Currently the `impl` block of `Events` is split in two, and the big part
of its implementations are put at the end of the file, far from the
definition of the `struct`.

## Solution

- Move and merge the `impl` blocks of `Events` next to its definition.
- Move the `EventSequence` definition and implementations before the
`Events`, because they're pretty trivial and help understand how
`Events` work, rather than being buried bellow `Events`.

I separated those two steps in two commits to not be too confusing. I
didn't modify any code of documentation. I want to do a second PR with
such modifications after this one is merged.
  • Loading branch information
Selene-Amanita authored Aug 28, 2023
1 parent fb9a65f commit f38549c
Showing 1 changed file with 159 additions and 161 deletions.
320 changes: 159 additions & 161 deletions crates/bevy_ecs/src/event.rs
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,165 @@ impl<E: Event> Events<E> {
.start_event_count
.min(self.events_b.start_event_count)
}

/// "Sends" an `event` by writing it to the current event buffer. [`EventReader`]s can then read
/// the event.
pub fn send(&mut self, event: E) {
let event_id = EventId {
id: self.event_count,
_marker: PhantomData,
};
detailed_trace!("Events::send() -> id: {}", event_id);

let event_instance = EventInstance { event_id, event };

self.events_b.push(event_instance);
self.event_count += 1;
}

/// Sends the default value of the event. Useful when the event is an empty struct.
pub fn send_default(&mut self)
where
E: Default,
{
self.send(Default::default());
}

/// Gets a new [`ManualEventReader`]. This will include all events already in the event buffers.
pub fn get_reader(&self) -> ManualEventReader<E> {
ManualEventReader::default()
}

/// Gets a new [`ManualEventReader`]. This will ignore all events already in the event buffers.
/// It will read all future events.
pub fn get_reader_current(&self) -> ManualEventReader<E> {
ManualEventReader {
last_event_count: self.event_count,
..Default::default()
}
}

/// Swaps the event buffers and clears the oldest event buffer. In general, this should be
/// called once per frame/update.
pub fn update(&mut self) {
std::mem::swap(&mut self.events_a, &mut self.events_b);
self.events_b.clear();
self.events_b.start_event_count = self.event_count;
debug_assert_eq!(
self.events_a.start_event_count + self.events_a.len(),
self.events_b.start_event_count
);
}

/// A system that calls [`Events::update`] once per frame.
pub fn update_system(mut events: ResMut<Self>) {
events.update();
}

#[inline]
fn reset_start_event_count(&mut self) {
self.events_a.start_event_count = self.event_count;
self.events_b.start_event_count = self.event_count;
}

/// Removes all events.
#[inline]
pub fn clear(&mut self) {
self.reset_start_event_count();
self.events_a.clear();
self.events_b.clear();
}

/// Returns the number of events currently stored in the event buffer.
#[inline]
pub fn len(&self) -> usize {
self.events_a.len() + self.events_b.len()
}

/// Returns true if there are no events currently stored in the event buffer.
#[inline]
pub fn is_empty(&self) -> bool {
self.len() == 0
}

/// Creates a draining iterator that removes all events.
pub fn drain(&mut self) -> impl Iterator<Item = E> + '_ {
self.reset_start_event_count();

// Drain the oldest events first, then the newest
self.events_a
.drain(..)
.chain(self.events_b.drain(..))
.map(|i| i.event)
}

/// Iterates over events that happened since the last "update" call.
/// WARNING: You probably don't want to use this call. In most cases you should use an
/// [`EventReader`]. You should only use this if you know you only need to consume events
/// between the last `update()` call and your call to `iter_current_update_events`.
/// If events happen outside that window, they will not be handled. For example, any events that
/// happen after this call and before the next `update()` call will be dropped.
pub fn iter_current_update_events(&self) -> impl ExactSizeIterator<Item = &E> {
self.events_b.iter().map(|i| &i.event)
}

/// Get a specific event by id if it still exists in the events buffer.
pub fn get_event(&self, id: usize) -> Option<(&E, EventId<E>)> {
if id < self.oldest_id() {
return None;
}

let sequence = self.sequence(id);
let index = id.saturating_sub(sequence.start_event_count);

sequence
.get(index)
.map(|instance| (&instance.event, instance.event_id))
}

/// Oldest id still in the events buffer.
pub fn oldest_id(&self) -> usize {
self.events_a.start_event_count
}

/// Which event buffer is this event id a part of.
fn sequence(&self, id: usize) -> &EventSequence<E> {
if id < self.events_b.start_event_count {
&self.events_a
} else {
&self.events_b
}
}
}

impl<E: Event> std::iter::Extend<E> for Events<E> {
fn extend<I>(&mut self, iter: I)
where
I: IntoIterator<Item = E>,
{
let old_count = self.event_count;
let mut event_count = self.event_count;
let events = iter.into_iter().map(|event| {
let event_id = EventId {
id: event_count,
_marker: PhantomData,
};
event_count += 1;
EventInstance { event_id, event }
});

self.events_b.extend(events);

if old_count != event_count {
detailed_trace!(
"Events::extend() -> ids: ({}..{})",
self.event_count,
event_count
);
}

self.event_count = event_count;
}
}

#[derive(Debug)]
Expand Down Expand Up @@ -553,167 +712,6 @@ impl<'a, E: Event> ExactSizeIterator for ManualEventIteratorWithId<'a, E> {
}
}

impl<E: Event> Events<E> {
/// "Sends" an `event` by writing it to the current event buffer. [`EventReader`]s can then read
/// the event.
pub fn send(&mut self, event: E) {
let event_id = EventId {
id: self.event_count,
_marker: PhantomData,
};
detailed_trace!("Events::send() -> id: {}", event_id);

let event_instance = EventInstance { event_id, event };

self.events_b.push(event_instance);
self.event_count += 1;
}

/// Sends the default value of the event. Useful when the event is an empty struct.
pub fn send_default(&mut self)
where
E: Default,
{
self.send(Default::default());
}

/// Gets a new [`ManualEventReader`]. This will include all events already in the event buffers.
pub fn get_reader(&self) -> ManualEventReader<E> {
ManualEventReader::default()
}

/// Gets a new [`ManualEventReader`]. This will ignore all events already in the event buffers.
/// It will read all future events.
pub fn get_reader_current(&self) -> ManualEventReader<E> {
ManualEventReader {
last_event_count: self.event_count,
..Default::default()
}
}

/// Swaps the event buffers and clears the oldest event buffer. In general, this should be
/// called once per frame/update.
pub fn update(&mut self) {
std::mem::swap(&mut self.events_a, &mut self.events_b);
self.events_b.clear();
self.events_b.start_event_count = self.event_count;
debug_assert_eq!(
self.events_a.start_event_count + self.events_a.len(),
self.events_b.start_event_count
);
}

/// A system that calls [`Events::update`] once per frame.
pub fn update_system(mut events: ResMut<Self>) {
events.update();
}

#[inline]
fn reset_start_event_count(&mut self) {
self.events_a.start_event_count = self.event_count;
self.events_b.start_event_count = self.event_count;
}

/// Removes all events.
#[inline]
pub fn clear(&mut self) {
self.reset_start_event_count();
self.events_a.clear();
self.events_b.clear();
}

/// Returns the number of events currently stored in the event buffer.
#[inline]
pub fn len(&self) -> usize {
self.events_a.len() + self.events_b.len()
}

/// Returns true if there are no events currently stored in the event buffer.
#[inline]
pub fn is_empty(&self) -> bool {
self.len() == 0
}

/// Creates a draining iterator that removes all events.
pub fn drain(&mut self) -> impl Iterator<Item = E> + '_ {
self.reset_start_event_count();

// Drain the oldest events first, then the newest
self.events_a
.drain(..)
.chain(self.events_b.drain(..))
.map(|i| i.event)
}

/// Iterates over events that happened since the last "update" call.
/// WARNING: You probably don't want to use this call. In most cases you should use an
/// [`EventReader`]. You should only use this if you know you only need to consume events
/// between the last `update()` call and your call to `iter_current_update_events`.
/// If events happen outside that window, they will not be handled. For example, any events that
/// happen after this call and before the next `update()` call will be dropped.
pub fn iter_current_update_events(&self) -> impl ExactSizeIterator<Item = &E> {
self.events_b.iter().map(|i| &i.event)
}

/// Get a specific event by id if it still exists in the events buffer.
pub fn get_event(&self, id: usize) -> Option<(&E, EventId<E>)> {
if id < self.oldest_id() {
return None;
}

let sequence = self.sequence(id);
let index = id.saturating_sub(sequence.start_event_count);

sequence
.get(index)
.map(|instance| (&instance.event, instance.event_id))
}

/// Oldest id still in the events buffer.
pub fn oldest_id(&self) -> usize {
self.events_a.start_event_count
}

/// Which event buffer is this event id a part of.
fn sequence(&self, id: usize) -> &EventSequence<E> {
if id < self.events_b.start_event_count {
&self.events_a
} else {
&self.events_b
}
}
}

impl<E: Event> std::iter::Extend<E> for Events<E> {
fn extend<I>(&mut self, iter: I)
where
I: IntoIterator<Item = E>,
{
let old_count = self.event_count;
let mut event_count = self.event_count;
let events = iter.into_iter().map(|event| {
let event_id = EventId {
id: event_count,
_marker: PhantomData,
};
event_count += 1;
EventInstance { event_id, event }
});

self.events_b.extend(events);

if old_count != event_count {
detailed_trace!(
"Events::extend() -> ids: ({}..{})",
self.event_count,
event_count
);
}

self.event_count = event_count;
}
}

#[cfg(test)]
mod tests {
use crate::{prelude::World, system::SystemState};
Expand Down

0 comments on commit f38549c

Please sign in to comment.