use crate as bevy_ecs;
use crate::system::{Local, Res, ResMut, Resource, SystemParam};
use bevy_utils::tracing::trace;
use std::ops::{Deref, DerefMut};
use std::{fmt, hash::Hash, marker::PhantomData};
pub trait Event: Send + Sync + 'static {}
impl<T> Event for T where T: Send + Sync + 'static {}
#[derive(Eq, PartialEq, Ord, PartialOrd, Hash)]
pub struct EventId<E: Event> {
pub id: usize,
_marker: PhantomData<E>,
}
impl<E: Event> Copy for EventId<E> {}
impl<E: Event> Clone for EventId<E> {
fn clone(&self) -> Self {
*self
}
}
impl<E: Event> fmt::Display for EventId<E> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
<Self as fmt::Debug>::fmt(self, f)
}
}
impl<E: Event> fmt::Debug for EventId<E> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(
f,
"event<{}>#{}",
std::any::type_name::<E>().split("::").last().unwrap(),
self.id,
)
}
}
#[derive(Debug)]
struct EventInstance<E: Event> {
pub event_id: EventId<E>,
pub event: E,
}
#[derive(Debug, Resource)]
pub struct Events<E: Event> {
events_a: EventSequence<E>,
events_b: EventSequence<E>,
event_count: usize,
}
impl<E: Event> Default for Events<E> {
fn default() -> Self {
Self {
events_a: Default::default(),
events_b: Default::default(),
event_count: Default::default(),
}
}
}
impl<E: Event> Events<E> {
pub fn oldest_event_count(&self) -> usize {
self.events_a
.start_event_count
.min(self.events_b.start_event_count)
}
}
#[derive(Debug)]
struct EventSequence<E: Event> {
events: Vec<EventInstance<E>>,
start_event_count: usize,
}
impl<E: Event> Default for EventSequence<E> {
fn default() -> Self {
Self {
events: Default::default(),
start_event_count: Default::default(),
}
}
}
impl<E: Event> Deref for EventSequence<E> {
type Target = Vec<EventInstance<E>>;
fn deref(&self) -> &Self::Target {
&self.events
}
}
impl<E: Event> DerefMut for EventSequence<E> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.events
}
}
#[derive(SystemParam)]
pub struct EventReader<'w, 's, E: Event> {
reader: Local<'s, ManualEventReader<E>>,
events: Res<'w, Events<E>>,
}
impl<'w, 's, E: Event> EventReader<'w, 's, E> {
pub fn iter(&mut self) -> impl DoubleEndedIterator<Item = &E> + ExactSizeIterator<Item = &E> {
self.iter_with_id().map(|(event, _id)| event)
}
pub fn iter_with_id(
&mut self,
) -> impl DoubleEndedIterator<Item = (&E, EventId<E>)> + ExactSizeIterator<Item = (&E, EventId<E>)>
{
self.reader.iter_with_id(&self.events).inspect(|(_, id)| {
trace!("EventReader::iter() -> {}", id);
})
}
pub fn len(&self) -> usize {
self.reader.len(&self.events)
}
pub fn is_empty(&self) -> bool {
self.len() == 0
}
pub fn clear(mut self) {
self.iter().last();
}
}
#[derive(SystemParam)]
pub struct EventWriter<'w, 's, E: Event> {
events: ResMut<'w, Events<E>>,
#[system_param(ignore)]
marker: PhantomData<&'s usize>,
}
impl<'w, 's, E: Event> EventWriter<'w, 's, E> {
pub fn send(&mut self, event: E) {
self.events.send(event);
}
pub fn send_batch(&mut self, events: impl IntoIterator<Item = E>) {
self.events.extend(events);
}
pub fn send_default(&mut self)
where
E: Default,
{
self.events.send_default();
}
}
#[derive(Debug)]
pub struct ManualEventReader<E: Event> {
last_event_count: usize,
_marker: PhantomData<E>,
}
impl<E: Event> Default for ManualEventReader<E> {
fn default() -> Self {
ManualEventReader {
last_event_count: 0,
_marker: Default::default(),
}
}
}
#[allow(clippy::len_without_is_empty)] impl<E: Event> ManualEventReader<E> {
pub fn iter<'a>(
&'a mut self,
events: &'a Events<E>,
) -> impl DoubleEndedIterator<Item = &'a E> + ExactSizeIterator<Item = &'a E> {
self.iter_with_id(events).map(|(e, _)| e)
}
pub fn iter_with_id<'a>(
&'a mut self,
events: &'a Events<E>,
) -> impl DoubleEndedIterator<Item = (&'a E, EventId<E>)>
+ ExactSizeIterator<Item = (&'a E, EventId<E>)> {
let a_index = (self.last_event_count).saturating_sub(events.events_a.start_event_count);
let b_index = (self.last_event_count).saturating_sub(events.events_b.start_event_count);
let a = events.events_a.get(a_index..).unwrap_or_default();
let b = events.events_b.get(b_index..).unwrap_or_default();
let unread_count = a.len() + b.len();
debug_assert_eq!(unread_count, self.len(events));
self.last_event_count = events.event_count - unread_count;
let iterator = a.iter().chain(b.iter());
iterator
.map(|e| (&e.event, e.event_id))
.with_exact_size(unread_count)
.inspect(move |(_, id)| self.last_event_count = (id.id + 1).max(self.last_event_count))
}
pub fn len(&self, events: &Events<E>) -> usize {
events
.event_count
.saturating_sub(self.last_event_count)
.min(events.len())
}
pub fn missed_events(&self, events: &Events<E>) -> usize {
events
.oldest_event_count()
.saturating_sub(self.last_event_count)
}
pub fn is_empty(&self, events: &Events<E>) -> bool {
self.len(events) == 0
}
}
trait IteratorExt {
fn with_exact_size(self, len: usize) -> ExactSize<Self>
where
Self: Sized,
{
ExactSize::new(self, len)
}
}
impl<I> IteratorExt for I where I: Iterator {}
#[must_use = "iterators are lazy and do nothing unless consumed"]
#[derive(Clone)]
struct ExactSize<I> {
iter: I,
len: usize,
}
impl<I> ExactSize<I> {
fn new(iter: I, len: usize) -> Self {
ExactSize { iter, len }
}
}
impl<I: Iterator> Iterator for ExactSize<I> {
type Item = I::Item;
#[inline]
fn next(&mut self) -> Option<I::Item> {
self.iter.next().map(|e| {
self.len -= 1;
e
})
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
(self.len, Some(self.len))
}
}
impl<I: DoubleEndedIterator> DoubleEndedIterator for ExactSize<I> {
#[inline]
fn next_back(&mut self) -> Option<I::Item> {
self.iter.next_back().map(|e| {
self.len -= 1;
e
})
}
}
impl<I: Iterator> ExactSizeIterator for ExactSize<I> {
fn len(&self) -> usize {
self.len
}
}
impl<E: Event> Events<E> {
pub fn send(&mut self, event: E) {
let event_id = EventId {
id: self.event_count,
_marker: PhantomData,
};
trace!("Events::send() -> id: {}", event_id);
let event_instance = EventInstance { event_id, event };
self.events_b.push(event_instance);
self.event_count += 1;
}
pub fn send_default(&mut self)
where
E: Default,
{
self.send(Default::default());
}
pub fn get_reader(&self) -> ManualEventReader<E> {
ManualEventReader::default()
}
pub fn get_reader_current(&self) -> ManualEventReader<E> {
ManualEventReader {
last_event_count: self.event_count,
..Default::default()
}
}
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
);
}
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;
}
#[inline]
pub fn clear(&mut self) {
self.reset_start_event_count();
self.events_a.clear();
self.events_b.clear();
}
#[inline]
pub fn len(&self) -> usize {
self.events_a.len() + self.events_b.len()
}
#[inline]
pub fn is_empty(&self) -> bool {
self.len() == 0
}
pub fn drain(&mut self) -> impl Iterator<Item = E> + '_ {
self.reset_start_event_count();
self.events_a
.drain(..)
.chain(self.events_b.drain(..))
.map(|i| i.event)
}
pub fn iter_current_update_events(
&self,
) -> impl DoubleEndedIterator<Item = &E> + ExactSizeIterator<Item = &E> {
self.events_b.iter().map(|i| &i.event)
}
}
impl<E: Event> std::iter::Extend<E> for Events<E> {
fn extend<I>(&mut self, iter: I)
where
I: IntoIterator<Item = E>,
{
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);
trace!(
"Events::extend() -> ids: ({}..{})",
self.event_count,
event_count
);
self.event_count = event_count;
}
}
#[cfg(test)]
mod tests {
use crate::{prelude::World, system::SystemState};
use super::*;
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
struct TestEvent {
i: usize,
}
#[test]
fn test_events() {
let mut events = Events::<TestEvent>::default();
let event_0 = TestEvent { i: 0 };
let event_1 = TestEvent { i: 1 };
let event_2 = TestEvent { i: 2 };
let mut reader_missed = events.get_reader();
let mut reader_a = events.get_reader();
events.send(event_0);
assert_eq!(
get_events(&events, &mut reader_a),
vec![event_0],
"reader_a created before event receives event"
);
assert_eq!(
get_events(&events, &mut reader_a),
vec![],
"second iteration of reader_a created before event results in zero events"
);
let mut reader_b = events.get_reader();
assert_eq!(
get_events(&events, &mut reader_b),
vec![event_0],
"reader_b created after event receives event"
);
assert_eq!(
get_events(&events, &mut reader_b),
vec![],
"second iteration of reader_b created after event results in zero events"
);
events.send(event_1);
let mut reader_c = events.get_reader();
assert_eq!(
get_events(&events, &mut reader_c),
vec![event_0, event_1],
"reader_c created after two events receives both events"
);
assert_eq!(
get_events(&events, &mut reader_c),
vec![],
"second iteration of reader_c created after two event results in zero events"
);
assert_eq!(
get_events(&events, &mut reader_a),
vec![event_1],
"reader_a receives next unread event"
);
events.update();
let mut reader_d = events.get_reader();
events.send(event_2);
assert_eq!(
get_events(&events, &mut reader_a),
vec![event_2],
"reader_a receives event created after update"
);
assert_eq!(
get_events(&events, &mut reader_b),
vec![event_1, event_2],
"reader_b receives events created before and after update"
);
assert_eq!(
get_events(&events, &mut reader_d),
vec![event_0, event_1, event_2],
"reader_d receives all events created before and after update"
);
events.update();
assert_eq!(
get_events(&events, &mut reader_missed),
vec![event_2],
"reader_missed missed events unread after two update() calls"
);
}
fn get_events<E: Event + Clone>(
events: &Events<E>,
reader: &mut ManualEventReader<E>,
) -> Vec<E> {
reader.iter(events).cloned().collect::<Vec<E>>()
}
#[derive(PartialEq, Eq, Debug)]
struct E(usize);
fn events_clear_and_read_impl(clear_func: impl FnOnce(&mut Events<E>)) {
let mut events = Events::<E>::default();
let mut reader = events.get_reader();
assert!(reader.iter(&events).next().is_none());
events.send(E(0));
assert_eq!(*reader.iter(&events).next().unwrap(), E(0));
assert_eq!(reader.iter(&events).next(), None);
events.send(E(1));
clear_func(&mut events);
assert!(reader.iter(&events).next().is_none());
events.send(E(2));
events.update();
events.send(E(3));
assert!(reader.iter(&events).eq([E(2), E(3)].iter()));
}
#[test]
fn test_events_clear_and_read() {
events_clear_and_read_impl(|events| events.clear());
}
#[test]
fn test_events_drain_and_read() {
events_clear_and_read_impl(|events| {
assert!(events.drain().eq(vec![E(0), E(1)].into_iter()));
});
}
#[test]
fn test_events_extend_impl() {
let mut events = Events::<TestEvent>::default();
let mut reader = events.get_reader();
events.extend(vec![TestEvent { i: 0 }, TestEvent { i: 1 }]);
assert!(reader
.iter(&events)
.eq([TestEvent { i: 0 }, TestEvent { i: 1 }].iter()));
}
#[test]
fn test_events_empty() {
let mut events = Events::<TestEvent>::default();
assert!(events.is_empty());
events.send(TestEvent { i: 0 });
assert!(!events.is_empty());
events.update();
assert!(!events.is_empty());
events.update();
assert!(events.is_empty());
}
#[test]
fn test_event_reader_len_empty() {
let events = Events::<TestEvent>::default();
assert_eq!(events.get_reader().len(&events), 0);
assert!(events.get_reader().is_empty(&events));
}
#[test]
fn test_event_reader_len_filled() {
let mut events = Events::<TestEvent>::default();
events.send(TestEvent { i: 0 });
assert_eq!(events.get_reader().len(&events), 1);
assert!(!events.get_reader().is_empty(&events));
}
#[test]
fn test_event_iter_len_updated() {
let mut events = Events::<TestEvent>::default();
events.send(TestEvent { i: 0 });
events.send(TestEvent { i: 1 });
events.send(TestEvent { i: 2 });
let mut reader = events.get_reader();
let mut iter = reader.iter(&events);
assert_eq!(iter.len(), 3);
iter.next();
assert_eq!(iter.len(), 2);
iter.next_back();
assert_eq!(iter.len(), 1);
}
#[test]
fn test_event_reader_len_current() {
let mut events = Events::<TestEvent>::default();
events.send(TestEvent { i: 0 });
let reader = events.get_reader_current();
dbg!(&reader);
dbg!(&events);
assert!(reader.is_empty(&events));
events.send(TestEvent { i: 0 });
assert_eq!(reader.len(&events), 1);
assert!(!reader.is_empty(&events));
}
#[test]
fn test_event_reader_len_update() {
let mut events = Events::<TestEvent>::default();
events.send(TestEvent { i: 0 });
events.send(TestEvent { i: 0 });
let reader = events.get_reader();
assert_eq!(reader.len(&events), 2);
events.update();
events.send(TestEvent { i: 0 });
assert_eq!(reader.len(&events), 3);
events.update();
assert_eq!(reader.len(&events), 1);
events.update();
assert!(reader.is_empty(&events));
}
#[test]
fn test_event_reader_clear() {
use bevy_ecs::prelude::*;
let mut world = World::new();
let mut events = Events::<TestEvent>::default();
events.send(TestEvent { i: 0 });
world.insert_resource(events);
let mut reader = IntoSystem::into_system(|events: EventReader<TestEvent>| -> bool {
if !events.is_empty() {
events.clear();
false
} else {
true
}
});
reader.initialize(&mut world);
let is_empty = reader.run((), &mut world);
assert!(!is_empty, "EventReader should not be empty");
let is_empty = reader.run((), &mut world);
assert!(is_empty, "EventReader should be empty");
}
#[derive(Clone, PartialEq, Debug, Default)]
struct EmptyTestEvent;
#[test]
fn test_firing_empty_event() {
let mut events = Events::<EmptyTestEvent>::default();
events.send_default();
let mut reader = events.get_reader();
assert_eq!(
get_events(&events, &mut reader),
vec![EmptyTestEvent::default()]
);
}
#[test]
fn ensure_reader_readonly() {
fn read_for<E: Event>() {
let mut world = World::new();
world.init_resource::<Events<E>>();
let mut state = SystemState::<EventReader<E>>::new(&mut world);
let _reader = state.get(&world);
}
read_for::<EmptyTestEvent>();
}
}