Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion src/entities.rs
Original file line number Diff line number Diff line change
Expand Up @@ -548,9 +548,13 @@ impl EntityMeta {
};
}

/// Where an entity is currently stored
#[derive(Copy, Clone)]
pub(crate) struct Location {
pub struct Location {
/// Index of the enclosing archetype in [`World::archetypes`](crate::World::archetypes)
pub archetype: u32,
/// Index of the entity's components in [`Archetype::get`](crate::Archetype::get) on the
/// associated [`Archetype`](crate::Archetype)
pub index: u32,
}

Expand Down
2 changes: 1 addition & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ pub use archetype::{Archetype, ArchetypeColumn, ArchetypeColumnMut};
pub use batch::{BatchIncomplete, BatchWriter, ColumnBatch, ColumnBatchBuilder, ColumnBatchType};
pub use bundle::{Bundle, DynamicBundle, DynamicBundleClone, MissingComponent};
pub use command_buffer::CommandBuffer;
pub use entities::{Entity, NoSuchEntity};
pub use entities::{Entity, Location, NoSuchEntity};
pub use entity_builder::{BuiltEntity, BuiltEntityClone, EntityBuilder, EntityBuilderClone};
pub use entity_ref::{ComponentRef, ComponentRefShared, EntityRef, Ref, RefMut};
pub use query::{
Expand Down
9 changes: 5 additions & 4 deletions src/query.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1081,11 +1081,12 @@ impl<Q: Query> PreparedQuery<Q> {

let state = world
.archetypes()
.iter()
.enumerate()
.filter_map(|(idx, x)| Q::Fetch::prepare(x).map(|state| (idx, state)))
.collect();

let fetch = world.archetypes().map(|_| None).collect();
let fetch = world.archetypes().iter().map(|_| None).collect();

Self { memo, state, fetch }
}
Expand All @@ -1100,7 +1101,7 @@ impl<Q: Query> PreparedQuery<Q> {
}

let meta = world.entities_meta();
let archetypes = world.archetypes_inner();
let archetypes = world.archetypes();

PreparedQueryBorrow::new(meta, archetypes, &self.state, &mut self.fetch)
}
Expand All @@ -1116,7 +1117,7 @@ impl<Q: Query> PreparedQuery<Q> {
}

let meta = world.entities_meta();
let archetypes = world.archetypes_inner();
let archetypes = world.archetypes();

let state: &'q [(usize, <Q::Fetch as Fetch>::State)] =
unsafe { mem::transmute(&*self.state) };
Expand All @@ -1133,7 +1134,7 @@ impl<Q: Query> PreparedQuery<Q> {
}

let meta = world.entities_meta();
let archetypes = world.archetypes_inner();
let archetypes = world.archetypes();

let state: &'q [(usize, <Q::Fetch as Fetch>::State)] =
unsafe { mem::transmute(&*self.state) };
Expand Down
5 changes: 3 additions & 2 deletions src/serialize/column.rs
Original file line number Diff line number Diff line change
Expand Up @@ -291,8 +291,9 @@ where
}

let predicate = |x: &&Archetype| -> bool { !x.is_empty() && x.satisfies::<Q>() };
let mut seq = serializer.serialize_seq(Some(world.archetypes().filter(predicate).count()))?;
for archetype in world.archetypes().filter(predicate) {
let mut seq =
serializer.serialize_seq(Some(world.archetypes().iter().filter(predicate).count()))?;
for archetype in world.archetypes().iter().filter(predicate) {
seq.serialize_element(&SerializeArchetype {
world,
archetype,
Expand Down
1 change: 1 addition & 0 deletions src/serialize/row.rs
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ where
{
let entity_count = world
.archetypes()
.iter()
.filter(|a| a.satisfies::<Q>())
.map(|a| a.len() as usize)
.sum();
Expand Down
23 changes: 14 additions & 9 deletions src/world.rs
Original file line number Diff line number Diff line change
Expand Up @@ -416,7 +416,11 @@ impl World {
&self.entities.meta
}

pub(crate) fn archetypes_inner(&self) -> &[Archetype] {
/// Inspect the archetypes that entities are organized into
///
/// Useful for dynamically scheduling concurrent queries by checking borrows in advance, and for
/// efficient serialization.
pub fn archetypes(&self) -> &[Archetype] {
&self.archetypes.archetypes
}

Expand Down Expand Up @@ -500,6 +504,15 @@ impl World {
}
}

/// Storage location of `entity`
///
/// Useful in combination with [`archetypes`](Self::archetypes). May be invalidated when
/// [`archetypes_generation`](Self::archetypes_generation) changes.
#[inline]
pub fn location_of(&self, entity: Entity) -> Result<Location, NoSuchEntity> {
self.entities.get(entity)
}

/// Given an id obtained from [`Entity::id`], reconstruct the still-live [`Entity`].
///
/// # Safety
Expand Down Expand Up @@ -818,14 +831,6 @@ impl World {
.flush(|id, location| location.index = unsafe { arch.allocate(id) });
}

/// Inspect the archetypes that entities are organized into
///
/// Useful for dynamically scheduling concurrent queries by checking borrows in advance, and for
/// efficient serialization.
pub fn archetypes(&self) -> impl ExactSizeIterator<Item = &'_ Archetype> + '_ {
self.archetypes_inner().iter()
}

/// Despawn `entity`, yielding a [`DynamicBundle`] of its components
///
/// Useful for moving entities between worlds.
Expand Down
2 changes: 1 addition & 1 deletion tests/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -858,7 +858,7 @@ fn columnar_access() {
let e = world.spawn(("abc", 123));
let f = world.spawn(("def", 456, true));
let g = world.spawn(("ghi", 789, false));
let mut archetypes = world.archetypes();
let mut archetypes = world.archetypes().iter();
let _empty = archetypes.next().unwrap();
let a = archetypes.next().unwrap();
assert_eq!(a.ids(), &[e.id()]);
Expand Down