From 5c598c206c03edd8c276a40b55828632263ee140 Mon Sep 17 00:00:00 2001 From: james7132 Date: Sat, 4 Jun 2022 04:48:12 -0700 Subject: [PATCH 1/2] Remove table and sparse set component IDs from Archetype --- crates/bevy_ecs/src/archetype.rs | 81 +++++++++++-------------- crates/bevy_ecs/src/bundle.rs | 4 +- crates/bevy_ecs/src/world/entity_ref.rs | 6 +- 3 files changed, 40 insertions(+), 51 deletions(-) diff --git a/crates/bevy_ecs/src/archetype.rs b/crates/bevy_ecs/src/archetype.rs index ab33119a93be6..8e5d65a76fb8f 100644 --- a/crates/bevy_ecs/src/archetype.rs +++ b/crates/bevy_ecs/src/archetype.rs @@ -120,8 +120,6 @@ pub struct Archetype { entities: Vec, edges: Edges, table_info: TableInfo, - table_components: Box<[ComponentId]>, - sparse_set_components: Box<[ComponentId]>, pub(crate) unique_components: SparseSet, pub(crate) components: SparseSet, } @@ -130,18 +128,15 @@ impl Archetype { pub fn new( id: ArchetypeId, table_id: TableId, - table_components: Box<[ComponentId]>, - sparse_set_components: Box<[ComponentId]>, - table_archetype_components: Vec, - sparse_set_archetype_components: Vec, + table_components: impl Iterator, + sparse_set_components: impl Iterator, ) -> Self { - let mut components = - SparseSet::with_capacity(table_components.len() + sparse_set_components.len()); - for (component_id, archetype_component_id) in - table_components.iter().zip(table_archetype_components) - { + let (min_table, _) = table_components.size_hint(); + let (min_sparse, _) = table_components.size_hint(); + let mut components = SparseSet::with_capacity(min_table + min_sparse); + for (component_id, archetype_component_id) in table_components { components.insert( - *component_id, + component_id, ArchetypeComponentInfo { storage_type: StorageType::Table, archetype_component_id, @@ -149,12 +144,9 @@ impl Archetype { ); } - for (component_id, archetype_component_id) in sparse_set_components - .iter() - .zip(sparse_set_archetype_components) - { + for (component_id, archetype_component_id) in sparse_set_components { components.insert( - *component_id, + component_id, ArchetypeComponentInfo { storage_type: StorageType::SparseSet, archetype_component_id, @@ -168,8 +160,6 @@ impl Archetype { entity_rows: Default::default(), }, components, - table_components, - sparse_set_components, unique_components: SparseSet::new(), entities: Default::default(), edges: Default::default(), @@ -197,13 +187,19 @@ impl Archetype { } #[inline] - pub fn table_components(&self) -> &[ComponentId] { - &self.table_components + pub fn table_components(&self) -> impl Iterator + '_ { + self.components + .iter() + .filter(|(_, component)| component.storage_type == StorageType::Table) + .map(|(id, _)| *id) } #[inline] - pub fn sparse_set_components(&self) -> &[ComponentId] { - &self.sparse_set_components + pub fn sparse_set_components(&self) -> impl Iterator + '_ { + self.components + .iter() + .filter(|(_, component)| component.storage_type == StorageType::SparseSet) + .map(|(id, _)| *id) } #[inline] @@ -380,10 +376,8 @@ impl Default for Archetypes { archetypes.archetypes.push(Archetype::new( ArchetypeId::RESOURCE, TableId::empty(), - Box::new([]), - Box::new([]), - Vec::new(), - Vec::new(), + std::iter::empty(), + std::iter::empty(), )); archetypes } @@ -476,38 +470,33 @@ impl Archetypes { table_components: Vec, sparse_set_components: Vec, ) -> ArchetypeId { - let table_components = table_components.into_boxed_slice(); - let sparse_set_components = sparse_set_components.into_boxed_slice(); let archetype_identity = ArchetypeIdentity { - sparse_set_components: sparse_set_components.clone(), - table_components: table_components.clone(), + sparse_set_components: sparse_set_components.clone().into_boxed_slice(), + table_components: table_components.clone().into_boxed_slice(), }; let archetypes = &mut self.archetypes; let archetype_component_count = &mut self.archetype_component_count; - let mut next_archetype_component_id = move || { - let id = ArchetypeComponentId(*archetype_component_count); - *archetype_component_count += 1; - id - }; *self .archetype_ids .entry(archetype_identity) .or_insert_with(move || { let id = ArchetypeId(archetypes.len()); - let table_archetype_components = (0..table_components.len()) - .map(|_| next_archetype_component_id()) - .collect(); - let sparse_set_archetype_components = (0..sparse_set_components.len()) - .map(|_| next_archetype_component_id()) - .collect(); + let table_start = *archetype_component_count; + *archetype_component_count += table_components.len(); + let table_archetype_components = + (table_start..*archetype_component_count).map(ArchetypeComponentId); + let sparse_start = *archetype_component_count; + *archetype_component_count += sparse_set_components.len(); + let sparse_set_archetype_components = + (sparse_start..*archetype_component_count).map(ArchetypeComponentId); archetypes.push(Archetype::new( id, table_id, - table_components, - sparse_set_components, - table_archetype_components, - sparse_set_archetype_components, + table_components.into_iter().zip(table_archetype_components), + sparse_set_components + .into_iter() + .zip(sparse_set_archetype_components), )); id }) diff --git a/crates/bevy_ecs/src/bundle.rs b/crates/bevy_ecs/src/bundle.rs index 6b81435fc8b4b..750039138f41c 100644 --- a/crates/bevy_ecs/src/bundle.rs +++ b/crates/bevy_ecs/src/bundle.rs @@ -349,7 +349,7 @@ impl BundleInfo { table_components = if new_table_components.is_empty() { // if there are no new table components, we can keep using this table table_id = current_archetype.table_id(); - current_archetype.table_components().to_vec() + current_archetype.table_components().collect() } else { new_table_components.extend(current_archetype.table_components()); // sort to ignore order while hashing @@ -365,7 +365,7 @@ impl BundleInfo { }; sparse_set_components = if new_sparse_set_components.is_empty() { - current_archetype.sparse_set_components().to_vec() + current_archetype.sparse_set_components().collect() } else { new_sparse_set_components.extend(current_archetype.sparse_set_components()); // sort to ignore order while hashing diff --git a/crates/bevy_ecs/src/world/entity_ref.rs b/crates/bevy_ecs/src/world/entity_ref.rs index bf2701714190d..d44faae2a1c93 100644 --- a/crates/bevy_ecs/src/world/entity_ref.rs +++ b/crates/bevy_ecs/src/world/entity_ref.rs @@ -467,7 +467,7 @@ impl<'w> EntityMut<'w> { table_row = remove_result.table_row; for component_id in archetype.sparse_set_components() { - let sparse_set = world.storages.sparse_sets.get_mut(*component_id).unwrap(); + let sparse_set = world.storages.sparse_sets.get_mut(component_id).unwrap(); sparse_set.remove(self.entity); } // SAFE: table rows stored in archetypes always exist @@ -789,8 +789,8 @@ unsafe fn remove_bundle_from_archetype( // components are already sorted removed_table_components.sort(); removed_sparse_set_components.sort(); - next_table_components = current_archetype.table_components().to_vec(); - next_sparse_set_components = current_archetype.sparse_set_components().to_vec(); + next_table_components = current_archetype.table_components().collect(); + next_sparse_set_components = current_archetype.sparse_set_components().collect(); sorted_remove(&mut next_table_components, &removed_table_components); sorted_remove( &mut next_sparse_set_components, From 71262b223be9dca05f0ef4503a04623b29534a02 Mon Sep 17 00:00:00 2001 From: James Liu Date: Mon, 31 Oct 2022 20:56:51 -0700 Subject: [PATCH 2/2] Use the correct size_hint Co-authored-by: Alice Cecile --- crates/bevy_ecs/src/archetype.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/bevy_ecs/src/archetype.rs b/crates/bevy_ecs/src/archetype.rs index b1900fb2e60b4..eac8fe5c567a3 100644 --- a/crates/bevy_ecs/src/archetype.rs +++ b/crates/bevy_ecs/src/archetype.rs @@ -162,7 +162,7 @@ impl Archetype { sparse_set_components: impl Iterator, ) -> Self { let (min_table, _) = table_components.size_hint(); - let (min_sparse, _) = table_components.size_hint(); + let (min_sparse, _) = sparse_set_components.size_hint(); let mut components = SparseSet::with_capacity(min_table + min_sparse); for (component_id, archetype_component_id) in table_components { components.insert(