Skip to content

Commit 571b3ba

Browse files
authored
Remove ArchetypeComponentId and archetype_component_access (#19143)
# Objective Remove `ArchetypeComponentId` and `archetype_component_access`. Following #16885, they are no longer used by the engine, so we can stop spending time calculating them or space storing them. ## Solution Remove `ArchetypeComponentId` and everything that touches it. The `System::update_archetype_component_access` method no longer needs to update `archetype_component_access`. We do still need to update query caches, but we no longer need to do so *before* running the system. We'd have to touch every caller anyway if we gave the method a better name, so just remove `System::update_archetype_component_access` and `SystemParam::new_archetype` entirely, and update the query cache in `Query::get_param`. The `Single` and `Populated` params also need their query caches updated in `SystemParam::validate_param`, so change `validate_param` to take `&mut Self::State` instead of `&Self::State`.
1 parent 2946de4 commit 571b3ba

File tree

31 files changed

+161
-963
lines changed

31 files changed

+161
-963
lines changed

benches/benches/bevy_ecs/iteration/heavy_compute.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,6 @@ pub fn heavy_compute(c: &mut Criterion) {
4545

4646
let mut system = IntoSystem::into_system(sys);
4747
system.initialize(&mut world);
48-
system.update_archetype_component_access(world.as_unsafe_world_cell());
4948

5049
b.iter(move || system.run((), &mut world));
5150
});

benches/benches/bevy_ecs/iteration/iter_simple_system.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,6 @@ impl Benchmark {
3737

3838
let mut system = IntoSystem::into_system(query_system);
3939
system.initialize(&mut world);
40-
system.update_archetype_component_access(world.as_unsafe_world_cell());
4140
Self(world, Box::new(system))
4241
}
4342

crates/bevy_ecs/macros/src/lib.rs

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -432,11 +432,6 @@ pub fn derive_system_param(input: TokenStream) -> TokenStream {
432432
}
433433
}
434434

