@@ -14,7 +14,7 @@ use bevy_tasks::{ComputeTaskPool, TaskPool};
14
14
#[ cfg( feature = "trace" ) ]
15
15
use bevy_utils:: tracing:: Instrument ;
16
16
use fixedbitset:: FixedBitSet ;
17
- use std:: { fmt, ops:: Deref } ;
17
+ use std:: { borrow :: Borrow , fmt, ops:: Deref } ;
18
18
19
19
use super :: { QueryFetch , QueryItem , ROQueryFetch , ROQueryItem } ;
20
20
@@ -693,6 +693,93 @@ impl<Q: WorldQuery, F: WorldQuery> QueryState<Q, F> {
693
693
) ;
694
694
}
695
695
696
+ /// Runs `func` on each query result for the given [`World`]. This is faster than the equivalent
697
+ /// iter() method, but cannot be chained like a normal [`Iterator`].
698
+ ///
699
+ /// This can only be called for read-only queries, see [`Self::for_each_mut`] for write-queries.
700
+ #[ inline]
701
+ pub fn many_for_each <
702
+ ' w ,
703
+ E : Borrow < Entity > ,
704
+ EntityList : IntoIterator < Item = E > ,
705
+ FN : FnMut ( ROQueryItem < ' w , Q > ) ,
706
+ > (
707
+ & mut self ,
708
+ world : & ' w World ,
709
+ entities : EntityList ,
710
+ func : FN ,
711
+ ) {
712
+ // SAFETY: query is read only
713
+ unsafe {
714
+ self . update_archetypes ( world) ;
715
+ self . many_for_each_unchecked_manual :: < ROQueryFetch < Q > , E , EntityList , FN > (
716
+ world,
717
+ entities,
718
+ func,
719
+ world. last_change_tick ( ) ,
720
+ world. read_change_tick ( ) ,
721
+ ) ;
722
+ }
723
+ }
724
+
725
+ /// Runs `func` on each query result for the given [`World`]. This is faster than the equivalent
726
+ /// `iter_mut()` method, but cannot be chained like a normal [`Iterator`].
727
+ #[ inline]
728
+ pub fn many_for_each_mut <
729
+ ' w ,
730
+ E : Borrow < Entity > ,
731
+ EntityList : IntoIterator < Item = E > ,
732
+ FN : FnMut ( QueryItem < ' w , Q > ) ,
733
+ > (
734
+ & mut self ,
735
+ world : & ' w mut World ,
736
+ entities : EntityList ,
737
+ func : FN ,
738
+ ) {
739
+ // SAFETY: query has unique world access
740
+ unsafe {
741
+ self . update_archetypes ( world) ;
742
+ self . many_for_each_unchecked_manual :: < QueryFetch < Q > , E , EntityList , FN > (
743
+ world,
744
+ entities,
745
+ func,
746
+ world. last_change_tick ( ) ,
747
+ world. read_change_tick ( ) ,
748
+ ) ;
749
+ }
750
+ }
751
+
752
+ /// Runs `func` on each query result for the given [`World`]. This is faster than the equivalent
753
+ /// iter() method, but cannot be chained like a normal [`Iterator`].
754
+ ///
755
+ /// This can only be called for read-only queries.
756
+ ///
757
+ /// # Safety
758
+ ///
759
+ /// This does not check for mutable query correctness. To be safe, make sure mutable queries
760
+ /// have unique access to the components they query.
761
+ #[ inline]
762
+ pub unsafe fn many_for_each_unchecked <
763
+ ' w ,
764
+ E : Borrow < Entity > ,
765
+ EntityList : IntoIterator < Item = E > ,
766
+ FN : FnMut ( QueryItem < ' w , Q > ) ,
767
+ > (
768
+ & mut self ,
769
+ world : & ' w World ,
770
+ entities : EntityList ,
771
+ func : FN ,
772
+ ) {
773
+ self . update_archetypes ( world) ;
774
+ self . many_for_each_unchecked_manual :: < QueryFetch < Q > , E , EntityList , FN > (
775
+ world,
776
+ entities,
777
+ func,
778
+ world. last_change_tick ( ) ,
779
+ world. read_change_tick ( ) ,
780
+ ) ;
781
+ }
782
+
696
783
/// Runs `func` on each query result in parallel.
697
784
///
698
785
/// This can only be called for read-only queries, see [`Self::par_for_each_mut`] for
@@ -797,7 +884,7 @@ impl<Q: WorldQuery, F: WorldQuery> QueryState<Q, F> {
797
884
change_tick : u32 ,
798
885
) {
799
886
// NOTE: If you are changing query iteration code, remember to update the following places, where relevant:
800
- // QueryIter, QueryIterationCursor, QueryState::for_each_unchecked_manual, QueryState::par_for_each_unchecked_manual
887
+ // QueryIter, QueryIterationCursor, QueryState::for_each_unchecked_manual, QueryState::many_for_each_unchecked_manual, QueryState:: par_for_each_unchecked_manual
801
888
let mut fetch = QF :: init ( world, & self . fetch_state , last_change_tick, change_tick) ;
802
889
let mut filter = <QueryFetch < F > as Fetch >:: init (
803
890
world,
@@ -839,6 +926,63 @@ impl<Q: WorldQuery, F: WorldQuery> QueryState<Q, F> {
839
926
}
840
927
}
841
928
929
+ /// Runs `func` on each query result for the given [`World`], where the last change and
930
+ /// the current change tick are given. This is faster than the equivalent
931
+ /// iter() method, but cannot be chained like a normal [`Iterator`].
932
+ ///
933
+ /// # Safety
934
+ ///
935
+ /// This does not check for mutable query correctness. To be safe, make sure mutable queries
936
+ /// have unique access to the components they query.
937
+ /// This does not validate that `world.id()` matches `self.world_id`. Calling this on a `world`
938
+ /// with a mismatched [`WorldId`] is unsound.
939
+ pub ( crate ) unsafe fn many_for_each_unchecked_manual <
940
+ ' w ,
941
+ QF : Fetch < ' w , State = Q :: State > ,
942
+ E : Borrow < Entity > ,
943
+ EntityList : IntoIterator < Item = E > ,
944
+ FN : FnMut ( QF :: Item ) ,
945
+ > (
946
+ & self ,
947
+ world : & ' w World ,
948
+ entities : EntityList ,
949
+ mut func : FN ,
950
+ last_change_tick : u32 ,
951
+ change_tick : u32 ,
952
+ ) {
953
+ // NOTE: If you are changing query iteration code, remember to update the following places, where relevant:
954
+ // QueryIter, QueryIterationCursor, QueryState::for_each_unchecked_manual, QueryState::many_for_each_unchecked_manual, QueryState::par_for_each_unchecked_manual
955
+ let mut fetch = QF :: init ( world, & self . fetch_state , last_change_tick, change_tick) ;
956
+ let mut filter = <QueryFetch < F > as Fetch >:: init (
957
+ world,
958
+ & self . filter_state ,
959
+ last_change_tick,
960
+ change_tick,
961
+ ) ;
962
+ let archetypes = & world. archetypes ;
963
+ let tables = & world. storages ( ) . tables ;
964
+
965
+ for location in entities
966
+ . into_iter ( )
967
+ . filter_map ( |e| world. entities . get ( * e. borrow ( ) ) )
968
+ {
969
+ if !self
970
+ . matched_archetypes
971
+ . contains ( location. archetype_id . index ( ) )
972
+ {
973
+ continue ;
974
+ }
975
+
976
+ let archetype = & archetypes[ location. archetype_id ] ;
977
+
978
+ fetch. set_archetype ( & self . fetch_state , archetype, tables) ;
979
+ filter. set_archetype ( & self . filter_state , archetype, tables) ;
980
+ if filter. archetype_filter_fetch ( location. index ) {
981
+ func ( fetch. archetype_fetch ( location. index ) )
982
+ }
983
+ }
984
+ }
985
+
842
986
/// Runs `func` on each query result in parallel for the given [`World`], where the last change and
843
987
/// the current change tick are given. This is faster than the equivalent
844
988
/// iter() method, but cannot be chained like a normal [`Iterator`].
@@ -866,7 +1010,7 @@ impl<Q: WorldQuery, F: WorldQuery> QueryState<Q, F> {
866
1010
change_tick : u32 ,
867
1011
) {
868
1012
// NOTE: If you are changing query iteration code, remember to update the following places, where relevant:
869
- // QueryIter, QueryIterationCursor, QueryState::for_each_unchecked_manual, QueryState::par_for_each_unchecked_manual
1013
+ // QueryIter, QueryIterationCursor, QueryState::for_each_unchecked_manual, QueryState::many_for_each_unchecked_manual, QueryState:: par_for_each_unchecked_manual
870
1014
self . task_pool
871
1015
. as_ref ( )
872
1016
. expect ( "Cannot iterate query in parallel. No ComputeTaskPool initialized." )
0 commit comments