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`]
|
/// See [`EventReader::iter`]
|
||||||
pub fn iter<'a>(&'a mut self, events: &'a Events<T>) -> impl DoubleEndedIterator<Item = &'a T> {
|
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)
|
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>)> {
|
) -> impl DoubleEndedIterator<Item = (&'a T, EventId<T>)> {
|
||||||
internal_event_reader(&mut self.last_event_count, events)
|
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
|
/// 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)
|
(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> {
|
impl<T: Resource> Events<T> {
|
||||||
@ -355,7 +376,7 @@ impl<T: Resource> Events<T> {
|
|||||||
|
|
||||||
/// Iterates over events that happened since the last "update" call.
|
/// 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
|
/// 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`.
|
/// 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
|
/// 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.
|
/// 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),
|
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> {
|
impl<T> std::iter::Extend<T> for Events<T> {
|
||||||
@ -566,4 +610,46 @@ mod tests {
|
|||||||
events.update();
|
events.update();
|
||||||
assert!(events.is_empty());
|
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