435-
unsafe fn new_archetype(state: &mut Self::State, archetype: &#path::archetype::Archetype, system_meta: &mut #path::system::SystemMeta) {
436-
// SAFETY: The caller ensures that `archetype` is from the World the state was initialized from in `init_state`.
437-
unsafe { <#fields_alias::<'_, '_, #punctuated_generic_idents> as #path::system::SystemParam>::new_archetype(&mut state.state, archetype, system_meta) }
438-
}
439-
440435
fn apply(state: &mut Self::State, system_meta: &#path::system::SystemMeta, world: &mut #path::world::World) {
441436
<#fields_alias::<'_, '_, #punctuated_generic_idents> as #path::system::SystemParam>::apply(&mut state.state, system_meta, world);
442437
}
@@ -447,7 +442,7 @@ pub fn derive_system_param(input: TokenStream) -> TokenStream {
447442

448443
#[inline]
449444
unsafe fn validate_param<'w, 's>(
450-
state: &'s Self::State,
445+
state: &'s mut Self::State,
451446
_system_meta: &#path::system::SystemMeta,
452447
_world: #path::world::unsafe_world_cell::UnsafeWorldCell<'w>,
453448
) -> Result<(), #path::system::SystemParamValidationError> {

crates/bevy_ecs/macros/src/world_query.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ pub(crate) fn world_query_impl(
9292
}
9393
}
9494

95-
// SAFETY: `update_component_access` and `update_archetype_component_access` are called on every field
95+
// SAFETY: `update_component_access` is called on every field
9696
unsafe impl #user_impl_generics #path::query::WorldQuery
9797
for #struct_name #user_ty_generics #user_where_clauses {
9898

crates/bevy_ecs/src/archetype.rs

Lines changed: 7 additions & 113 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ use crate::{
2424
component::{ComponentId, Components, RequiredComponentConstructor, StorageType},
2525
entity::{Entity, EntityLocation},
2626
observer::Observers,
27-
storage::{ImmutableSparseSet, SparseArray, SparseSet, SparseSetIndex, TableId, TableRow},
27+
storage::{ImmutableSparseSet, SparseArray, SparseSet, TableId, TableRow},
2828
};
2929
use alloc::{boxed::Box, vec::Vec};
3030
use bevy_platform::collections::HashMap;
@@ -349,7 +349,6 @@ pub(crate) struct ArchetypeSwapRemoveResult {
349349
/// [`Component`]: crate::component::Component
350350
struct ArchetypeComponentInfo {
351351
storage_type: StorageType,
352-
archetype_component_id: ArchetypeComponentId,
353352
}
354353

355354
bitflags::bitflags! {
@@ -394,14 +393,14 @@ impl Archetype {
394393
observers: &Observers,
395394
id: ArchetypeId,
396395
table_id: TableId,
397-
table_components: impl Iterator<Item = (ComponentId, ArchetypeComponentId)>,
398-
sparse_set_components: impl Iterator<Item = (ComponentId, ArchetypeComponentId)>,
396+
table_components: impl Iterator<Item = ComponentId>,
397+
sparse_set_components: impl Iterator<Item = ComponentId>,
399398
) -> Self {
400399
let (min_table, _) = table_components.size_hint();
401400
let (min_sparse, _) = sparse_set_components.size_hint();
402401
let mut flags = ArchetypeFlags::empty();
403402
let mut archetype_components = SparseSet::with_capacity(min_table + min_sparse);
404-
for (idx, (component_id, archetype_component_id)) in table_components.enumerate() {
403+
for (idx, component_id) in table_components.enumerate() {
405404
// SAFETY: We are creating an archetype that includes this component so it must exist
406405
let info = unsafe { components.get_info_unchecked(component_id) };
407406
info.update_archetype_flags(&mut flags);
@@ -410,7 +409,6 @@ impl Archetype {
410409
component_id,
411410
ArchetypeComponentInfo {
412411
storage_type: StorageType::Table,
413-
archetype_component_id,
414412
},
415413
);
416414
// NOTE: the `table_components` are sorted AND they were inserted in the `Table` in the same
@@ -422,7 +420,7 @@ impl Archetype {
422420
.insert(id, ArchetypeRecord { column: Some(idx) });
423421
}
424422

425-
for (component_id, archetype_component_id) in sparse_set_components {
423+
for component_id in sparse_set_components {
426424
// SAFETY: We are creating an archetype that includes this component so it must exist
427425
let info = unsafe { components.get_info_unchecked(component_id) };
428426
info.update_archetype_flags(&mut flags);
@@ -431,7 +429,6 @@ impl Archetype {
431429
component_id,
432430
ArchetypeComponentInfo {
433431
storage_type: StorageType::SparseSet,
434-
archetype_component_id,
435432
},
436433
);
437434
component_index
@@ -536,16 +533,6 @@ impl Archetype {
536533
self.components.len()
537534
}
538535

539-
/// Gets an iterator of all of the components in the archetype, along with
540-
/// their archetype component ID.
541-
pub(crate) fn components_with_archetype_component_id(
542-
&self,
543-
) -> impl Iterator<Item = (ComponentId, ArchetypeComponentId)> + '_ {
544-
self.components
545-
.iter()
546-
.map(|(component_id, info)| (*component_id, info.archetype_component_id))
547-
}
548-
549536
/// Fetches an immutable reference to the archetype's [`Edges`], a cache of
550537
/// archetypal relationships.
551538
#[inline]
@@ -664,19 +651,6 @@ impl Archetype {
664651
.map(|info| info.storage_type)
665652
}
666653

667-
/// Fetches the corresponding [`ArchetypeComponentId`] for a component in the archetype.
668-
/// Returns `None` if the component is not part of the archetype.
669-
/// This runs in `O(1)` time.
670-
#[inline]
671-
pub fn get_archetype_component_id(
672-
&self,
673-
component_id: ComponentId,
674-
) -> Option<ArchetypeComponentId> {
675-
self.components
676-
.get(component_id)
677-
.map(|info| info.archetype_component_id)
678-
}
679-
680654
/// Clears all entities from the archetype.
681655
pub(crate) fn clear_entities(&mut self) {
682656
self.entities.clear();
@@ -774,46 +748,6 @@ struct ArchetypeComponents {
774748
sparse_set_components: Box<[ComponentId]>,
775749
}
776750

777-
/// An opaque unique joint ID for a [`Component`] in an [`Archetype`] within a [`World`].
778-
///
779-
/// A component may be present within multiple archetypes, but each component within
780-
/// each archetype has its own unique `ArchetypeComponentId`. This is leveraged by the system
781-
/// schedulers to opportunistically run multiple systems in parallel that would otherwise
782-
/// conflict. For example, `Query<&mut A, With<B>>` and `Query<&mut A, Without<B>>` can run in
783-
/// parallel as the matched `ArchetypeComponentId` sets for both queries are disjoint, even
784-
/// though `&mut A` on both queries point to the same [`ComponentId`].
785-
///
786-
/// In SQL terms, these IDs are composite keys on a [many-to-many relationship] between archetypes
787-
/// and components. Each component type will have only one [`ComponentId`], but may have many
788-
/// [`ArchetypeComponentId`]s, one for every archetype the component is present in. Likewise, each
789-
/// archetype will have only one [`ArchetypeId`] but may have many [`ArchetypeComponentId`]s, one
790-
/// for each component that belongs to the archetype.
791-
///
792-
/// Every [`Resource`] is also assigned one of these IDs. As resources do not belong to any
793-
/// particular archetype, a resource's ID uniquely identifies it.
794-
///
795-
/// These IDs are only valid within a given World, and are not globally unique.
796-
/// Attempting to use an ID on a world that it wasn't sourced from will
797-
/// not point to the same archetype nor the same component.
798-
///
799-
/// [`Component`]: crate::component::Component
800-
/// [`World`]: crate::world::World
801-
/// [`Resource`]: crate::resource::Resource
802-
/// [many-to-many relationship]: https://en.wikipedia.org/wiki/Many-to-many_(data_model)
803-
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
804-
pub struct ArchetypeComponentId(usize);
805-
806-
impl SparseSetIndex for ArchetypeComponentId {
807-
#[inline]
808-
fn sparse_set_index(&self) -> usize {
809-
self.0
810-
}
811-
812-
fn get_sparse_set_index(value: usize) -> Self {
813-
Self(value)
814-
}
815-
}
816-
817751
/// Maps a [`ComponentId`] to the list of [`Archetypes`]([`Archetype`]) that contain the [`Component`](crate::component::Component),
818752
/// along with an [`ArchetypeRecord`] which contains some metadata about how the component is stored in the archetype.
819753
pub type ComponentIndex = HashMap<ComponentId, HashMap<ArchetypeId, ArchetypeRecord>>;
@@ -826,7 +760,6 @@ pub type ComponentIndex = HashMap<ComponentId, HashMap<ArchetypeId, ArchetypeRec
826760
/// [module level documentation]: crate::archetype
827761
pub struct Archetypes {
828762
pub(crate) archetypes: Vec<Archetype>,
829-
archetype_component_count: usize,
830763
/// find the archetype id by the archetype's components
831764
by_components: HashMap<ArchetypeComponents, ArchetypeId>,
832765
/// find all the archetypes that contain a component
@@ -850,7 +783,6 @@ impl Archetypes {
850783
archetypes: Vec::new(),
851784
by_components: Default::default(),
852785
by_component: Default::default(),
853-
archetype_component_count: 0,
854786
};
855787
// SAFETY: Empty archetype has no components
856788
unsafe {
@@ -905,22 +837,6 @@ impl Archetypes {
905837
}
906838
}
907839

908-
/// Generate and store a new [`ArchetypeComponentId`].
909-
///
910-
/// This simply increment the counter and return the new value.
911-
///
912-
/// # Panics
913-
///
914-
/// On archetype component id overflow.
915-
pub(crate) fn new_archetype_component_id(&mut self) -> ArchetypeComponentId {
916-
let id = ArchetypeComponentId(self.archetype_component_count);
917-
self.archetype_component_count = self
918-
.archetype_component_count
919-
.checked_add(1)
920-
.expect("archetype_component_count overflow");
921-
id
922-
}
923-
924840
/// Fetches an immutable reference to an [`Archetype`] using its
925841
/// ID. Returns `None` if no corresponding archetype exists.
926842
#[inline]
@@ -972,7 +888,6 @@ impl Archetypes {
972888
};
973889

974890
let archetypes = &mut self.archetypes;
975-
let archetype_component_count = &mut self.archetype_component_count;
976891
let component_index = &mut self.by_component;
977892
*self
978893
.by_components
@@ -983,40 +898,19 @@ impl Archetypes {
983898
sparse_set_components,
984899
} = identity;
985900
let id = ArchetypeId::new(archetypes.len());
986-
let table_start = *archetype_component_count;
987-
*archetype_component_count += table_components.len();
988-
let table_archetype_components =
989-
(table_start..*archetype_component_count).map(ArchetypeComponentId);
990-
let sparse_start = *archetype_component_count;
991-
*archetype_component_count += sparse_set_components.len();
992-
let sparse_set_archetype_components =
993-
(sparse_start..*archetype_component_count).map(ArchetypeComponentId);
994901
archetypes.push(Archetype::new(
995902
components,
996903
component_index,
997904
observers,
998905
id,
999906
table_id,
1000-
table_components
1001-
.iter()
1002-
.copied()
1003-
.zip(table_archetype_components),
1004-
sparse_set_components
1005-
.iter()
1006-
.copied()
1007-
.zip(sparse_set_archetype_components),
907+
table_components.iter().copied(),
908+
sparse_set_components.iter().copied(),
1008909
));
1009910
id
1010911
})
1011912
}
1012913

1013-
/// Returns the number of components that are stored in archetypes.
1014-
/// Note that if some component `T` is stored in more than one archetype, it will be counted once for each archetype it's present in.
1015-
#[inline]
1016-
pub fn archetype_components_len(&self) -> usize {
1017-
self.archetype_component_count
1018-
}
1019-
1020914
/// Clears all entities from all archetypes.
1021915
pub(crate) fn clear_entities(&mut self) {
1022916
for archetype in &mut self.archetypes {

crates/bevy_ecs/src/lib.rs

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1228,7 +1228,6 @@ mod tests {
12281228
.components()
12291229
.get_resource_id(TypeId::of::<Num>())
12301230
.unwrap();
1231-
let archetype_component_id = world.storages().resources.get(resource_id).unwrap().id();
12321231

12331232
assert_eq!(world.resource::<Num>().0, 123);
12341233
assert!(world.contains_resource::<Num>());
@@ -1290,14 +1289,6 @@ mod tests {
12901289
resource_id, current_resource_id,
12911290
"resource id does not change after removing / re-adding"
12921291
);
1293-
1294-
let current_archetype_component_id =
1295-
world.storages().resources.get(resource_id).unwrap().id();
1296-
1297-
assert_eq!(
1298-
archetype_component_id, current_archetype_component_id,
1299-
"resource archetype component id does not change after removing / re-adding"
1300-
);
13011292
}
13021293

13031294
#[test]

crates/bevy_ecs/src/observer/runner.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -366,13 +366,11 @@ fn observer_system_runner<E: Event, B: Bundle, S: ObserverSystem<E, B>>(
366366
};
367367

368368
// SAFETY:
369-
// - `update_archetype_component_access` is called first
370369
// - there are no outstanding references to world except a private component
371370
// - system is an `ObserverSystem` so won't mutate world beyond the access of a `DeferredWorld`
372371
// and is never exclusive
373372
// - system is the same type erased system from above
374373
unsafe {
375-
(*system).update_archetype_component_access(world);
376374
match (*system).validate_param_unsafe(world) {
377375
Ok(()) => {
378376
if let Err(err) = (*system).run_unsafe(trigger, world) {

0 commit comments

Comments
 (0)