@@ -74,7 +74,7 @@ use bevy_ptr::{move_as_ptr, MovingPtr, OwningPtr, Ptr};
7474use bevy_utils:: prelude:: DebugName ;
7575use core:: { any:: TypeId , fmt, mem:: ManuallyDrop } ;
7676use log:: warn;
77- use unsafe_world_cell:: UnsafeWorldCell ;
77+ use unsafe_world_cell:: { UnsafeEntityCell , UnsafeWorldCell } ;
7878
7979/// Stores and exposes operations on [entities](Entity), [components](Component), resources,
8080/// and their associated metadata.
@@ -984,6 +984,31 @@ impl World {
984984 unsafe { entities. fetch_mut ( cell) }
985985 }
986986
987+ /// Returns an [`Entity`] iterator of current entities.
988+ ///
989+ /// This is useful in contexts where you only have immutable access to the [`World`].
990+ /// If you have mutable access to the [`World`], use
991+ /// [`query()::<EntityRef>().iter(&world)`](World::query()) instead.
992+ #[ inline]
993+ pub fn iter_entities ( & self ) -> impl Iterator < Item = EntityRef < ' _ > > + ' _ {
994+ self . archetypes . iter ( ) . flat_map ( |archetype| {
995+ archetype
996+ . entities_with_location ( )
997+ . map ( |( entity, location) | {
998+ // SAFETY: entity exists and location accurately specifies the archetype where the entity is stored.
999+ let cell = UnsafeEntityCell :: new (
1000+ self . as_unsafe_world_cell_readonly ( ) ,
1001+ entity,
1002+ location,
1003+ self . last_change_tick ,
1004+ self . read_change_tick ( ) ,
1005+ ) ;
1006+ // SAFETY: `&self` gives read access to the entire world.
1007+ unsafe { EntityRef :: new ( cell) }
1008+ } )
1009+ } )
1010+ }
1011+
9871012 /// Simultaneously provides access to entity data and a command queue, which
9881013 /// will be applied when the world is next flushed.
9891014 ///
@@ -3852,7 +3877,7 @@ mod tests {
38523877 vec:: Vec ,
38533878 } ;
38543879 use bevy_ecs_macros:: Component ;
3855- use bevy_platform:: collections:: HashSet ;
3880+ use bevy_platform:: collections:: { HashMap , HashSet } ;
38563881 use bevy_utils:: prelude:: DebugName ;
38573882 use core:: {
38583883 any:: TypeId ,
@@ -4266,6 +4291,75 @@ mod tests {
42664291 ) ;
42674292 }
42684293
4294+ #[ test]
4295+ fn iterate_entities ( ) {
4296+ let mut world = World :: new ( ) ;
4297+ let mut entity_counters = <HashMap < _ , _ > >:: default ( ) ;
4298+
4299+ let iterate_and_count_entities = |world : & World , entity_counters : & mut HashMap < _ , _ > | {
4300+ entity_counters. clear ( ) ;
4301+ for entity in world. iter_entities ( ) {
4302+ let counter = entity_counters. entry ( entity. id ( ) ) . or_insert ( 0 ) ;
4303+ * counter += 1 ;
4304+ }
4305+ } ;
4306+
4307+ // Adding one entity and validating iteration
4308+ let ent0 = world. spawn ( ( Foo , Bar , Baz ) ) . id ( ) ;
4309+
4310+ iterate_and_count_entities ( & world, & mut entity_counters) ;
4311+ assert_eq ! ( entity_counters[ & ent0] , 1 ) ;
4312+ assert_eq ! ( entity_counters. len( ) , 1 ) ;
4313+
4314+ // Spawning three more entities and then validating iteration
4315+ let ent1 = world. spawn ( ( Foo , Bar ) ) . id ( ) ;
4316+ let ent2 = world. spawn ( ( Bar , Baz ) ) . id ( ) ;
4317+ let ent3 = world. spawn ( ( Foo , Baz ) ) . id ( ) ;
4318+
4319+ iterate_and_count_entities ( & world, & mut entity_counters) ;
4320+
4321+ assert_eq ! ( entity_counters[ & ent0] , 1 ) ;
4322+ assert_eq ! ( entity_counters[ & ent1] , 1 ) ;
4323+ assert_eq ! ( entity_counters[ & ent2] , 1 ) ;
4324+ assert_eq ! ( entity_counters[ & ent3] , 1 ) ;
4325+ assert_eq ! ( entity_counters. len( ) , 4 ) ;
4326+
4327+ // Despawning first entity and then validating the iteration
4328+ assert ! ( world. despawn( ent0) ) ;
4329+
4330+ iterate_and_count_entities ( & world, & mut entity_counters) ;
4331+
4332+ assert_eq ! ( entity_counters[ & ent1] , 1 ) ;
4333+ assert_eq ! ( entity_counters[ & ent2] , 1 ) ;
4334+ assert_eq ! ( entity_counters[ & ent3] , 1 ) ;
4335+ assert_eq ! ( entity_counters. len( ) , 3 ) ;
4336+
4337+ // Spawning three more entities, despawning three and then validating the iteration
4338+ let ent4 = world. spawn ( Foo ) . id ( ) ;
4339+ let ent5 = world. spawn ( Bar ) . id ( ) ;
4340+ let ent6 = world. spawn ( Baz ) . id ( ) ;
4341+
4342+ assert ! ( world. despawn( ent2) ) ;
4343+ assert ! ( world. despawn( ent3) ) ;
4344+ assert ! ( world. despawn( ent4) ) ;
4345+
4346+ iterate_and_count_entities ( & world, & mut entity_counters) ;
4347+
4348+ assert_eq ! ( entity_counters[ & ent1] , 1 ) ;
4349+ assert_eq ! ( entity_counters[ & ent5] , 1 ) ;
4350+ assert_eq ! ( entity_counters[ & ent6] , 1 ) ;
4351+ assert_eq ! ( entity_counters. len( ) , 3 ) ;
4352+
4353+ // Despawning remaining entities and then validating the iteration
4354+ assert ! ( world. despawn( ent1) ) ;
4355+ assert ! ( world. despawn( ent5) ) ;
4356+ assert ! ( world. despawn( ent6) ) ;
4357+
4358+ iterate_and_count_entities ( & world, & mut entity_counters) ;
4359+
4360+ assert_eq ! ( entity_counters. len( ) , 0 ) ;
4361+ }
4362+
42694363 #[ test]
42704364 fn spawn_empty_bundle ( ) {
42714365 let mut world = World :: new ( ) ;
0 commit comments