2020-07-10 04:18:35 +00:00
use bevy_ecs ::ResMut ;
2020-03-30 05:44:38 +00:00
use std ::marker ::PhantomData ;
2020-06-04 06:22:32 +00:00
#[ derive(Debug) ]
2020-03-30 05:44:38 +00:00
struct EventInstance < T > {
pub event_count : usize ,
pub event : T ,
}
2020-06-04 06:22:32 +00:00
#[ derive(Debug) ]
2020-03-30 05:44:38 +00:00
enum State {
A ,
B ,
}
2020-04-01 01:04:54 +00:00
/// An event collection that represents the events that occurred within the last two [Events::update] calls. Events can be cheaply read using
2020-04-30 23:19:28 +00:00
/// an [EventReader]. This collection is meant to be paired with a system that calls [Events::update] exactly once per update/frame. [Events::update_system]
/// is a system that does this. [EventReader]s are expected to read events from this collection at least once per update/frame. If events are not handled
2020-04-01 01:04:54 +00:00
/// within one frame/update, they will be dropped.
///
/// # Example
/// ```
2020-04-19 20:23:19 +00:00
/// use bevy_app::Events;
2020-04-04 19:43:16 +00:00
///
2020-04-01 01:04:54 +00:00
/// struct MyEvent {
/// value: usize
/// }
///
/// // setup
/// let mut events = Events::<MyEvent>::default();
/// let mut reader = events.get_reader();
///
/// // run this once per update/frame
/// events.update();
///
/// // somewhere else: send an event
/// events.send(MyEvent { value: 1 });
///
/// // somewhere else: read the events
2020-04-28 17:59:42 +00:00
/// for event in reader.iter(&events) {
2020-04-01 01:04:54 +00:00
/// assert_eq!(event.value, 1)
/// }
///
/// // events are only processed once per reader
2020-04-28 17:59:42 +00:00
/// assert_eq!(reader.iter(&events).count(), 0);
2020-04-01 01:04:54 +00:00
/// ```
///
/// # Details
///
/// [Events] is implemented using a double buffer. Each call to [Events::update] swaps buffers and clears out the oldest buffer.
/// [EventReader]s that read at least once per update will never drop events. [EventReader]s that read once within two updates might
/// still receive some events. [EventReader]s that read after two updates are guaranteed to drop all events that occurred before those updates.
///
/// The buffers in [Events] will grow indefinitely if [Events::update] is never called.
///
/// An alternative call pattern would be to call [Events::update] manually across frames to control when events are cleared. However
/// this complicates consumption
2020-06-04 06:22:32 +00:00
#[ derive(Debug) ]
2020-05-13 23:17:06 +00:00
pub struct Events < T > {
2020-03-30 05:44:38 +00:00
events_a : Vec < EventInstance < T > > ,
events_b : Vec < EventInstance < T > > ,
a_start_event_count : usize ,
b_start_event_count : usize ,
event_count : usize ,
state : State ,
}
2020-05-13 23:17:06 +00:00
impl < T > Default for Events < T > {
2020-03-30 05:44:38 +00:00
fn default ( ) -> Self {
2020-04-01 01:04:54 +00:00
Events {
2020-03-30 05:44:38 +00:00
a_start_event_count : 0 ,
b_start_event_count : 0 ,
event_count : 0 ,
events_a : Vec ::new ( ) ,
events_b : Vec ::new ( ) ,
state : State ::A ,
}
}
}
2020-06-17 05:20:08 +00:00
fn map_instance_event < T > ( event_instance : & EventInstance < T > ) -> & T {
2020-03-30 05:44:38 +00:00
& event_instance . event
}
2020-08-16 03:27:41 +00:00
/// Reads events of type `T` in order and tracks which events have already been read.
2020-04-01 01:04:54 +00:00
pub struct EventReader < T > {
2020-03-30 05:44:38 +00:00
last_event_count : usize ,
_marker : PhantomData < T > ,
}
2020-06-04 06:53:00 +00:00
impl < T > Default for EventReader < T > {
fn default ( ) -> Self {
Self {
last_event_count : 0 ,
_marker : PhantomData ::default ( ) ,
}
}
}
2020-05-13 23:17:06 +00:00
impl < T > EventReader < T > {
2020-04-28 17:59:42 +00:00
/// Iterates over the events this EventReader has not seen yet. This updates the EventReader's
/// event counter, which means subsequent event reads will not include events that happened before now.
pub fn iter < ' a > ( & mut self , events : & ' a Events < T > ) -> impl DoubleEndedIterator < Item = & ' a T > {
2020-04-01 01:04:54 +00:00
// if the reader has seen some of the events in a buffer, find the proper index offset.
// otherwise read all events in the buffer
2020-04-28 17:59:42 +00:00
let a_index = if self . last_event_count > events . a_start_event_count {
self . last_event_count - events . a_start_event_count
2020-04-01 01:04:54 +00:00
} else {
0
} ;
2020-04-28 17:59:42 +00:00
let b_index = if self . last_event_count > events . b_start_event_count {
self . last_event_count - events . b_start_event_count
2020-04-01 01:04:54 +00:00
} else {
0
} ;
2020-04-28 17:59:42 +00:00
self . last_event_count = events . event_count ;
match events . state {
State ::A = > events
2020-03-30 05:44:38 +00:00
. events_b
. get ( b_index .. )
. unwrap_or_else ( | | & [ ] )
. iter ( )
2020-06-17 05:20:08 +00:00
. map ( map_instance_event )
2020-03-30 05:44:38 +00:00
. chain (
2020-04-28 17:59:42 +00:00
events
. events_a
2020-03-30 05:44:38 +00:00
. get ( a_index .. )
. unwrap_or_else ( | | & [ ] )
. iter ( )
2020-06-17 05:20:08 +00:00
. map ( map_instance_event ) ,
2020-03-30 05:44:38 +00:00
) ,
2020-04-28 17:59:42 +00:00
State ::B = > events
2020-03-30 05:44:38 +00:00
. events_a
. get ( a_index .. )
. unwrap_or_else ( | | & [ ] )
. iter ( )
2020-06-17 05:20:08 +00:00
. map ( map_instance_event )
2020-03-30 05:44:38 +00:00
. chain (
2020-04-28 17:59:42 +00:00
events
. events_b
2020-03-30 05:44:38 +00:00
. get ( b_index .. )
. unwrap_or_else ( | | & [ ] )
. iter ( )
2020-06-17 05:20:08 +00:00
. map ( map_instance_event ) ,
2020-03-30 05:44:38 +00:00
) ,
}
}
2020-04-28 17:59:42 +00:00
/// Retrieves the latest event that this EventReader hasn't seen yet. This updates the EventReader's
/// event counter, which means subsequent event reads will not include events that happened before now.
pub fn latest < ' a > ( & mut self , events : & ' a Events < T > ) -> Option < & ' a T > {
self . iter ( events ) . rev ( ) . next ( )
2020-04-16 18:16:22 +00:00
}
2020-04-28 17:59:42 +00:00
/// Retrieves the latest event that matches the given `predicate` that this reader hasn't seen yet. This updates the EventReader's
/// event counter, which means subsequent event reads will not include events that happened before now.
pub fn find_latest < ' a > (
& mut self ,
events : & ' a Events < T > ,
2020-04-25 01:55:15 +00:00
predicate : impl FnMut ( & & T ) -> bool ,
2020-04-28 17:59:42 +00:00
) -> Option < & ' a T > {
self . iter ( events ) . rev ( ) . filter ( predicate ) . next ( )
2020-04-16 18:16:22 +00:00
}
2020-04-28 17:59:42 +00:00
/// Retrieves the earliest event in `events` that this reader hasn't seen yet. This updates the EventReader's
/// event counter, which means subsequent event reads will not include events that happened before now.
pub fn earliest < ' a > ( & mut self , events : & ' a Events < T > ) -> Option < & ' a T > {
self . iter ( events ) . next ( )
}
}
2020-07-10 04:18:35 +00:00
impl < T : bevy_ecs ::Resource > Events < T > {
2020-04-28 17:59:42 +00:00
/// "Sends" an `event` by writing it to the current event buffer. [EventReader]s can then read the event.
pub fn send ( & mut self , event : T ) {
let event_instance = EventInstance {
event ,
event_count : self . event_count ,
} ;
match self . state {
State ::A = > self . events_a . push ( event_instance ) ,
State ::B = > self . events_b . push ( event_instance ) ,
}
self . event_count + = 1 ;
2020-04-16 18:16:22 +00:00
}
2020-04-01 01:04:54 +00:00
/// Gets a new [EventReader]. This will include all events already in the event buffers.
pub fn get_reader ( & self ) -> EventReader < T > {
EventReader {
2020-03-30 21:53:32 +00:00
last_event_count : 0 ,
2020-03-30 05:44:38 +00:00
_marker : PhantomData ,
}
}
2020-04-01 01:04:54 +00:00
/// Gets a new [EventReader]. This will ignore all events already in the event buffers. It will read all future events.
pub fn get_reader_current ( & self ) -> EventReader < T > {
EventReader {
last_event_count : self . event_count ,
_marker : PhantomData ,
}
}
/// Swaps the event buffers and clears the oldest event buffer. In general, this should be called once per frame/update.
2020-03-30 05:44:38 +00:00
pub fn update ( & mut self ) {
match self . state {
State ::A = > {
self . events_b = Vec ::new ( ) ;
self . state = State ::B ;
self . b_start_event_count = self . event_count ;
}
State ::B = > {
self . events_a = Vec ::new ( ) ;
self . state = State ::A ;
self . a_start_event_count = self . event_count ;
}
}
}
2020-04-30 23:19:28 +00:00
/// A system that calls [Events::update] once per frame.
2020-05-14 00:52:47 +00:00
pub fn update_system ( mut events : ResMut < Self > ) {
2020-04-30 23:19:28 +00:00
events . update ( ) ;
2020-03-30 05:44:38 +00:00
}
2020-05-13 23:17:06 +00:00
/// Removes all events.
pub fn clear ( & mut self ) {
self . events_a . clear ( ) ;
self . events_b . clear ( ) ;
}
/// Creates a draining iterator that removes all events.
pub fn drain < ' a > ( & ' a mut self ) -> impl Iterator < Item = T > + ' a {
let map = | i : EventInstance < T > | i . event ;
match self . state {
State ::A = > self
. events_b
. drain ( .. )
. map ( map )
. chain ( self . events_a . drain ( .. ) . map ( map ) ) ,
State ::B = > self
. events_a
. drain ( .. )
. map ( map )
. chain ( self . events_b . drain ( .. ) . map ( map ) ) ,
}
}
2020-05-14 01:05:18 +00:00
pub fn extend < I > ( & mut self , events : I )
where
I : Iterator < Item = T > ,
{
2020-05-13 23:17:06 +00:00
for event in events {
self . send ( event ) ;
}
}
2020-06-17 05:20:08 +00:00
/// Iterates over events that happened since the last "update" call.
2020-07-10 04:18:35 +00:00
/// WARNING: You probably don't want to use this call. In most cases you should use an `EventReader`. You should only use
2020-06-17 05:20:08 +00:00
/// 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 DoubleEndedIterator < Item = & T > {
match self . state {
State ::A = > self . events_a . iter ( ) . map ( map_instance_event ) ,
State ::B = > self . events_b . iter ( ) . map ( map_instance_event ) ,
}
}
2020-03-30 05:44:38 +00:00
}
2020-03-30 21:53:32 +00:00
2020-04-01 01:04:54 +00:00
#[ cfg(test) ]
mod tests {
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 } ;
// this reader will miss event_0 and event_1 because it wont read them over the course of two updates
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 to update() calls "
) ;
}
fn get_events (
events : & Events < TestEvent > ,
reader : & mut EventReader < TestEvent > ,
) -> Vec < TestEvent > {
2020-04-28 17:59:42 +00:00
reader . iter ( events ) . cloned ( ) . collect ::< Vec < TestEvent > > ( )
2020-03-30 21:53:32 +00:00
}
}