@@ -4,8 +4,7 @@ use crate as bevy_ecs;
4
4
use crate :: system:: { Local , Res , ResMut , Resource , SystemParam } ;
5
5
use bevy_utils:: tracing:: trace;
6
6
use std:: ops:: { Deref , DerefMut } ;
7
- use std:: { fmt, hash:: Hash , marker:: PhantomData } ;
8
-
7
+ use std:: { fmt, hash:: Hash , iter:: Chain , marker:: PhantomData , slice:: Iter } ;
9
8
/// A type that can be stored in an [`Events<E>`] resource
10
9
/// You can conveniently access events using the [`EventReader`] and [`EventWriter`] system parameter.
11
10
///
@@ -194,18 +193,13 @@ impl<'w, 's, E: Event> EventReader<'w, 's, E> {
194
193
/// Iterates over the events this [`EventReader`] has not seen yet. This updates the
195
194
/// [`EventReader`]'s event counter, which means subsequent event reads will not include events
196
195
/// that happened before now.
197
- pub fn iter ( & mut self ) -> impl DoubleEndedIterator < Item = & E > + ExactSizeIterator < Item = & E > {
198
- self . iter_with_id ( ) . map ( | ( event , _id ) | event )
196
+ pub fn iter ( & mut self ) -> ManualEventIterator < ' _ , E > {
197
+ self . reader . iter ( & self . events )
199
198
}
200
199
201
200
/// Like [`iter`](Self::iter), except also returning the [`EventId`] of the events.
202
- pub fn iter_with_id (
203
- & mut self ,
204
- ) -> impl DoubleEndedIterator < Item = ( & E , EventId < E > ) > + ExactSizeIterator < Item = ( & E , EventId < E > ) >
205
- {
206
- self . reader . iter_with_id ( & self . events ) . inspect ( |( _, id) | {
207
- trace ! ( "EventReader::iter() -> {}" , id) ;
208
- } )
201
+ pub fn iter_with_id ( & mut self ) -> ManualEventIteratorWithId < ' _ , E > {
202
+ self . reader . iter_with_id ( & self . events )
209
203
}
210
204
211
205
/// Determines the number of events available to be read from this [`EventReader`] without consuming any.
@@ -337,34 +331,16 @@ impl<E: Event> Default for ManualEventReader<E> {
337
331
#[ allow( clippy:: len_without_is_empty) ] // Check fails since the is_empty implementation has a signature other than `(&self) -> bool`
338
332
impl < E : Event > ManualEventReader < E > {
339
333
/// See [`EventReader::iter`]
340
- pub fn iter < ' a > (
341
- & ' a mut self ,
342
- events : & ' a Events < E > ,
343
- ) -> impl DoubleEndedIterator < Item = & ' a E > + ExactSizeIterator < Item = & ' a E > {
344
- self . iter_with_id ( events) . map ( |( e, _) | e)
334
+ pub fn iter < ' a > ( & ' a mut self , events : & ' a Events < E > ) -> ManualEventIterator < ' a , E > {
335
+ self . iter_with_id ( events) . without_id ( )
345
336
}
346
337
347
338
/// See [`EventReader::iter_with_id`]
348
339
pub fn iter_with_id < ' a > (
349
340
& ' a mut self ,
350
341
events : & ' a Events < E > ,
351
- ) -> impl DoubleEndedIterator < Item = ( & ' a E , EventId < E > ) >
352
- + ExactSizeIterator < Item = ( & ' a E , EventId < E > ) > {
353
- let a_index = ( self . last_event_count ) . saturating_sub ( events. events_a . start_event_count ) ;
354
- let b_index = ( self . last_event_count ) . saturating_sub ( events. events_b . start_event_count ) ;
355
- let a = events. events_a . get ( a_index..) . unwrap_or_default ( ) ;
356
- let b = events. events_b . get ( b_index..) . unwrap_or_default ( ) ;
357
-
358
- let unread_count = a. len ( ) + b. len ( ) ;
359
- // Ensure `len` is implemented correctly
360
- debug_assert_eq ! ( unread_count, self . len( events) ) ;
361
- self . last_event_count = events. event_count - unread_count;
362
- // Iterate the oldest first, then the newer events
363
- let iterator = a. iter ( ) . chain ( b. iter ( ) ) ;
364
- iterator
365
- . map ( |e| ( & e. event , e. event_id ) )
366
- . with_exact_size ( unread_count)
367
- . inspect ( move |( _, id) | self . last_event_count = ( id. id + 1 ) . max ( self . last_event_count ) )
342
+ ) -> ManualEventIteratorWithId < ' a , E > {
343
+ ManualEventIteratorWithId :: new ( self , events)
368
344
}
369
345
370
346
/// See [`EventReader::len`]
@@ -392,57 +368,114 @@ impl<E: Event> ManualEventReader<E> {
392
368
}
393
369
}
394
370
395
- trait IteratorExt {
396
- fn with_exact_size ( self , len : usize ) -> ExactSize < Self >
397
- where
398
- Self : Sized ,
399
- {
400
- ExactSize :: new ( self , len)
371
+ pub struct ManualEventIterator < ' a , E : Event > {
372
+ iter : ManualEventIteratorWithId < ' a , E > ,
373
+ }
374
+
375
+ impl < ' a , E : Event > Iterator for ManualEventIterator < ' a , E > {
376
+ type Item = & ' a E ;
377
+ fn next ( & mut self ) -> Option < Self :: Item > {
378
+ self . iter . next ( ) . map ( |( event, _) | event)
379
+ }
380
+
381
+ fn size_hint ( & self ) -> ( usize , Option < usize > ) {
382
+ self . iter . size_hint ( )
401
383
}
402
384
}
403
- impl < I > IteratorExt for I where I : Iterator { }
404
385
405
- #[ must_use = "iterators are lazy and do nothing unless consumed" ]
406
- #[ derive( Clone ) ]
407
- struct ExactSize < I > {
408
- iter : I ,
409
- len : usize ,
386
+ impl < ' a , E : Event > ExactSizeIterator for ManualEventIterator < ' a , E > {
387
+ fn len ( & self ) -> usize {
388
+ self . iter . len ( )
389
+ }
410
390
}
411
- impl < I > ExactSize < I > {
412
- fn new ( iter : I , len : usize ) -> Self {
413
- ExactSize { iter, len }
391
+
392
+ impl < ' a , E : Event > DoubleEndedIterator for ManualEventIterator < ' a , E > {
393
+ fn next_back ( & mut self ) -> Option < Self :: Item > {
394
+ self . iter . next_back ( ) . map ( |( event, _) | event)
414
395
}
415
396
}
416
397
417
- impl < I : Iterator > Iterator for ExactSize < I > {
418
- type Item = I :: Item ;
398
+ #[ derive( Debug ) ]
399
+ pub struct ManualEventIteratorWithId < ' a , E : Event > {
400
+ reader : & ' a mut ManualEventReader < E > ,
401
+ chain : Chain < Iter < ' a , EventInstance < E > > , Iter < ' a , EventInstance < E > > > ,
402
+ unread : usize ,
403
+ }
404
+
405
+ fn event_trace < E : Event > ( id : EventId < E > ) {
406
+ trace ! ( "EventReader::iter() -> {}" , id) ;
407
+ }
419
408
420
- #[ inline]
421
- fn next ( & mut self ) -> Option < I :: Item > {
422
- self . iter . next ( ) . map ( |e| {
423
- self . len -= 1 ;
424
- e
425
- } )
409
+ impl < ' a , E : Event > ManualEventIteratorWithId < ' a , E > {
410
+ pub fn new ( reader : & ' a mut ManualEventReader < E > , events : & ' a Events < E > ) -> Self {
411
+ let a_index = ( reader. last_event_count ) . saturating_sub ( events. events_a . start_event_count ) ;
412
+ let b_index = ( reader. last_event_count ) . saturating_sub ( events. events_b . start_event_count ) ;
413
+ let a = events. events_a . get ( a_index..) . unwrap_or_default ( ) ;
414
+ let b = events. events_b . get ( b_index..) . unwrap_or_default ( ) ;
415
+
416
+ let unread_count = a. len ( ) + b. len ( ) ;
417
+ // Ensure `len` is implemented correctly
418
+ debug_assert_eq ! ( unread_count, reader. len( events) ) ;
419
+ reader. last_event_count = events. event_count - unread_count;
420
+ // Iterate the oldest first, then the newer events
421
+ let chain = a. iter ( ) . chain ( b. iter ( ) ) ;
422
+
423
+ Self {
424
+ reader,
425
+ chain,
426
+ unread : unread_count,
427
+ }
428
+ }
429
+
430
+ /// Iterate over only the events.
431
+ pub fn without_id ( self ) -> ManualEventIterator < ' a , E > {
432
+ ManualEventIterator { iter : self }
433
+ }
434
+ }
435
+
436
+ impl < ' a , E : Event > Iterator for ManualEventIteratorWithId < ' a , E > {
437
+ type Item = ( & ' a E , EventId < E > ) ;
438
+ fn next ( & mut self ) -> Option < Self :: Item > {
439
+ match self
440
+ . chain
441
+ . next ( )
442
+ . map ( |instance| ( & instance. event , instance. event_id ) )
443
+ {
444
+ Some ( item) => {
445
+ event_trace ( item. 1 ) ;
446
+ self . reader . last_event_count += 1 ;
447
+ self . unread -= 1 ;
448
+ Some ( item)
449
+ }
450
+ None => None ,
451
+ }
426
452
}
427
453
428
- #[ inline]
429
454
fn size_hint ( & self ) -> ( usize , Option < usize > ) {
430
- ( self . len , Some ( self . len ) )
455
+ self . chain . size_hint ( )
431
456
}
432
457
}
433
458
434
- impl < I : DoubleEndedIterator > DoubleEndedIterator for ExactSize < I > {
435
- #[ inline]
436
- fn next_back ( & mut self ) -> Option < I :: Item > {
437
- self . iter . next_back ( ) . map ( |e| {
438
- self . len -= 1 ;
439
- e
440
- } )
459
+ impl < ' a , E : Event > DoubleEndedIterator for ManualEventIteratorWithId < ' a , E > {
460
+ fn next_back ( & mut self ) -> Option < Self :: Item > {
461
+ match self
462
+ . chain
463
+ . next_back ( )
464
+ . map ( |instance| ( & instance. event , instance. event_id ) )
465
+ {
466
+ Some ( item) => {
467
+ event_trace ( item. 1 ) ;
468
+ self . unread -= 1 ;
469
+ Some ( item)
470
+ }
471
+ None => None ,
472
+ }
441
473
}
442
474
}
443
- impl < I : Iterator > ExactSizeIterator for ExactSize < I > {
475
+
476
+ impl < ' a , E : Event > ExactSizeIterator for ManualEventIteratorWithId < ' a , E > {
444
477
fn len ( & self ) -> usize {
445
- self . len
478
+ self . unread
446
479
}
447
480
}
448
481
@@ -548,6 +581,34 @@ impl<E: Event> Events<E> {
548
581
) -> impl DoubleEndedIterator < Item = & E > + ExactSizeIterator < Item = & E > {
549
582
self . events_b . iter ( ) . map ( |i| & i. event )
550
583
}
584
+
585
+ /// Get a specific event by id if it still exists in the events buffer.
586
+ pub fn get_event ( & self , id : usize ) -> Option < ( & E , EventId < E > ) > {
587
+ if id < self . oldest_id ( ) {
588
+ return None ;
589
+ }
590
+
591
+ let sequence = self . sequence ( id) ;
592
+ let index = id. saturating_sub ( sequence. start_event_count ) ;
593
+
594
+ sequence
595
+ . get ( index)
596
+ . map ( |instance| ( & instance. event , instance. event_id ) )
597
+ }
598
+
599
+ /// Oldest id still in the events buffer.
600
+ pub fn oldest_id ( & self ) -> usize {
601
+ self . events_a . start_event_count
602
+ }
603
+
604
+ /// Which event buffer is this event id a part of.
605
+ fn sequence ( & self , id : usize ) -> & EventSequence < E > {
606
+ if id < self . events_b . start_event_count {
607
+ & self . events_a
608
+ } else {
609
+ & self . events_b
610
+ }
611
+ }
551
612
}
552
613
553
614
impl < E : Event > std:: iter:: Extend < E > for Events < E > {
0 commit comments