mirror of
https://github.com/bevyengine/bevy
synced 2024-11-25 22:20:20 +00:00
# Objective Fixes #6059, changing all incorrect occurrences of ``id`` in the ``entity`` module to ``index``: * struct level documentation, * ``id`` struct field, * ``id`` method and its documentation. ## Solution Renaming and verifying using CI. Co-authored-by: Edvin Kjell <43633999+Edwox@users.noreply.github.com>
This commit is contained in:
parent
ed3ecda91d
commit
a8a62fcf3d
9 changed files with 133 additions and 118 deletions
|
@ -543,10 +543,10 @@ impl<'a, 'b> BundleInserter<'a, 'b> {
|
|||
InsertBundleResult::NewArchetypeSameTable { new_archetype } => {
|
||||
let result = self.archetype.swap_remove(location.index);
|
||||
if let Some(swapped_entity) = result.swapped_entity {
|
||||
self.entities.meta[swapped_entity.id as usize].location = location;
|
||||
self.entities.meta[swapped_entity.index as usize].location = location;
|
||||
}
|
||||
let new_location = new_archetype.allocate(entity, result.table_row);
|
||||
self.entities.meta[entity.id as usize].location = new_location;
|
||||
self.entities.meta[entity.index as usize].location = new_location;
|
||||
|
||||
// PERF: this could be looked up during Inserter construction and stored (but borrowing makes this nasty)
|
||||
let add_bundle = self
|
||||
|
@ -571,7 +571,7 @@ impl<'a, 'b> BundleInserter<'a, 'b> {
|
|||
} => {
|
||||
let result = self.archetype.swap_remove(location.index);
|
||||
if let Some(swapped_entity) = result.swapped_entity {
|
||||
self.entities.meta[swapped_entity.id as usize].location = location;
|
||||
self.entities.meta[swapped_entity.index as usize].location = location;
|
||||
}
|
||||
// PERF: store "non bundle" components in edge, then just move those to avoid
|
||||
// redundant copies
|
||||
|
@ -579,7 +579,7 @@ impl<'a, 'b> BundleInserter<'a, 'b> {
|
|||
.table
|
||||
.move_to_superset_unchecked(result.table_row, new_table);
|
||||
let new_location = new_archetype.allocate(entity, move_result.new_row);
|
||||
self.entities.meta[entity.id as usize].location = new_location;
|
||||
self.entities.meta[entity.index as usize].location = new_location;
|
||||
|
||||
// if an entity was moved into this entity's table spot, update its table row
|
||||
if let Some(swapped_entity) = move_result.swapped_entity {
|
||||
|
@ -655,7 +655,7 @@ impl<'a, 'b> BundleSpawner<'a, 'b> {
|
|||
self.change_tick,
|
||||
bundle,
|
||||
);
|
||||
self.entities.meta[entity.id as usize].location = location;
|
||||
self.entities.meta[entity.index as usize].location = location;
|
||||
|
||||
location
|
||||
}
|
||||
|
|
|
@ -53,7 +53,7 @@ type IdCursor = isize;
|
|||
|
||||
/// Lightweight identifier of an [entity](crate::entity).
|
||||
///
|
||||
/// The identifier is implemented using a [generational index]: a combination of an ID and a generation.
|
||||
/// The identifier is implemented using a [generational index]: a combination of an index and a generation.
|
||||
/// This allows fast insertion after data removal in an array while minimizing loss of spatial locality.
|
||||
///
|
||||
/// [generational index]: https://lucassardois.medium.com/generational-indices-guide-8e3c5f7fd594
|
||||
|
@ -106,7 +106,7 @@ type IdCursor = isize;
|
|||
#[derive(Clone, Copy, Deserialize, Eq, Hash, Ord, PartialEq, PartialOrd, Serialize)]
|
||||
pub struct Entity {
|
||||
pub(crate) generation: u32,
|
||||
pub(crate) id: u32,
|
||||
pub(crate) index: u32,
|
||||
}
|
||||
|
||||
pub enum AllocAtWithoutReplacement {
|
||||
|
@ -116,14 +116,14 @@ pub enum AllocAtWithoutReplacement {
|
|||
}
|
||||
|
||||
impl Entity {
|
||||
/// Creates a new entity reference with the specified `id` and a generation of 0.
|
||||
/// Creates a new entity reference with the specified `index` and a generation of 0.
|
||||
///
|
||||
/// # Note
|
||||
///
|
||||
/// Spawning a specific `entity` value is __rarely the right choice__. Most apps should favor
|
||||
/// [`Commands::spawn`](crate::system::Commands::spawn). This method should generally
|
||||
/// only be used for sharing entities across apps, and only when they have a scheme
|
||||
/// worked out to share an ID space (which doesn't happen by default).
|
||||
/// worked out to share an index space (which doesn't happen by default).
|
||||
///
|
||||
/// In general, one should not try to synchronize the ECS by attempting to ensure that
|
||||
/// `Entity` lines up between instances, but instead insert a secondary identifier as
|
||||
|
@ -163,8 +163,11 @@ impl Entity {
|
|||
/// }
|
||||
/// }
|
||||
/// ```
|
||||
pub const fn from_raw(id: u32) -> Entity {
|
||||
Entity { id, generation: 0 }
|
||||
pub const fn from_raw(index: u32) -> Entity {
|
||||
Entity {
|
||||
index,
|
||||
generation: 0,
|
||||
}
|
||||
}
|
||||
|
||||
/// Convert to a form convenient for passing outside of rust.
|
||||
|
@ -174,7 +177,7 @@ impl Entity {
|
|||
///
|
||||
/// No particular structure is guaranteed for the returned bits.
|
||||
pub fn to_bits(self) -> u64 {
|
||||
u64::from(self.generation) << 32 | u64::from(self.id)
|
||||
u64::from(self.generation) << 32 | u64::from(self.index)
|
||||
}
|
||||
|
||||
/// Reconstruct an `Entity` previously destructured with [`Entity::to_bits`].
|
||||
|
@ -183,23 +186,23 @@ impl Entity {
|
|||
pub const fn from_bits(bits: u64) -> Self {
|
||||
Self {
|
||||
generation: (bits >> 32) as u32,
|
||||
id: bits as u32,
|
||||
index: bits as u32,
|
||||
}
|
||||
}
|
||||
|
||||
/// Return a transiently unique identifier.
|
||||
///
|
||||
/// No two simultaneously-live entities share the same ID, but dead entities' IDs may collide
|
||||
/// No two simultaneously-live entities share the same index, but dead entities' indices may collide
|
||||
/// with both live and dead entities. Useful for compactly representing entities within a
|
||||
/// specific snapshot of the world, such as when serializing.
|
||||
#[inline]
|
||||
pub const fn id(self) -> u32 {
|
||||
self.id
|
||||
pub const fn index(self) -> u32 {
|
||||
self.index
|
||||
}
|
||||
|
||||
/// Returns the generation of this Entity's id. The generation is incremented each time an
|
||||
/// entity with a given id is despawned. This serves as a "count" of the number of times a
|
||||
/// given id has been reused (id, generation) pairs uniquely identify a given Entity.
|
||||
/// Returns the generation of this Entity's index. The generation is incremented each time an
|
||||
/// entity with a given index is despawned. This serves as a "count" of the number of times a
|
||||
/// given index has been reused (index, generation) pairs uniquely identify a given Entity.
|
||||
#[inline]
|
||||
pub const fn generation(self) -> u32 {
|
||||
self.generation
|
||||
|
@ -208,13 +211,13 @@ impl Entity {
|
|||
|
||||
impl fmt::Debug for Entity {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(f, "{}v{}", self.id, self.generation)
|
||||
write!(f, "{}v{}", self.index, self.generation)
|
||||
}
|
||||
}
|
||||
|
||||
impl SparseSetIndex for Entity {
|
||||
fn sparse_set_index(&self) -> usize {
|
||||
self.id() as usize
|
||||
self.index() as usize
|
||||
}
|
||||
|
||||
fn get_sparse_set_index(value: usize) -> Self {
|
||||
|
@ -228,28 +231,33 @@ pub struct ReserveEntitiesIterator<'a> {
|
|||
// Metas, so we can recover the current generation for anything in the freelist.
|
||||
meta: &'a [EntityMeta],
|
||||
|
||||
// Reserved IDs formerly in the freelist to hand out.
|
||||
id_iter: std::slice::Iter<'a, u32>,
|
||||
// Reserved indices formerly in the freelist to hand out.
|
||||
index_iter: std::slice::Iter<'a, u32>,
|
||||
|
||||
// New Entity IDs to hand out, outside the range of meta.len().
|
||||
id_range: std::ops::Range<u32>,
|
||||
// New Entity indices to hand out, outside the range of meta.len().
|
||||
index_range: std::ops::Range<u32>,
|
||||
}
|
||||
|
||||
impl<'a> Iterator for ReserveEntitiesIterator<'a> {
|
||||
type Item = Entity;
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
self.id_iter
|
||||
self.index_iter
|
||||
.next()
|
||||
.map(|&id| Entity {
|
||||
generation: self.meta[id as usize].generation,
|
||||
id,
|
||||
.map(|&index| Entity {
|
||||
generation: self.meta[index as usize].generation,
|
||||
index,
|
||||
})
|
||||
.or_else(|| {
|
||||
self.index_range.next().map(|index| Entity {
|
||||
generation: 0,
|
||||
index,
|
||||
})
|
||||
})
|
||||
.or_else(|| self.id_range.next().map(|id| Entity { generation: 0, id }))
|
||||
}
|
||||
|
||||
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||
let len = self.id_iter.len() + self.id_range.len();
|
||||
let len = self.index_iter.len() + self.index_range.len();
|
||||
(len, Some(len))
|
||||
}
|
||||
}
|
||||
|
@ -344,8 +352,8 @@ impl Entities {
|
|||
|
||||
ReserveEntitiesIterator {
|
||||
meta: &self.meta[..],
|
||||
id_iter: self.pending[freelist_range].iter(),
|
||||
id_range: new_id_start..new_id_end,
|
||||
index_iter: self.pending[freelist_range].iter(),
|
||||
index_range: new_id_start..new_id_end,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -356,10 +364,10 @@ impl Entities {
|
|||
let n = self.free_cursor.fetch_sub(1, Ordering::Relaxed);
|
||||
if n > 0 {
|
||||
// Allocate from the freelist.
|
||||
let id = self.pending[(n - 1) as usize];
|
||||
let index = self.pending[(n - 1) as usize];
|
||||
Entity {
|
||||
generation: self.meta[id as usize].generation,
|
||||
id,
|
||||
generation: self.meta[index as usize].generation,
|
||||
index,
|
||||
}
|
||||
} else {
|
||||
// Grab a new ID, outside the range of `meta.len()`. `flush()` must
|
||||
|
@ -369,7 +377,7 @@ impl Entities {
|
|||
// and farther beyond `meta.len()`.
|
||||
Entity {
|
||||
generation: 0,
|
||||
id: u32::try_from(self.meta.len() as IdCursor - n).expect("too many entities"),
|
||||
index: u32::try_from(self.meta.len() as IdCursor - n).expect("too many entities"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -386,17 +394,20 @@ impl Entities {
|
|||
pub fn alloc(&mut self) -> Entity {
|
||||
self.verify_flushed();
|
||||
self.len += 1;
|
||||
if let Some(id) = self.pending.pop() {
|
||||
if let Some(index) = self.pending.pop() {
|
||||
let new_free_cursor = self.pending.len() as IdCursor;
|
||||
*self.free_cursor.get_mut() = new_free_cursor;
|
||||
Entity {
|
||||
generation: self.meta[id as usize].generation,
|
||||
id,
|
||||
generation: self.meta[index as usize].generation,
|
||||
index,
|
||||
}
|
||||
} else {
|
||||
let id = u32::try_from(self.meta.len()).expect("too many entities");
|
||||
let index = u32::try_from(self.meta.len()).expect("too many entities");
|
||||
self.meta.push(EntityMeta::EMPTY);
|
||||
Entity { generation: 0, id }
|
||||
Entity {
|
||||
generation: 0,
|
||||
index,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -407,14 +418,15 @@ impl Entities {
|
|||
pub fn alloc_at(&mut self, entity: Entity) -> Option<EntityLocation> {
|
||||
self.verify_flushed();
|
||||
|
||||
let loc = if entity.id as usize >= self.meta.len() {
|
||||
self.pending.extend((self.meta.len() as u32)..entity.id);
|
||||
let loc = if entity.index as usize >= self.meta.len() {
|
||||
self.pending.extend((self.meta.len() as u32)..entity.index);
|
||||
let new_free_cursor = self.pending.len() as IdCursor;
|
||||
*self.free_cursor.get_mut() = new_free_cursor;
|
||||
self.meta.resize(entity.id as usize + 1, EntityMeta::EMPTY);
|
||||
self.meta
|
||||
.resize(entity.index as usize + 1, EntityMeta::EMPTY);
|
||||
self.len += 1;
|
||||
None
|
||||
} else if let Some(index) = self.pending.iter().position(|item| *item == entity.id) {
|
||||
} else if let Some(index) = self.pending.iter().position(|item| *item == entity.index) {
|
||||
self.pending.swap_remove(index);
|
||||
let new_free_cursor = self.pending.len() as IdCursor;
|
||||
*self.free_cursor.get_mut() = new_free_cursor;
|
||||
|
@ -422,12 +434,12 @@ impl Entities {
|
|||
None
|
||||
} else {
|
||||
Some(mem::replace(
|
||||
&mut self.meta[entity.id as usize].location,
|
||||
&mut self.meta[entity.index as usize].location,
|
||||
EntityMeta::EMPTY.location,
|
||||
))
|
||||
};
|
||||
|
||||
self.meta[entity.id as usize].generation = entity.generation;
|
||||
self.meta[entity.index as usize].generation = entity.generation;
|
||||
|
||||
loc
|
||||
}
|
||||
|
@ -438,21 +450,22 @@ impl Entities {
|
|||
pub fn alloc_at_without_replacement(&mut self, entity: Entity) -> AllocAtWithoutReplacement {
|
||||
self.verify_flushed();
|
||||
|
||||
let result = if entity.id as usize >= self.meta.len() {
|
||||
self.pending.extend((self.meta.len() as u32)..entity.id);
|
||||
let result = if entity.index as usize >= self.meta.len() {
|
||||
self.pending.extend((self.meta.len() as u32)..entity.index);
|
||||
let new_free_cursor = self.pending.len() as IdCursor;
|
||||
*self.free_cursor.get_mut() = new_free_cursor;
|
||||
self.meta.resize(entity.id as usize + 1, EntityMeta::EMPTY);
|
||||
self.meta
|
||||
.resize(entity.index as usize + 1, EntityMeta::EMPTY);
|
||||
self.len += 1;
|
||||
AllocAtWithoutReplacement::DidNotExist
|
||||
} else if let Some(index) = self.pending.iter().position(|item| *item == entity.id) {
|
||||
} else if let Some(index) = self.pending.iter().position(|item| *item == entity.index) {
|
||||
self.pending.swap_remove(index);
|
||||
let new_free_cursor = self.pending.len() as IdCursor;
|
||||
*self.free_cursor.get_mut() = new_free_cursor;
|
||||
self.len += 1;
|
||||
AllocAtWithoutReplacement::DidNotExist
|
||||
} else {
|
||||
let current_meta = &mut self.meta[entity.id as usize];
|
||||
let current_meta = &mut self.meta[entity.index as usize];
|
||||
if current_meta.location.archetype_id == ArchetypeId::INVALID {
|
||||
AllocAtWithoutReplacement::DidNotExist
|
||||
} else if current_meta.generation == entity.generation {
|
||||
|
@ -462,7 +475,7 @@ impl Entities {
|
|||
}
|
||||
};
|
||||
|
||||
self.meta[entity.id as usize].generation = entity.generation;
|
||||
self.meta[entity.index as usize].generation = entity.generation;
|
||||
result
|
||||
}
|
||||
|
||||
|
@ -472,7 +485,7 @@ impl Entities {
|
|||
pub fn free(&mut self, entity: Entity) -> Option<EntityLocation> {
|
||||
self.verify_flushed();
|
||||
|
||||
let meta = &mut self.meta[entity.id as usize];
|
||||
let meta = &mut self.meta[entity.index as usize];
|
||||
if meta.generation != entity.generation {
|
||||
return None;
|
||||
}
|
||||
|
@ -480,7 +493,7 @@ impl Entities {
|
|||
|
||||
let loc = mem::replace(&mut meta.location, EntityMeta::EMPTY.location);
|
||||
|
||||
self.pending.push(entity.id);
|
||||
self.pending.push(entity.index);
|
||||
|
||||
let new_free_cursor = self.pending.len() as IdCursor;
|
||||
*self.free_cursor.get_mut() = new_free_cursor;
|
||||
|
@ -505,7 +518,7 @@ impl Entities {
|
|||
// This will return false for entities which have been freed, even if
|
||||
// not reallocated since the generation is incremented in `free`
|
||||
pub fn contains(&self, entity: Entity) -> bool {
|
||||
self.resolve_from_id(entity.id())
|
||||
self.resolve_from_id(entity.index())
|
||||
.map_or(false, |e| e.generation() == entity.generation)
|
||||
}
|
||||
|
||||
|
@ -518,8 +531,8 @@ impl Entities {
|
|||
|
||||
/// Returns `Ok(Location { archetype: Archetype::invalid(), index: undefined })` for pending entities.
|
||||
pub fn get(&self, entity: Entity) -> Option<EntityLocation> {
|
||||
if (entity.id as usize) < self.meta.len() {
|
||||
let meta = &self.meta[entity.id as usize];
|
||||
if (entity.index as usize) < self.meta.len() {
|
||||
let meta = &self.meta[entity.index as usize];
|
||||
if meta.generation != entity.generation
|
||||
|| meta.location.archetype_id == ArchetypeId::INVALID
|
||||
{
|
||||
|
@ -537,17 +550,20 @@ impl Entities {
|
|||
/// Note: This method may return [`Entities`](Entity) which are currently free
|
||||
/// Note that [`contains`](Entities::contains) will correctly return false for freed
|
||||
/// entities, since it checks the generation
|
||||
pub fn resolve_from_id(&self, id: u32) -> Option<Entity> {
|
||||
let idu = id as usize;
|
||||
pub fn resolve_from_id(&self, index: u32) -> Option<Entity> {
|
||||
let idu = index as usize;
|
||||
if let Some(&EntityMeta { generation, .. }) = self.meta.get(idu) {
|
||||
Some(Entity { generation, id })
|
||||
Some(Entity { generation, index })
|
||||
} else {
|
||||
// `id` is outside of the meta list - check whether it is reserved but not yet flushed.
|
||||
let free_cursor = self.free_cursor.load(Ordering::Relaxed);
|
||||
// If this entity was manually created, then free_cursor might be positive
|
||||
// Returning None handles that case correctly
|
||||
let num_pending = usize::try_from(-free_cursor).ok()?;
|
||||
(idu < self.meta.len() + num_pending).then_some(Entity { generation: 0, id })
|
||||
(idu < self.meta.len() + num_pending).then_some(Entity {
|
||||
generation: 0,
|
||||
index,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -576,10 +592,10 @@ impl Entities {
|
|||
let new_meta_len = old_meta_len + -current_free_cursor as usize;
|
||||
self.meta.resize(new_meta_len, EntityMeta::EMPTY);
|
||||
self.len += -current_free_cursor as u32;
|
||||
for (id, meta) in self.meta.iter_mut().enumerate().skip(old_meta_len) {
|
||||
for (index, meta) in self.meta.iter_mut().enumerate().skip(old_meta_len) {
|
||||
init(
|
||||
Entity {
|
||||
id: id as u32,
|
||||
index: index as u32,
|
||||
generation: meta.generation,
|
||||
},
|
||||
&mut meta.location,
|
||||
|
@ -591,11 +607,11 @@ impl Entities {
|
|||
};
|
||||
|
||||
self.len += (self.pending.len() - new_free_cursor) as u32;
|
||||
for id in self.pending.drain(new_free_cursor..) {
|
||||
let meta = &mut self.meta[id as usize];
|
||||
for index in self.pending.drain(new_free_cursor..) {
|
||||
let meta = &mut self.meta[index as usize];
|
||||
init(
|
||||
Entity {
|
||||
id,
|
||||
index,
|
||||
generation: meta.generation,
|
||||
},
|
||||
&mut meta.location,
|
||||
|
@ -684,7 +700,7 @@ mod tests {
|
|||
fn entity_bits_roundtrip() {
|
||||
let e = Entity {
|
||||
generation: 0xDEADBEEF,
|
||||
id: 0xBAADF00D,
|
||||
index: 0xBAADF00D,
|
||||
};
|
||||
assert_eq!(Entity::from_bits(e.to_bits()), e);
|
||||
}
|
||||
|
@ -719,14 +735,14 @@ mod tests {
|
|||
#[test]
|
||||
fn entity_const() {
|
||||
const C1: Entity = Entity::from_raw(42);
|
||||
assert_eq!(42, C1.id);
|
||||
assert_eq!(42, C1.index);
|
||||
assert_eq!(0, C1.generation);
|
||||
|
||||
const C2: Entity = Entity::from_bits(0x0000_00ff_0000_00cc);
|
||||
assert_eq!(0x0000_00cc, C2.id);
|
||||
assert_eq!(0x0000_00cc, C2.index);
|
||||
assert_eq!(0x0000_00ff, C2.generation);
|
||||
|
||||
const C3: u32 = Entity::from_raw(33).id();
|
||||
const C3: u32 = Entity::from_raw(33).index();
|
||||
assert_eq!(33, C3);
|
||||
|
||||
const C4: u32 = Entity::from_bits(0x00dd_00ff_0000_0000).generation();
|
||||
|
|
|
@ -1453,7 +1453,7 @@ mod tests {
|
|||
e4,
|
||||
Entity {
|
||||
generation: 0,
|
||||
id: 3,
|
||||
index: 3,
|
||||
},
|
||||
"new entity is created immediately after world_a's max entity"
|
||||
);
|
||||
|
@ -1487,7 +1487,7 @@ mod tests {
|
|||
|
||||
let e4_mismatched_generation = Entity {
|
||||
generation: 1,
|
||||
id: 3,
|
||||
index: 3,
|
||||
};
|
||||
assert!(
|
||||
world_b.get_or_spawn(e4_mismatched_generation).is_none(),
|
||||
|
@ -1506,7 +1506,7 @@ mod tests {
|
|||
|
||||
let high_non_existent_entity = Entity {
|
||||
generation: 0,
|
||||
id: 6,
|
||||
index: 6,
|
||||
};
|
||||
world_b
|
||||
.get_or_spawn(high_non_existent_entity)
|
||||
|
@ -1520,7 +1520,7 @@ mod tests {
|
|||
|
||||
let high_non_existent_but_reserved_entity = Entity {
|
||||
generation: 0,
|
||||
id: 5,
|
||||
index: 5,
|
||||
};
|
||||
assert!(
|
||||
world_b.get_entity(high_non_existent_but_reserved_entity).is_none(),
|
||||
|
@ -1539,19 +1539,19 @@ mod tests {
|
|||
vec![
|
||||
Entity {
|
||||
generation: 0,
|
||||
id: 5
|
||||
index: 5
|
||||
},
|
||||
Entity {
|
||||
generation: 0,
|
||||
id: 4
|
||||
index: 4
|
||||
},
|
||||
Entity {
|
||||
generation: 0,
|
||||
id: 7,
|
||||
index: 7,
|
||||
},
|
||||
Entity {
|
||||
generation: 0,
|
||||
id: 8,
|
||||
index: 8,
|
||||
},
|
||||
],
|
||||
"space between original entities and high entities is used for new entity ids"
|
||||
|
@ -1603,7 +1603,7 @@ mod tests {
|
|||
let e2 = world.spawn_empty().id();
|
||||
let invalid_e2 = Entity {
|
||||
generation: 1,
|
||||
id: e2.id,
|
||||
index: e2.index,
|
||||
};
|
||||
|
||||
let values = vec![(e0, (B(0), C)), (e1, (B(1), C)), (invalid_e2, (B(2), C))];
|
||||
|
|
|
@ -120,18 +120,18 @@ impl ComponentSparseSet {
|
|||
/// The `value` pointer must point to a valid address that matches the [`Layout`](std::alloc::Layout)
|
||||
/// inside the [`ComponentInfo`] given when constructing this sparse set.
|
||||
pub(crate) unsafe fn insert(&mut self, entity: Entity, value: OwningPtr<'_>, change_tick: u32) {
|
||||
if let Some(&dense_index) = self.sparse.get(entity.id()) {
|
||||
if let Some(&dense_index) = self.sparse.get(entity.index()) {
|
||||
#[cfg(debug_assertions)]
|
||||
assert_eq!(entity, self.entities[dense_index as usize]);
|
||||
self.dense.replace(dense_index as usize, value, change_tick);
|
||||
} else {
|
||||
let dense_index = self.dense.len();
|
||||
self.dense.push(value, ComponentTicks::new(change_tick));
|
||||
self.sparse.insert(entity.id(), dense_index as u32);
|
||||
self.sparse.insert(entity.index(), dense_index as u32);
|
||||
#[cfg(debug_assertions)]
|
||||
assert_eq!(self.entities.len(), dense_index);
|
||||
#[cfg(not(debug_assertions))]
|
||||
self.entities.push(entity.id());
|
||||
self.entities.push(entity.index());
|
||||
#[cfg(debug_assertions)]
|
||||
self.entities.push(entity);
|
||||
}
|
||||
|
@ -141,7 +141,7 @@ impl ComponentSparseSet {
|
|||
pub fn contains(&self, entity: Entity) -> bool {
|
||||
#[cfg(debug_assertions)]
|
||||
{
|
||||
if let Some(&dense_index) = self.sparse.get(entity.id()) {
|
||||
if let Some(&dense_index) = self.sparse.get(entity.index()) {
|
||||
#[cfg(debug_assertions)]
|
||||
assert_eq!(entity, self.entities[dense_index as usize]);
|
||||
true
|
||||
|
@ -150,12 +150,12 @@ impl ComponentSparseSet {
|
|||
}
|
||||
}
|
||||
#[cfg(not(debug_assertions))]
|
||||
self.sparse.contains(entity.id())
|
||||
self.sparse.contains(entity.index())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn get(&self, entity: Entity) -> Option<Ptr<'_>> {
|
||||
self.sparse.get(entity.id()).map(|dense_index| {
|
||||
self.sparse.get(entity.index()).map(|dense_index| {
|
||||
let dense_index = *dense_index as usize;
|
||||
#[cfg(debug_assertions)]
|
||||
assert_eq!(entity, self.entities[dense_index]);
|
||||
|
@ -166,7 +166,7 @@ impl ComponentSparseSet {
|
|||
|
||||
#[inline]
|
||||
pub fn get_with_ticks(&self, entity: Entity) -> Option<(Ptr<'_>, &UnsafeCell<ComponentTicks>)> {
|
||||
let dense_index = *self.sparse.get(entity.id())? as usize;
|
||||
let dense_index = *self.sparse.get(entity.index())? as usize;
|
||||
#[cfg(debug_assertions)]
|
||||
assert_eq!(entity, self.entities[dense_index]);
|
||||
// SAFETY: if the sparse index points to something in the dense vec, it exists
|
||||
|
@ -180,7 +180,7 @@ impl ComponentSparseSet {
|
|||
|
||||
#[inline]
|
||||
pub fn get_ticks(&self, entity: Entity) -> Option<&UnsafeCell<ComponentTicks>> {
|
||||
let dense_index = *self.sparse.get(entity.id())? as usize;
|
||||
let dense_index = *self.sparse.get(entity.index())? as usize;
|
||||
#[cfg(debug_assertions)]
|
||||
assert_eq!(entity, self.entities[dense_index]);
|
||||
// SAFETY: if the sparse index points to something in the dense vec, it exists
|
||||
|
@ -191,7 +191,7 @@ impl ComponentSparseSet {
|
|||
/// it exists).
|
||||
#[must_use = "The returned pointer must be used to drop the removed component."]
|
||||
pub(crate) fn remove_and_forget(&mut self, entity: Entity) -> Option<OwningPtr<'_>> {
|
||||
self.sparse.remove(entity.id()).map(|dense_index| {
|
||||
self.sparse.remove(entity.index()).map(|dense_index| {
|
||||
let dense_index = dense_index as usize;
|
||||
#[cfg(debug_assertions)]
|
||||
assert_eq!(entity, self.entities[dense_index]);
|
||||
|
@ -202,17 +202,17 @@ impl ComponentSparseSet {
|
|||
if !is_last {
|
||||
let swapped_entity = self.entities[dense_index];
|
||||
#[cfg(not(debug_assertions))]
|
||||
let idx = swapped_entity;
|
||||
let index = swapped_entity;
|
||||
#[cfg(debug_assertions)]
|
||||
let idx = swapped_entity.id();
|
||||
*self.sparse.get_mut(idx).unwrap() = dense_index as u32;
|
||||
let index = swapped_entity.index();
|
||||
*self.sparse.get_mut(index).unwrap() = dense_index as u32;
|
||||
}
|
||||
value
|
||||
})
|
||||
}
|
||||
|
||||
pub(crate) fn remove(&mut self, entity: Entity) -> bool {
|
||||
if let Some(dense_index) = self.sparse.remove(entity.id()) {
|
||||
if let Some(dense_index) = self.sparse.remove(entity.index()) {
|
||||
let dense_index = dense_index as usize;
|
||||
#[cfg(debug_assertions)]
|
||||
assert_eq!(entity, self.entities[dense_index]);
|
||||
|
@ -223,10 +223,10 @@ impl ComponentSparseSet {
|
|||
if !is_last {
|
||||
let swapped_entity = self.entities[dense_index];
|
||||
#[cfg(not(debug_assertions))]
|
||||
let idx = swapped_entity;
|
||||
let index = swapped_entity;
|
||||
#[cfg(debug_assertions)]
|
||||
let idx = swapped_entity.id();
|
||||
*self.sparse.get_mut(idx).unwrap() = dense_index as u32;
|
||||
let index = swapped_entity.index();
|
||||
*self.sparse.get_mut(index).unwrap() = dense_index as u32;
|
||||
}
|
||||
true
|
||||
} else {
|
||||
|
|
|
@ -369,7 +369,7 @@ impl<'w> EntityMut<'w> {
|
|||
let old_archetype = &mut archetypes[old_archetype_id];
|
||||
let remove_result = old_archetype.swap_remove(old_location.index);
|
||||
if let Some(swapped_entity) = remove_result.swapped_entity {
|
||||
entities.meta[swapped_entity.id as usize].location = old_location;
|
||||
entities.meta[swapped_entity.index as usize].location = old_location;
|
||||
}
|
||||
let old_table_row = remove_result.table_row;
|
||||
let old_table_id = old_archetype.table_id();
|
||||
|
@ -403,7 +403,7 @@ impl<'w> EntityMut<'w> {
|
|||
};
|
||||
|
||||
*self_location = new_location;
|
||||
entities.meta[entity.id as usize].location = new_location;
|
||||
entities.meta[entity.index as usize].location = new_location;
|
||||
}
|
||||
|
||||
#[deprecated(
|
||||
|
@ -498,7 +498,7 @@ impl<'w> EntityMut<'w> {
|
|||
}
|
||||
let remove_result = archetype.swap_remove(location.index);
|
||||
if let Some(swapped_entity) = remove_result.swapped_entity {
|
||||
world.entities.meta[swapped_entity.id as usize].location = location;
|
||||
world.entities.meta[swapped_entity.index as usize].location = location;
|
||||
}
|
||||
table_row = remove_result.table_row;
|
||||
|
||||
|
|
|
@ -483,7 +483,7 @@ impl World {
|
|||
// SAFETY: entity index was just allocated
|
||||
self.entities
|
||||
.meta
|
||||
.get_unchecked_mut(entity.id() as usize)
|
||||
.get_unchecked_mut(entity.index() as usize)
|
||||
.location = location;
|
||||
EntityMut::new(self, entity, location)
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@ use std::collections::BTreeMap;
|
|||
///
|
||||
/// # Entity Order
|
||||
///
|
||||
/// Extracted entities will always be stored in ascending order based on their [id](Entity::id).
|
||||
/// Extracted entities will always be stored in ascending order based on their [id](Entity::index).
|
||||
/// This means that inserting `Entity(1v0)` then `Entity(0v0)` will always result in the entities
|
||||
/// being ordered as `[Entity(0v0), Entity(1v0)]`.
|
||||
///
|
||||
|
@ -100,14 +100,14 @@ impl<'w> DynamicSceneBuilder<'w> {
|
|||
let type_registry = self.type_registry.read();
|
||||
|
||||
for entity in entities {
|
||||
let id = entity.id();
|
||||
let index = entity.index();
|
||||
|
||||
if self.entities.contains_key(&id) {
|
||||
if self.entities.contains_key(&index) {
|
||||
continue;
|
||||
}
|
||||
|
||||
let mut entry = DynamicEntity {
|
||||
entity: id,
|
||||
entity: index,
|
||||
components: Vec::new(),
|
||||
};
|
||||
|
||||
|
@ -125,8 +125,7 @@ impl<'w> DynamicSceneBuilder<'w> {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
self.entities.insert(id, entry);
|
||||
self.entities.insert(index, entry);
|
||||
}
|
||||
|
||||
drop(type_registry);
|
||||
|
@ -167,7 +166,7 @@ mod tests {
|
|||
let scene = builder.build();
|
||||
|
||||
assert_eq!(scene.entities.len(), 1);
|
||||
assert_eq!(scene.entities[0].entity, entity.id());
|
||||
assert_eq!(scene.entities[0].entity, entity.index());
|
||||
assert_eq!(scene.entities[0].components.len(), 1);
|
||||
assert!(scene.entities[0].components[0].represents::<ComponentA>());
|
||||
}
|
||||
|
@ -188,7 +187,7 @@ mod tests {
|
|||
let scene = builder.build();
|
||||
|
||||
assert_eq!(scene.entities.len(), 1);
|
||||
assert_eq!(scene.entities[0].entity, entity.id());
|
||||
assert_eq!(scene.entities[0].entity, entity.index());
|
||||
assert_eq!(scene.entities[0].components.len(), 1);
|
||||
assert!(scene.entities[0].components[0].represents::<ComponentA>());
|
||||
}
|
||||
|
@ -212,7 +211,7 @@ mod tests {
|
|||
let scene = builder.build();
|
||||
|
||||
assert_eq!(scene.entities.len(), 1);
|
||||
assert_eq!(scene.entities[0].entity, entity.id());
|
||||
assert_eq!(scene.entities[0].entity, entity.index());
|
||||
assert_eq!(scene.entities[0].components.len(), 2);
|
||||
assert!(scene.entities[0].components[0].represents::<ComponentA>());
|
||||
assert!(scene.entities[0].components[1].represents::<ComponentB>());
|
||||
|
@ -239,10 +238,10 @@ mod tests {
|
|||
let mut entities = builder.build().entities.into_iter();
|
||||
|
||||
// Assert entities are ordered
|
||||
assert_eq!(entity_a.id(), entities.next().map(|e| e.entity).unwrap());
|
||||
assert_eq!(entity_b.id(), entities.next().map(|e| e.entity).unwrap());
|
||||
assert_eq!(entity_c.id(), entities.next().map(|e| e.entity).unwrap());
|
||||
assert_eq!(entity_d.id(), entities.next().map(|e| e.entity).unwrap());
|
||||
assert_eq!(entity_a.index(), entities.next().map(|e| e.entity).unwrap());
|
||||
assert_eq!(entity_b.index(), entities.next().map(|e| e.entity).unwrap());
|
||||
assert_eq!(entity_c.index(), entities.next().map(|e| e.entity).unwrap());
|
||||
assert_eq!(entity_d.index(), entities.next().map(|e| e.entity).unwrap());
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -269,6 +268,6 @@ mod tests {
|
|||
assert_eq!(scene.entities.len(), 2);
|
||||
let mut scene_entities = vec![scene.entities[0].entity, scene.entities[1].entity];
|
||||
scene_entities.sort();
|
||||
assert_eq!(scene_entities, [entity_a_b.id(), entity_a.id()]);
|
||||
assert_eq!(scene_entities, [entity_a_b.index(), entity_a.index()]);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -525,7 +525,7 @@ pub fn queue_sprites(
|
|||
);
|
||||
|
||||
view_entities.clear();
|
||||
view_entities.extend(visible_entities.entities.iter().map(|e| e.id() as usize));
|
||||
view_entities.extend(visible_entities.entities.iter().map(|e| e.index() as usize));
|
||||
transparent_phase.items.reserve(extracted_sprites.len());
|
||||
|
||||
// Impossible starting values that will be replaced on the first iteration
|
||||
|
@ -541,7 +541,7 @@ pub fn queue_sprites(
|
|||
// Batches are merged later (in `batch_phase_system()`), so that they can be interrupted
|
||||
// by any other phase item (and they can interrupt other items from batching).
|
||||
for extracted_sprite in extracted_sprites.iter() {
|
||||
if !view_entities.contains(extracted_sprite.entity.id() as usize) {
|
||||
if !view_entities.contains(extracted_sprite.entity.index() as usize) {
|
||||
continue;
|
||||
}
|
||||
let new_batch = SpriteBatch {
|
||||
|
|
|
@ -76,7 +76,7 @@ fn load_scene_system(mut commands: Commands, asset_server: Res<AssetServer>) {
|
|||
// load_scene_example.scn. You should immediately see the changes appear in the console.
|
||||
fn log_system(query: Query<(Entity, &ComponentA), Changed<ComponentA>>) {
|
||||
for (entity, component_a) in &query {
|
||||
info!(" Entity({})", entity.id());
|
||||
info!(" Entity({})", entity.index());
|
||||
info!(
|
||||
" ComponentA: {{ x: {} y: {} }}\n",
|
||||
component_a.x, component_a.y
|
||||
|
|
Loading…
Reference in a new issue