mirror of
https://github.com/bevyengine/bevy
synced 2024-11-26 14:40:19 +00:00
# Objective - Add a way to iterate over all entities from &World ## Solution - Added a function `iter_entities` on World which returns an iterator of `Entity` derived from the entities in the `World`'s `archetypes` --- ## Changelog - Added a function `iter_entities` on World, allowing iterating over all entities in contexts where you only have read-only access to the World.
This commit is contained in:
parent
05c7babba2
commit
a0f1468108
2 changed files with 81 additions and 7 deletions
|
@ -320,6 +320,16 @@ impl World {
|
||||||
Some(EntityRef::new(self, entity, location))
|
Some(EntityRef::new(self, entity, location))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns an [`Entity`] iterator of current entities.
|
||||||
|
///
|
||||||
|
/// This is useful in contexts where you only have read-only access to the [`World`].
|
||||||
|
#[inline]
|
||||||
|
pub fn iter_entities(&self) -> impl Iterator<Item = Entity> + '_ {
|
||||||
|
self.archetypes
|
||||||
|
.iter()
|
||||||
|
.flat_map(|archetype| archetype.entities().iter().copied())
|
||||||
|
}
|
||||||
|
|
||||||
/// Retrieves an [`EntityMut`] that exposes read and write operations for the given `entity`.
|
/// Retrieves an [`EntityMut`] that exposes read and write operations for the given `entity`.
|
||||||
/// Returns [`None`] if the `entity` does not exist. Use [`World::entity_mut`] if you don't want
|
/// Returns [`None`] if the `entity` does not exist. Use [`World::entity_mut`] if you don't want
|
||||||
/// to unwrap the [`EntityMut`] yourself.
|
/// to unwrap the [`EntityMut`] yourself.
|
||||||
|
@ -1634,7 +1644,7 @@ mod tests {
|
||||||
system::Resource,
|
system::Resource,
|
||||||
};
|
};
|
||||||
use bevy_ecs_macros::Component;
|
use bevy_ecs_macros::Component;
|
||||||
use bevy_utils::HashSet;
|
use bevy_utils::{HashMap, HashSet};
|
||||||
use std::{
|
use std::{
|
||||||
any::TypeId,
|
any::TypeId,
|
||||||
panic,
|
panic,
|
||||||
|
@ -1907,4 +1917,73 @@ mod tests {
|
||||||
[Some(baz_id)].into()
|
[Some(baz_id)].into()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn iterate_entities() {
|
||||||
|
let mut world = World::new();
|
||||||
|
let mut entity_counters = HashMap::new();
|
||||||
|
|
||||||
|
let iterate_and_count_entities = |world: &World, entity_counters: &mut HashMap<_, _>| {
|
||||||
|
entity_counters.clear();
|
||||||
|
for entity in world.iter_entities() {
|
||||||
|
let counter = entity_counters.entry(entity).or_insert(0);
|
||||||
|
*counter += 1;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Adding one entity and validating iteration
|
||||||
|
let ent0 = world.spawn((Foo, Bar, Baz)).id();
|
||||||
|
|
||||||
|
iterate_and_count_entities(&world, &mut entity_counters);
|
||||||
|
assert_eq!(entity_counters[&ent0], 1);
|
||||||
|
assert_eq!(entity_counters.len(), 1);
|
||||||
|
|
||||||
|
// Spawning three more entities and then validating iteration
|
||||||
|
let ent1 = world.spawn((Foo, Bar)).id();
|
||||||
|
let ent2 = world.spawn((Bar, Baz)).id();
|
||||||
|
let ent3 = world.spawn((Foo, Baz)).id();
|
||||||
|
|
||||||
|
iterate_and_count_entities(&world, &mut entity_counters);
|
||||||
|
|
||||||
|
assert_eq!(entity_counters[&ent0], 1);
|
||||||
|
assert_eq!(entity_counters[&ent1], 1);
|
||||||
|
assert_eq!(entity_counters[&ent2], 1);
|
||||||
|
assert_eq!(entity_counters[&ent3], 1);
|
||||||
|
assert_eq!(entity_counters.len(), 4);
|
||||||
|
|
||||||
|
// Despawning first entity and then validating the iteration
|
||||||
|
assert!(world.despawn(ent0));
|
||||||
|
|
||||||
|
iterate_and_count_entities(&world, &mut entity_counters);
|
||||||
|
|
||||||
|
assert_eq!(entity_counters[&ent1], 1);
|
||||||
|
assert_eq!(entity_counters[&ent2], 1);
|
||||||
|
assert_eq!(entity_counters[&ent3], 1);
|
||||||
|
assert_eq!(entity_counters.len(), 3);
|
||||||
|
|
||||||
|
// Spawning three more entities, despawning three and then validating the iteration
|
||||||
|
let ent4 = world.spawn(Foo).id();
|
||||||
|
let ent5 = world.spawn(Bar).id();
|
||||||
|
let ent6 = world.spawn(Baz).id();
|
||||||
|
|
||||||
|
assert!(world.despawn(ent2));
|
||||||
|
assert!(world.despawn(ent3));
|
||||||
|
assert!(world.despawn(ent4));
|
||||||
|
|
||||||
|
iterate_and_count_entities(&world, &mut entity_counters);
|
||||||
|
|
||||||
|
assert_eq!(entity_counters[&ent1], 1);
|
||||||
|
assert_eq!(entity_counters[&ent5], 1);
|
||||||
|
assert_eq!(entity_counters[&ent6], 1);
|
||||||
|
assert_eq!(entity_counters.len(), 3);
|
||||||
|
|
||||||
|
// Despawning remaining entities and then validating the iteration
|
||||||
|
assert!(world.despawn(ent1));
|
||||||
|
assert!(world.despawn(ent5));
|
||||||
|
assert!(world.despawn(ent6));
|
||||||
|
|
||||||
|
iterate_and_count_entities(&world, &mut entity_counters);
|
||||||
|
|
||||||
|
assert_eq!(entity_counters.len(), 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,12 +42,7 @@ impl DynamicScene {
|
||||||
let mut builder =
|
let mut builder =
|
||||||
DynamicSceneBuilder::from_world_with_type_registry(world, type_registry.clone());
|
DynamicSceneBuilder::from_world_with_type_registry(world, type_registry.clone());
|
||||||
|
|
||||||
builder.extract_entities(
|
builder.extract_entities(world.iter_entities());
|
||||||
world
|
|
||||||
.archetypes()
|
|
||||||
.iter()
|
|
||||||
.flat_map(|archetype| archetype.entities().iter().copied()),
|
|
||||||
);
|
|
||||||
|
|
||||||
builder.build()
|
builder.build()
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue