Implement len and is_empty for EventReaders (#2969)
# Objective Provide a non-consuming method of checking if there are events in an `EventReader`. Fixes #2967 ## Solution Implements the `len` and `is_empty` functions for `EventReader` and `ManualEventReader`, giving users the ability to check for the presence of new events without consuming any. Co-authored-by: Carter Anderson <mcanders1@gmail.com>
This commit is contained in:
parent
af22cc1dc3
commit
c216738b33
@ -192,7 +192,8 @@ impl<T> Default for ManualEventReader<T> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> ManualEventReader<T> {
|
||||
#[allow(clippy::len_without_is_empty)] // Check fails since the is_empty implementation has a signature other than `(&self) -> bool`
|
||||
impl<T: Resource> ManualEventReader<T> {
|
||||
/// See [`EventReader::iter`]
|
||||
pub fn iter<'a>(&'a mut self, events: &'a Events<T>) -> impl DoubleEndedIterator<Item = &'a T> {
|
||||
internal_event_reader(&mut self.last_event_count, events).map(|(e, _)| e)
|
||||
@ -205,6 +206,16 @@ impl<T> ManualEventReader<T> {
|
||||
) -> impl DoubleEndedIterator<Item = (&'a T, EventId<T>)> {
|
||||
internal_event_reader(&mut self.last_event_count, events)
|
||||
}
|
||||
|
||||
/// See [`EventReader::len`]
|
||||
pub fn len(&self, events: &Events<T>) -> usize {
|
||||
events.event_reader_len(self.last_event_count)
|
||||
}
|
||||
|
||||
/// See [`EventReader::is_empty`]
|
||||
pub fn is_empty(&self, events: &Events<T>) -> bool {
|
||||
self.len(events) == 0
|
||||
}
|
||||
}
|
||||
|
||||
/// Like [`iter_with_id`](EventReader::iter_with_id) except not emitting any traces for read
|
||||
@ -253,6 +264,16 @@ impl<'w, 's, T: Resource> EventReader<'w, 's, T> {
|
||||
(event, id)
|
||||
})
|
||||
}
|
||||
|
||||
/// Determines the number of events available to be read from this [`EventReader`] without consuming any.
|
||||
pub fn len(&self) -> usize {
|
||||
self.events.event_reader_len(self.last_event_count.0)
|
||||
}
|
||||
|
||||
/// Determines if are any events available to be read without consuming any.
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.len() == 0
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Resource> Events<T> {
|
||||
@ -355,7 +376,7 @@ impl<T: Resource> Events<T> {
|
||||
|
||||
/// 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
|
||||
/// [`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.
|
||||
@ -365,6 +386,29 @@ impl<T: Resource> Events<T> {
|
||||
State::B => self.events_b.iter().map(map_instance_event),
|
||||
}
|
||||
}
|
||||
|
||||
/// Determines how many events are in the reader after the given `last_event_count` parameter
|
||||
fn event_reader_len(&self, last_event_count: usize) -> usize {
|
||||
let a_count = if last_event_count <= self.a_start_event_count {
|
||||
self.events_a.len()
|
||||
} else {
|
||||
self.events_a
|
||||
.len()
|
||||
.checked_sub(last_event_count - self.a_start_event_count)
|
||||
.unwrap_or_default()
|
||||
};
|
||||
|
||||
let b_count = if last_event_count <= self.b_start_event_count {
|
||||
self.events_b.len()
|
||||
} else {
|
||||
self.events_b
|
||||
.len()
|
||||
.checked_sub(last_event_count - self.b_start_event_count)
|
||||
.unwrap_or_default()
|
||||
};
|
||||
|
||||
a_count + b_count
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> std::iter::Extend<T> for Events<T> {
|
||||
@ -566,4 +610,46 @@ mod tests {
|
||||
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_reader_len_current() {
|
||||
let mut events = Events::<TestEvent>::default();
|
||||
events.send(TestEvent { i: 0 });
|
||||
let reader = events.get_reader_current();
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user