Skip to content

Commit ab2ac3a

Browse files
committed
Remove broken DoubleEndedIterator impls on event iterators (#7469)
The `DoubleEndedIterator` impls produce incorrect results on subsequent calls to `iter()` if the iterator is only partially consumed. The following code shows what happens ```rust fn next_back_is_bad() { 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.next_back(), Some(&TestEvent { i: 2 })); assert_eq!(iter.next(), Some(&TestEvent { i: 0 })); let mut iter = reader.iter(&events); // `i: 2` event is returned twice! The `i: 1` event is missed. assert_eq!(iter.next(), Some(&TestEvent { i: 2 })); assert_eq!(iter.next(), None); } ``` I don't think this can be fixed without adding some very convoluted bookkeeping. ## Migration Guide `ManualEventIterator` and `ManualEventIteratorWithId` are no longer `DoubleEndedIterator`s. Co-authored-by: devil-ira <justthecooldude@gmail.com>
1 parent 5ee57ff commit ab2ac3a

File tree

2 files changed

+6
-28
lines changed

2 files changed

+6
-28
lines changed

crates/bevy_ecs/src/event.rs

+4-27
Original file line numberDiff line numberDiff line change
@@ -390,12 +390,6 @@ impl<'a, E: Event> ExactSizeIterator for ManualEventIterator<'a, E> {
390390
}
391391
}
392392

393-
impl<'a, E: Event> DoubleEndedIterator for ManualEventIterator<'a, E> {
394-
fn next_back(&mut self) -> Option<Self::Item> {
395-
self.iter.next_back().map(|(event, _)| event)
396-
}
397-
}
398-
399393
#[derive(Debug)]
400394
pub struct ManualEventIteratorWithId<'a, E: Event> {
401395
reader: &'a mut ManualEventReader<E>,
@@ -457,23 +451,6 @@ impl<'a, E: Event> Iterator for ManualEventIteratorWithId<'a, E> {
457451
}
458452
}
459453

460-
impl<'a, E: Event> DoubleEndedIterator for ManualEventIteratorWithId<'a, E> {
461-
fn next_back(&mut self) -> Option<Self::Item> {
462-
match self
463-
.chain
464-
.next_back()
465-
.map(|instance| (&instance.event, instance.event_id))
466-
{
467-
Some(item) => {
468-
event_trace(item.1);
469-
self.unread -= 1;
470-
Some(item)
471-
}
472-
None => None,
473-
}
474-
}
475-
}
476-
477454
impl<'a, E: Event> ExactSizeIterator for ManualEventIteratorWithId<'a, E> {
478455
fn len(&self) -> usize {
479456
self.unread
@@ -577,9 +554,7 @@ impl<E: Event> Events<E> {
577554
/// between the last `update()` call and your call to `iter_current_update_events`.
578555
/// If events happen outside that window, they will not be handled. For example, any events that
579556
/// happen after this call and before the next `update()` call will be dropped.
580-
pub fn iter_current_update_events(
581-
&self,
582-
) -> impl DoubleEndedIterator<Item = &E> + ExactSizeIterator<Item = &E> {
557+
pub fn iter_current_update_events(&self) -> impl ExactSizeIterator<Item = &E> {
583558
self.events_b.iter().map(|i| &i.event)
584559
}
585560

@@ -837,8 +812,10 @@ mod tests {
837812
assert_eq!(iter.len(), 3);
838813
iter.next();
839814
assert_eq!(iter.len(), 2);
840-
iter.next_back();
815+
iter.next();
841816
assert_eq!(iter.len(), 1);
817+
iter.next();
818+
assert_eq!(iter.len(), 0);
842819
}
843820

844821
#[test]

crates/bevy_ui/src/flex/mod.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -270,7 +270,8 @@ pub fn flex_node_system(
270270
}
271271
}
272272

273-
if scale_factor_events.iter().next_back().is_some() || ui_scale.is_changed() {
273+
if !scale_factor_events.is_empty() || ui_scale.is_changed() {
274+
scale_factor_events.clear();
274275
update_changed(&mut flex_surface, scale_factor, full_node_query);
275276
} else {
276277
update_changed(&mut flex_surface, scale_factor, node_query);

0 commit comments

Comments
 (0)