Skip to content

Commit

Permalink
Allow iterating over with EntityRef over the entire World (bevyengine…
Browse files Browse the repository at this point in the history
…#6843)

# Objective
Partially addresses bevyengine#5504. Allow users to get an `Iterator<Item = EntityRef<'a>>` over all entities in the `World`.

## Solution
Change `World::iter_entities` to return an iterator of `EntityRef` instead of `Entity`.

Not sure how to tackle making an `Iterator<Item = EntityMut<'_>>` without being horribly unsound. Might need to wait for `LendingIterator` to stabilize so we can ensure only one of them is valid at a given time.

---

## Changelog
Changed: `World::iter_entities` now returns an iterator of `EntityRef` instead of `Entity`.
  • Loading branch information
james7132 authored and ickshonpe committed Dec 6, 2022
1 parent 3972622 commit 262e4a0
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 8 deletions.
23 changes: 16 additions & 7 deletions crates/bevy_ecs/src/world/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use crate::{
component::{
Component, ComponentDescriptor, ComponentId, ComponentInfo, Components, TickCells,
},
entity::{AllocAtWithoutReplacement, Entities, Entity},
entity::{AllocAtWithoutReplacement, Entities, Entity, EntityLocation},
query::{QueryState, ReadOnlyWorldQuery, WorldQuery},
storage::{ResourceData, SparseSet, Storages},
system::Resource,
Expand Down Expand Up @@ -323,11 +323,20 @@ impl World {
///
/// 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())
.map(|archetype_entity| archetype_entity.entity())
pub fn iter_entities(&self) -> impl Iterator<Item = EntityRef<'_>> + '_ {
self.archetypes.iter().flat_map(|archetype| {
archetype
.entities()
.iter()
.enumerate()
.map(|(index, archetype_entity)| {
let location = EntityLocation {
archetype_id: archetype.id(),
index,
};
EntityRef::new(self, archetype_entity.entity(), location)
})
})
}

/// Retrieves an [`EntityMut`] that exposes read and write operations for the given `entity`.
Expand Down Expand Up @@ -1870,7 +1879,7 @@ mod tests {
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);
let counter = entity_counters.entry(entity.id()).or_insert(0);
*counter += 1;
}
};
Expand Down
2 changes: 1 addition & 1 deletion crates/bevy_scene/src/dynamic_scene.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ impl DynamicScene {
let mut builder =
DynamicSceneBuilder::from_world_with_type_registry(world, type_registry.clone());

builder.extract_entities(world.iter_entities());
builder.extract_entities(world.iter_entities().map(|entity| entity.id()));

builder.build()
}
Expand Down

0 comments on commit 262e4a0

Please sign in to comment.