From 301440ff373e1db87d54cb9ace0559931e8b10e1 Mon Sep 17 00:00:00 2001 From: Stefan Seemayer Date: Sat, 23 Oct 2021 16:46:39 +0200 Subject: [PATCH 01/10] impl<'c> IntoIterator for &'c Components This allows iteration over all `Component`s registered in a world by implementing `IntoIterator` for the `Components` type. --- crates/bevy_ecs/src/component.rs | 44 ++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/crates/bevy_ecs/src/component.rs b/crates/bevy_ecs/src/component.rs index fdcb2a0d0d974..a177b2b100214 100644 --- a/crates/bevy_ecs/src/component.rs +++ b/crates/bevy_ecs/src/component.rs @@ -403,6 +403,16 @@ impl Components { } } +impl<'c> IntoIterator for &'c Components { + type Item = &'c ComponentInfo; + + type IntoIter = std::slice::Iter<'c, ComponentInfo>; + + fn into_iter(self) -> Self::IntoIter { + self.components.iter() + } +} + /// Records when a component was added and when it was last mutably dereferenced (or added). #[derive(Copy, Clone, Debug)] pub struct ComponentTicks { @@ -483,3 +493,37 @@ fn check_tick(last_change_tick: &mut u32, change_tick: u32) { *last_change_tick = change_tick.wrapping_sub(MAX_CHANGE_AGE); } } + +#[cfg(test)] +mod tests { + use crate::{ + self as bevy_ecs, + component::{Component, ComponentInfo}, + world::World, + }; + + #[derive(Component)] + struct W(T); + + #[test] + fn components_iteration() { + let mut world = World::default(); + world.spawn().insert(W(42u32)).insert(W(12.3f32)); + world.spawn().insert(W(123u32)).insert(W(true)); + + let component_names: Vec<&str> = world + .components() + .into_iter() + .map(|ci: &ComponentInfo| ci.name()) + .collect(); + + assert_eq!( + component_names, + vec![ + "bevy_ecs::component::tests::W", + "bevy_ecs::component::tests::W", + "bevy_ecs::component::tests::W" + ] + ); + } +} From 044428ab432a476333dac880f15700d8c539319c Mon Sep 17 00:00:00 2001 From: Stefan Seemayer Date: Sun, 24 Oct 2021 18:10:18 +0200 Subject: [PATCH 02/10] Rename `Components` to `WorldData` the Components struct was not just storing metadata on components, but also on resources. WorldData is a new umbrella term for components and resources. also rename the following: `ComponentId` -> `DataId` `ComponentInfo` -> `DataInfo` `ComponentDescriptor` -> `DataDescriptor` --- crates/bevy_ecs/macros/src/fetch.rs | 4 +- crates/bevy_ecs/macros/src/lib.rs | 8 +- crates/bevy_ecs/src/archetype.rs | 41 ++--- crates/bevy_ecs/src/bundle.rs | 36 ++-- crates/bevy_ecs/src/component.rs | 130 +++++++------- crates/bevy_ecs/src/lib.rs | 24 +-- crates/bevy_ecs/src/query/fetch.rs | 40 ++--- crates/bevy_ecs/src/query/filter.rs | 24 +-- crates/bevy_ecs/src/query/state.rs | 4 +- crates/bevy_ecs/src/schedule/stage.rs | 8 +- .../bevy_ecs/src/schedule/system_container.rs | 8 +- crates/bevy_ecs/src/storage/sparse_set.rs | 12 +- crates/bevy_ecs/src/storage/table.rs | 24 +-- crates/bevy_ecs/src/system/function_system.rs | 6 +- crates/bevy_ecs/src/system/mod.rs | 13 +- crates/bevy_ecs/src/system/query.rs | 4 +- crates/bevy_ecs/src/system/system.rs | 4 +- crates/bevy_ecs/src/system/system_chaining.rs | 6 +- crates/bevy_ecs/src/system/system_param.rs | 48 ++--- crates/bevy_ecs/src/world/entity_ref.rs | 68 +++---- crates/bevy_ecs/src/world/mod.rs | 166 ++++++++---------- crates/bevy_ecs/src/world/spawn_batch.rs | 4 +- crates/bevy_ecs/src/world/world_cell.rs | 21 +-- crates/bevy_scene/src/dynamic_scene.rs | 2 +- crates/bevy_scene/src/scene_spawner.rs | 2 +- crates/bevy_time/src/fixed_timestep.rs | 4 +- 26 files changed, 340 insertions(+), 371 deletions(-) diff --git a/crates/bevy_ecs/macros/src/fetch.rs b/crates/bevy_ecs/macros/src/fetch.rs index 50adea5691e2e..68d76b1b791a4 100644 --- a/crates/bevy_ecs/macros/src/fetch.rs +++ b/crates/bevy_ecs/macros/src/fetch.rs @@ -271,7 +271,7 @@ pub fn derive_world_query_impl(ast: DeriveInput) -> TokenStream { } } - fn update_component_access(&self, _access: &mut #path::query::FilteredAccess<#path::component::ComponentId>) { + fn update_component_access(&self, _access: &mut #path::query::FilteredAccess<#path::component::DataId>) { #(self.#field_idents.update_component_access(_access);)* } @@ -279,7 +279,7 @@ pub fn derive_world_query_impl(ast: DeriveInput) -> TokenStream { #(self.#field_idents.update_archetype_component_access(_archetype, _access);)* } - fn matches_component_set(&self, _set_contains_id: &impl Fn(#path::component::ComponentId) -> bool) -> bool { + fn matches_component_set(&self, _set_contains_id: &impl Fn(#path::component::DataId) -> bool) -> bool { true #(&& self.#field_idents.matches_component_set(_set_contains_id))* } diff --git a/crates/bevy_ecs/macros/src/lib.rs b/crates/bevy_ecs/macros/src/lib.rs index 3273faf9ab1a2..7ef28e8625962 100644 --- a/crates/bevy_ecs/macros/src/lib.rs +++ b/crates/bevy_ecs/macros/src/lib.rs @@ -144,12 +144,12 @@ pub fn derive_bundle(input: TokenStream) -> TokenStream { let struct_name = &ast.ident; TokenStream::from(quote! { - /// SAFE: ComponentId is returned in field-definition-order. [from_components] and [get_components] use field-definition-order + /// SAFE: DataId is returned in field-definition-order. [from_components] and [get_components] use field-definition-order unsafe impl #impl_generics #ecs_path::bundle::Bundle for #struct_name #ty_generics #where_clause { fn component_ids( - components: &mut #ecs_path::component::Components, + components: &mut #ecs_path::component::WorldData, storages: &mut #ecs_path::storage::Storages, - ) -> Vec<#ecs_path::component::ComponentId> { + ) -> Vec<#ecs_path::component::DataId> { let mut component_ids = Vec::with_capacity(#field_len); #(#field_component_ids)* component_ids @@ -219,7 +219,7 @@ pub fn impl_param_set(_input: TokenStream) -> TokenStream { where #(#param_fetch: ReadOnlySystemParamFetch,)* { } - // SAFE: Relevant parameter ComponentId and ArchetypeComponentId access is applied to SystemMeta. If any ParamState conflicts + // SAFE: Relevant parameter DataId and ArchetypeComponentId access is applied to SystemMeta. If any ParamState conflicts // with any prior access, a panic will occur. unsafe impl<#(#param_fetch: for<'w1, 's1> SystemParamFetch<'w1, 's1>,)*> SystemParamState for ParamSetState<(#(#param_fetch,)*)> diff --git a/crates/bevy_ecs/src/archetype.rs b/crates/bevy_ecs/src/archetype.rs index ab33119a93be6..b17012d6482bd 100644 --- a/crates/bevy_ecs/src/archetype.rs +++ b/crates/bevy_ecs/src/archetype.rs @@ -3,7 +3,7 @@ use crate::{ bundle::BundleId, - component::{ComponentId, StorageType}, + component::{DataId, StorageType}, entity::{Entity, EntityLocation}, storage::{Column, SparseArray, SparseSet, SparseSetIndex, TableId}, }; @@ -120,18 +120,18 @@ 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, + table_components: Box<[DataId]>, + sparse_set_components: Box<[DataId]>, + pub(crate) unique_components: SparseSet, + pub(crate) components: SparseSet, } impl Archetype { pub fn new( id: ArchetypeId, table_id: TableId, - table_components: Box<[ComponentId]>, - sparse_set_components: Box<[ComponentId]>, + table_components: Box<[DataId]>, + sparse_set_components: Box<[DataId]>, table_archetype_components: Vec, sparse_set_archetype_components: Vec, ) -> Self { @@ -197,27 +197,27 @@ impl Archetype { } #[inline] - pub fn table_components(&self) -> &[ComponentId] { + pub fn table_components(&self) -> &[DataId] { &self.table_components } #[inline] - pub fn sparse_set_components(&self) -> &[ComponentId] { + pub fn sparse_set_components(&self) -> &[DataId] { &self.sparse_set_components } #[inline] - pub fn unique_components(&self) -> &SparseSet { + pub fn unique_components(&self) -> &SparseSet { &self.unique_components } #[inline] - pub fn unique_components_mut(&mut self) -> &mut SparseSet { + pub fn unique_components_mut(&mut self) -> &mut SparseSet { &mut self.unique_components } #[inline] - pub fn components(&self) -> impl Iterator + '_ { + pub fn components(&self) -> impl Iterator + '_ { self.components.indices() } @@ -285,22 +285,19 @@ impl Archetype { } #[inline] - pub fn contains(&self, component_id: ComponentId) -> bool { + pub fn contains(&self, component_id: DataId) -> bool { self.components.contains(component_id) } #[inline] - pub fn get_storage_type(&self, component_id: ComponentId) -> Option { + pub fn get_storage_type(&self, component_id: DataId) -> Option { self.components .get(component_id) .map(|info| info.storage_type) } #[inline] - pub fn get_archetype_component_id( - &self, - component_id: ComponentId, - ) -> Option { + pub fn get_archetype_component_id(&self, component_id: DataId) -> Option { self.components .get(component_id) .map(|info| info.archetype_component_id) @@ -330,8 +327,8 @@ impl ArchetypeGeneration { #[derive(Hash, PartialEq, Eq)] pub struct ArchetypeIdentity { - table_components: Box<[ComponentId]>, - sparse_set_components: Box<[ComponentId]>, + table_components: Box<[DataId]>, + sparse_set_components: Box<[DataId]>, } #[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)] @@ -473,8 +470,8 @@ impl Archetypes { pub(crate) fn get_id_or_insert( &mut self, table_id: TableId, - table_components: Vec, - sparse_set_components: Vec, + 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(); diff --git a/crates/bevy_ecs/src/bundle.rs b/crates/bevy_ecs/src/bundle.rs index 6b81435fc8b4b..1215c9f51217f 100644 --- a/crates/bevy_ecs/src/bundle.rs +++ b/crates/bevy_ecs/src/bundle.rs @@ -6,7 +6,7 @@ pub use bevy_ecs_macros::Bundle; use crate::{ archetype::{AddBundle, Archetype, ArchetypeId, Archetypes, ComponentStatus}, - component::{Component, ComponentId, ComponentTicks, Components, StorageType}, + component::{Component, ComponentTicks, DataId, StorageType, WorldData}, entity::{Entities, Entity, EntityLocation}, storage::{SparseSetIndex, SparseSets, Storages, Table}, }; @@ -72,26 +72,26 @@ use std::{any::TypeId, collections::HashMap}; /// /// # Safety /// -/// - [`Bundle::component_ids`] must return the [`ComponentId`] for each component type in the +/// - [`Bundle::component_ids`] must return the [`DataId`] for each component type in the /// bundle, in the _exact_ order that [`Bundle::get_components`] is called. -/// - [`Bundle::from_components`] must call `func` exactly once for each [`ComponentId`] returned by +/// - [`Bundle::from_components`] must call `func` exactly once for each [`DataId`] returned by /// [`Bundle::component_ids`]. pub unsafe trait Bundle: Send + Sync + 'static { - /// Gets this [`Bundle`]'s component ids, in the order of this bundle's [`Component`]s - fn component_ids(components: &mut Components, storages: &mut Storages) -> Vec; + /// Gets this [`Bundle`]'s component ids, in the order of this bundle's [`WorldData`]s + fn component_ids(components: &mut WorldData, storages: &mut Storages) -> Vec; /// Calls `func`, which should return data for each component in the bundle, in the order of - /// this bundle's [`Component`]s + /// this bundle's [`WorldData`]s /// /// # Safety /// Caller must return data for each component in the bundle, in the order of this bundle's - /// [`Component`]s + /// [`WorldData`]s unsafe fn from_components(ctx: &mut T, func: F) -> Self where F: FnMut(&mut T) -> OwningPtr<'_>, Self: Sized; - /// Calls `func` on each value, in the order of this bundle's [`Component`]s. This will + /// Calls `func` on each value, in the order of this bundle's [`WorldData`]s. This will /// [`std::mem::forget`] the bundle fields, so callers are responsible for dropping the fields /// if that is desirable. fn get_components(self, func: impl FnMut(OwningPtr<'_>)); @@ -101,7 +101,7 @@ macro_rules! tuple_impl { ($($name: ident),*) => { unsafe impl<$($name: Component),*> Bundle for ($($name,)*) { #[allow(unused_variables)] - fn component_ids(components: &mut Components, storages: &mut Storages) -> Vec { + fn component_ids(components: &mut WorldData, storages: &mut Storages) -> Vec { vec![$(components.init_component::<$name>(storages)),*] } @@ -152,7 +152,7 @@ impl SparseSetIndex for BundleId { pub struct BundleInfo { pub(crate) id: BundleId, - pub(crate) component_ids: Vec, + pub(crate) component_ids: Vec, pub(crate) storage_types: Vec, } @@ -163,7 +163,7 @@ impl BundleInfo { } #[inline] - pub fn components(&self) -> &[ComponentId] { + pub fn components(&self) -> &[DataId] { &self.component_ids } @@ -176,7 +176,7 @@ impl BundleInfo { &'b self, entities: &'a mut Entities, archetypes: &'a mut Archetypes, - components: &mut Components, + components: &mut WorldData, storages: &'a mut Storages, archetype_id: ArchetypeId, change_tick: u32, @@ -236,7 +236,7 @@ impl BundleInfo { &'b self, entities: &'a mut Entities, archetypes: &'a mut Archetypes, - components: &mut Components, + components: &mut WorldData, storages: &'a mut Storages, change_tick: u32, ) -> BundleSpawner<'a, 'b> { @@ -309,7 +309,7 @@ impl BundleInfo { &self, archetypes: &mut Archetypes, storages: &mut Storages, - components: &mut Components, + components: &mut WorldData, archetype_id: ArchetypeId, ) -> ArchetypeId { if let Some(add_bundle) = archetypes[archetype_id].edges().get_add_bundle(self.id) { @@ -592,7 +592,7 @@ impl Bundles { pub(crate) fn init_info<'a, T: Bundle>( &'a mut self, - components: &mut Components, + components: &mut WorldData, storages: &mut Storages, ) -> &'a BundleInfo { let bundle_infos = &mut self.bundle_infos; @@ -613,12 +613,12 @@ impl Bundles { /// # Safety /// -/// `component_id` must be valid [`ComponentId`]'s +/// `component_id` must be valid [`DataId`]'s unsafe fn initialize_bundle( bundle_type_name: &'static str, - component_ids: Vec, + component_ids: Vec, id: BundleId, - components: &mut Components, + components: &mut WorldData, ) -> BundleInfo { let mut storage_types = Vec::new(); diff --git a/crates/bevy_ecs/src/component.rs b/crates/bevy_ecs/src/component.rs index a177b2b100214..4d8d76594c12a 100644 --- a/crates/bevy_ecs/src/component.rs +++ b/crates/bevy_ecs/src/component.rs @@ -86,14 +86,14 @@ impl Default for StorageType { } #[derive(Debug)] -pub struct ComponentInfo { - id: ComponentId, - descriptor: ComponentDescriptor, +pub struct DataInfo { + id: DataId, + descriptor: DataDescriptor, } -impl ComponentInfo { +impl DataInfo { #[inline] - pub fn id(&self) -> ComponentId { + pub fn id(&self) -> DataId { self.id } @@ -133,18 +133,18 @@ impl ComponentInfo { self.descriptor.is_send_and_sync } - fn new(id: ComponentId, descriptor: ComponentDescriptor) -> Self { - ComponentInfo { id, descriptor } + fn new(id: DataId, descriptor: DataDescriptor) -> Self { + DataInfo { id, descriptor } } } #[derive(Debug, Copy, Clone, Hash, Ord, PartialOrd, Eq, PartialEq)] -pub struct ComponentId(usize); +pub struct DataId(usize); -impl ComponentId { +impl DataId { #[inline] - pub const fn new(index: usize) -> ComponentId { - ComponentId(index) + pub const fn new(index: usize) -> DataId { + DataId(index) } #[inline] @@ -153,7 +153,7 @@ impl ComponentId { } } -impl SparseSetIndex for ComponentId { +impl SparseSetIndex for DataId { #[inline] fn sparse_set_index(&self) -> usize { self.index() @@ -164,7 +164,7 @@ impl SparseSetIndex for ComponentId { } } -pub struct ComponentDescriptor { +pub struct DataDescriptor { name: Cow<'static, str>, // SAFETY: This must remain private. It must match the statically known StorageType of the // associated rust component type if one exists. @@ -181,9 +181,9 @@ pub struct ComponentDescriptor { } // We need to ignore the `drop` field in our `Debug` impl -impl std::fmt::Debug for ComponentDescriptor { +impl std::fmt::Debug for DataDescriptor { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.debug_struct("ComponentDescriptor") + f.debug_struct("DataDescriptor") .field("name", &self.name) .field("storage_type", &self.storage_type) .field("is_send_and_sync", &self.is_send_and_sync) @@ -193,7 +193,7 @@ impl std::fmt::Debug for ComponentDescriptor { } } -impl ComponentDescriptor { +impl DataDescriptor { // SAFETY: The pointer points to a valid value of type `T` and it is safe to drop this value. unsafe fn drop_ptr(x: OwningPtr<'_>) { x.drop_as::(); @@ -276,45 +276,41 @@ impl ComponentDescriptor { } #[derive(Debug, Default)] -pub struct Components { - components: Vec, +pub struct WorldData { + data: Vec, indices: std::collections::HashMap, resource_indices: std::collections::HashMap, } -impl Components { +impl WorldData { #[inline] - pub fn init_component(&mut self, storages: &mut Storages) -> ComponentId { + pub fn init_component(&mut self, storages: &mut Storages) -> DataId { let type_id = TypeId::of::(); - let Components { - indices, - components, - .. - } = self; + let WorldData { indices, data, .. } = self; let index = indices.entry(type_id).or_insert_with(|| { - Components::init_component_inner(components, storages, ComponentDescriptor::new::()) + WorldData::init_component_inner(data, storages, DataDescriptor::new::()) }); - ComponentId(*index) + DataId(*index) } pub fn init_component_with_descriptor( &mut self, storages: &mut Storages, - descriptor: ComponentDescriptor, - ) -> ComponentId { - let index = Components::init_component_inner(&mut self.components, storages, descriptor); - ComponentId(index) + descriptor: DataDescriptor, + ) -> DataId { + let index = WorldData::init_component_inner(&mut self.data, storages, descriptor); + DataId(index) } #[inline] fn init_component_inner( - components: &mut Vec, + components: &mut Vec, storages: &mut Storages, - descriptor: ComponentDescriptor, + descriptor: DataDescriptor, ) -> usize { let index = components.len(); - let info = ComponentInfo::new(ComponentId(index), descriptor); + let info = DataInfo::new(DataId(index), descriptor); if info.descriptor.storage_type == StorageType::SparseSet { storages.sparse_sets.get_or_insert(&info); } @@ -324,92 +320,92 @@ impl Components { #[inline] pub fn len(&self) -> usize { - self.components.len() + self.data.len() } #[inline] pub fn is_empty(&self) -> bool { - self.components.len() == 0 + self.data.len() == 0 } #[inline] - pub fn get_info(&self, id: ComponentId) -> Option<&ComponentInfo> { - self.components.get(id.0) + pub fn get_info(&self, id: DataId) -> Option<&DataInfo> { + self.data.get(id.0) } /// # Safety /// - /// `id` must be a valid [`ComponentId`] + /// `id` must be a valid [DataId] #[inline] - pub unsafe fn get_info_unchecked(&self, id: ComponentId) -> &ComponentInfo { - debug_assert!(id.index() < self.components.len()); - self.components.get_unchecked(id.0) + pub unsafe fn get_info_unchecked(&self, id: DataId) -> &DataInfo { + debug_assert!(id.index() < self.data.len()); + self.data.get_unchecked(id.0) } #[inline] - pub fn get_id(&self, type_id: TypeId) -> Option { - self.indices.get(&type_id).map(|index| ComponentId(*index)) + pub fn get_id(&self, type_id: TypeId) -> Option { + self.indices.get(&type_id).map(|index| DataId(*index)) } #[inline] - pub fn get_resource_id(&self, type_id: TypeId) -> Option { + pub fn get_resource_id(&self, type_id: TypeId) -> Option { self.resource_indices .get(&type_id) - .map(|index| ComponentId(*index)) + .map(|index| DataId(*index)) } #[inline] - pub fn init_resource(&mut self) -> ComponentId { - // SAFE: The [`ComponentDescriptor`] matches the [`TypeId`] + pub fn init_resource(&mut self) -> DataId { + // SAFE: The [`DataDescriptor`] matches the [`TypeId`] unsafe { self.get_or_insert_resource_with(TypeId::of::(), || { - ComponentDescriptor::new_resource::() + DataDescriptor::new_resource::() }) } } #[inline] - pub fn init_non_send(&mut self) -> ComponentId { - // SAFE: The [`ComponentDescriptor`] matches the [`TypeId`] + pub fn init_non_send(&mut self) -> DataId { + // SAFE: The [`DataDescriptor`] matches the [`TypeId`] unsafe { self.get_or_insert_resource_with(TypeId::of::(), || { - ComponentDescriptor::new_non_send::(StorageType::default()) + DataDescriptor::new_non_send::(StorageType::default()) }) } } /// # Safety /// - /// The [`ComponentDescriptor`] must match the [`TypeId`] + /// The [`DataDescriptor`] must match the [`TypeId`] #[inline] unsafe fn get_or_insert_resource_with( &mut self, type_id: TypeId, - func: impl FnOnce() -> ComponentDescriptor, - ) -> ComponentId { - let components = &mut self.components; + func: impl FnOnce() -> DataDescriptor, + ) -> DataId { + let components = &mut self.data; let index = self.resource_indices.entry(type_id).or_insert_with(|| { let descriptor = func(); let index = components.len(); - components.push(ComponentInfo::new(ComponentId(index), descriptor)); + components.push(DataInfo::new(DataId(index), descriptor)); index }); - ComponentId(*index) + DataId(*index) } - pub fn iter(&self) -> impl Iterator + '_ { - self.components.iter() + pub fn iter(&self) -> impl Iterator + '_ { + self.data.iter() } } -impl<'c> IntoIterator for &'c Components { - type Item = &'c ComponentInfo; +impl<'c> IntoIterator for &'c WorldData { + type Item = &'c DataInfo; - type IntoIter = std::slice::Iter<'c, ComponentInfo>; + type IntoIter = std::slice::Iter<'c, DataInfo>; fn into_iter(self) -> Self::IntoIter { - self.components.iter() + self.data.iter() } } @@ -498,7 +494,7 @@ fn check_tick(last_change_tick: &mut u32, change_tick: u32) { mod tests { use crate::{ self as bevy_ecs, - component::{Component, ComponentInfo}, + component::{Component, DataInfo}, world::World, }; @@ -512,9 +508,9 @@ mod tests { world.spawn().insert(W(123u32)).insert(W(true)); let component_names: Vec<&str> = world - .components() + .data() .into_iter() - .map(|ci: &ComponentInfo| ci.name()) + .map(|ci: &DataInfo| ci.name()) .collect(); assert_eq!( diff --git a/crates/bevy_ecs/src/lib.rs b/crates/bevy_ecs/src/lib.rs index 56ac5db9acd94..8d7b2634b36a8 100644 --- a/crates/bevy_ecs/src/lib.rs +++ b/crates/bevy_ecs/src/lib.rs @@ -54,7 +54,7 @@ mod tests { use crate::prelude::Or; use crate::{ bundle::Bundle, - component::{Component, ComponentId}, + component::{Component, DataId}, entity::Entity, query::{Added, ChangeTrackers, Changed, FilteredAccess, With, Without, WorldQuery}, world::{Mut, World}, @@ -138,7 +138,7 @@ mod tests { } assert_eq!( - ::component_ids(&mut world.components, &mut world.storages), + ::component_ids(&mut world.data, &mut world.storages), vec![ world.init_component::(), world.init_component::(), @@ -186,7 +186,7 @@ mod tests { } assert_eq!( - ::component_ids(&mut world.components, &mut world.storages), + ::component_ids(&mut world.data, &mut world.storages), vec![ world.init_component::(), world.init_component::(), @@ -1009,10 +1009,7 @@ mod tests { assert!(!world.is_resource_changed::()); world.insert_resource(123); - let resource_id = world - .components() - .get_resource_id(TypeId::of::()) - .unwrap(); + let resource_id = world.data().get_resource_id(TypeId::of::()).unwrap(); let archetype_component_id = world .archetypes() .resource() @@ -1071,10 +1068,7 @@ mod tests { "other resources are unaffected" ); - let current_resource_id = world - .components() - .get_resource_id(TypeId::of::()) - .unwrap(); + let current_resource_id = world.data().get_resource_id(TypeId::of::()).unwrap(); assert_eq!( resource_id, current_resource_id, "resource id does not change after removing / re-adding" @@ -1290,14 +1284,14 @@ mod tests { let mut world = World::new(); let query = world.query_filtered::<&mut A, Changed>(); - let mut expected = FilteredAccess::::default(); - let a_id = world.components.get_id(TypeId::of::()).unwrap(); - let b_id = world.components.get_id(TypeId::of::()).unwrap(); + let mut expected = FilteredAccess::::default(); + let a_id = world.data.get_id(TypeId::of::()).unwrap(); + let b_id = world.data.get_id(TypeId::of::()).unwrap(); expected.add_write(a_id); expected.add_read(b_id); assert!( query.component_access.eq(&expected), - "ComponentId access from query fetch and query filter should be combined" + "DataId access from query fetch and query filter should be combined" ); } diff --git a/crates/bevy_ecs/src/query/fetch.rs b/crates/bevy_ecs/src/query/fetch.rs index fafd634f8a464..92341a76391a1 100644 --- a/crates/bevy_ecs/src/query/fetch.rs +++ b/crates/bevy_ecs/src/query/fetch.rs @@ -1,7 +1,7 @@ use crate::{ archetype::{Archetype, ArchetypeComponentId}, change_detection::Ticks, - component::{Component, ComponentId, ComponentStorage, ComponentTicks, StorageType}, + component::{Component, ComponentStorage, ComponentTicks, DataId, StorageType}, entity::Entity, query::{debug_checked_unreachable, Access, FilteredAccess}, storage::{ComponentSparseSet, Table, Tables}, @@ -425,13 +425,13 @@ pub trait Fetch<'world>: Sized { /// [`Fetch::table_fetch`]. pub unsafe trait FetchState: Send + Sync + Sized { fn init(world: &mut World) -> Self; - fn update_component_access(&self, access: &mut FilteredAccess); + fn update_component_access(&self, access: &mut FilteredAccess); fn update_archetype_component_access( &self, archetype: &Archetype, access: &mut Access, ); - fn matches_component_set(&self, set_contains_id: &impl Fn(ComponentId) -> bool) -> bool; + fn matches_component_set(&self, set_contains_id: &impl Fn(DataId) -> bool) -> bool; } /// A fetch that is read only. @@ -469,7 +469,7 @@ unsafe impl FetchState for EntityState { Self } - fn update_component_access(&self, _access: &mut FilteredAccess) {} + fn update_component_access(&self, _access: &mut FilteredAccess) {} fn update_archetype_component_access( &self, @@ -479,7 +479,7 @@ unsafe impl FetchState for EntityState { } #[inline] - fn matches_component_set(&self, _set_contains_id: &impl Fn(ComponentId) -> bool) -> bool { + fn matches_component_set(&self, _set_contains_id: &impl Fn(DataId) -> bool) -> bool { true } } @@ -546,7 +546,7 @@ impl WorldQuery for &T { /// The [`FetchState`] of `&T`. #[doc(hidden)] pub struct ReadState { - component_id: ComponentId, + component_id: DataId, marker: PhantomData, } @@ -561,7 +561,7 @@ unsafe impl FetchState for ReadState { } } - fn update_component_access(&self, access: &mut FilteredAccess) { + fn update_component_access(&self, access: &mut FilteredAccess) { assert!( !access.access().has_write(self.component_id), "&{} conflicts with a previous access in this query. Shared access cannot coincide with exclusive access.", @@ -582,7 +582,7 @@ unsafe impl FetchState for ReadState { } } - fn matches_component_set(&self, set_contains_id: &impl Fn(ComponentId) -> bool) -> bool { + fn matches_component_set(&self, set_contains_id: &impl Fn(DataId) -> bool) -> bool { set_contains_id(self.component_id) } } @@ -779,7 +779,7 @@ impl Clone for ReadOnlyWriteFetch<'_, T> { /// The [`FetchState`] of `&mut T`. #[doc(hidden)] pub struct WriteState { - component_id: ComponentId, + component_id: DataId, marker: PhantomData, } @@ -794,7 +794,7 @@ unsafe impl FetchState for WriteState { } } - fn update_component_access(&self, access: &mut FilteredAccess) { + fn update_component_access(&self, access: &mut FilteredAccess) { assert!( !access.access().has_read(self.component_id), "&mut {} conflicts with a previous access in this query. Mutable component access must be unique.", @@ -815,7 +815,7 @@ unsafe impl FetchState for WriteState { } } - fn matches_component_set(&self, set_contains_id: &impl Fn(ComponentId) -> bool) -> bool { + fn matches_component_set(&self, set_contains_id: &impl Fn(DataId) -> bool) -> bool { set_contains_id(self.component_id) } } @@ -1076,7 +1076,7 @@ unsafe impl FetchState for OptionState { } } - fn update_component_access(&self, access: &mut FilteredAccess) { + fn update_component_access(&self, access: &mut FilteredAccess) { // We don't want to add the `with`/`without` of `T` as `Option` will match things regardless of // `T`'s filters. for example `Query<(Option<&U>, &mut V)>` will match every entity with a `V` component // regardless of whether it has a `U` component. If we dont do this the query will not conflict with @@ -1100,7 +1100,7 @@ unsafe impl FetchState for OptionState { } } - fn matches_component_set(&self, _set_contains_id: &impl Fn(ComponentId) -> bool) -> bool { + fn matches_component_set(&self, _set_contains_id: &impl Fn(DataId) -> bool) -> bool { true } } @@ -1250,7 +1250,7 @@ impl WorldQuery for ChangeTrackers { /// The [`FetchState`] of [`ChangeTrackers`]. #[doc(hidden)] pub struct ChangeTrackersState { - component_id: ComponentId, + component_id: DataId, marker: PhantomData, } @@ -1265,7 +1265,7 @@ unsafe impl FetchState for ChangeTrackersState { } } - fn update_component_access(&self, access: &mut FilteredAccess) { + fn update_component_access(&self, access: &mut FilteredAccess) { assert!( !access.access().has_write(self.component_id), "ChangeTrackers<{}> conflicts with a previous access in this query. Shared access cannot coincide with exclusive access.", @@ -1286,7 +1286,7 @@ unsafe impl FetchState for ChangeTrackersState { } } - fn matches_component_set(&self, set_contains_id: &impl Fn(ComponentId) -> bool) -> bool { + fn matches_component_set(&self, set_contains_id: &impl Fn(DataId) -> bool) -> bool { set_contains_id(self.component_id) } } @@ -1526,7 +1526,7 @@ macro_rules! impl_tuple_fetch { ($($name::init(_world),)*) } - fn update_component_access(&self, _access: &mut FilteredAccess) { + fn update_component_access(&self, _access: &mut FilteredAccess) { let ($($name,)*) = self; $($name.update_component_access(_access);)* } @@ -1536,7 +1536,7 @@ macro_rules! impl_tuple_fetch { $($name.update_archetype_component_access(_archetype, _access);)* } - fn matches_component_set(&self, _set_contains_id: &impl Fn(ComponentId) -> bool) -> bool { + fn matches_component_set(&self, _set_contains_id: &impl Fn(DataId) -> bool) -> bool { let ($($name,)*) = self; true $(&& $name.matches_component_set(_set_contains_id))* } @@ -1644,7 +1644,7 @@ macro_rules! impl_anytuple_fetch { AnyOf(($($name::init(_world),)*)) } - fn update_component_access(&self, _access: &mut FilteredAccess) { + fn update_component_access(&self, _access: &mut FilteredAccess) { let ($($name,)*) = &self.0; // We do not unconditionally add `$name`'s `with`/`without` accesses to `_access` @@ -1684,7 +1684,7 @@ macro_rules! impl_anytuple_fetch { } )* } - fn matches_component_set(&self, _set_contains_id: &impl Fn(ComponentId) -> bool) -> bool { + fn matches_component_set(&self, _set_contains_id: &impl Fn(DataId) -> bool) -> bool { let ($($name,)*) = &self.0; false $(|| $name.matches_component_set(_set_contains_id))* } diff --git a/crates/bevy_ecs/src/query/filter.rs b/crates/bevy_ecs/src/query/filter.rs index f7ef292d6b10f..2a6d2cdc94614 100644 --- a/crates/bevy_ecs/src/query/filter.rs +++ b/crates/bevy_ecs/src/query/filter.rs @@ -1,6 +1,6 @@ use crate::{ archetype::{Archetype, ArchetypeComponentId}, - component::{Component, ComponentId, ComponentStorage, ComponentTicks, StorageType}, + component::{Component, ComponentStorage, ComponentTicks, DataId, StorageType}, entity::Entity, query::{ debug_checked_unreachable, Access, Fetch, FetchState, FilteredAccess, QueryFetch, @@ -64,7 +64,7 @@ pub struct WithFetch { /// The [`FetchState`] of [`With`]. #[doc(hidden)] pub struct WithState { - component_id: ComponentId, + component_id: DataId, marker: PhantomData, } @@ -79,7 +79,7 @@ unsafe impl FetchState for WithState { } #[inline] - fn update_component_access(&self, access: &mut FilteredAccess) { + fn update_component_access(&self, access: &mut FilteredAccess) { access.add_with(self.component_id); } @@ -91,7 +91,7 @@ unsafe impl FetchState for WithState { ) { } - fn matches_component_set(&self, set_contains_id: &impl Fn(ComponentId) -> bool) -> bool { + fn matches_component_set(&self, set_contains_id: &impl Fn(DataId) -> bool) -> bool { set_contains_id(self.component_id) } } @@ -204,7 +204,7 @@ pub struct WithoutFetch { /// The [`FetchState`] of [`Without`]. #[doc(hidden)] pub struct WithoutState { - component_id: ComponentId, + component_id: DataId, marker: PhantomData, } @@ -219,7 +219,7 @@ unsafe impl FetchState for WithoutState { } #[inline] - fn update_component_access(&self, access: &mut FilteredAccess) { + fn update_component_access(&self, access: &mut FilteredAccess) { access.add_without(self.component_id); } @@ -230,7 +230,7 @@ unsafe impl FetchState for WithoutState { _access: &mut Access, ) { } - fn matches_component_set(&self, set_contains_id: &impl Fn(ComponentId) -> bool) -> bool { + fn matches_component_set(&self, set_contains_id: &impl Fn(DataId) -> bool) -> bool { !set_contains_id(self.component_id) } } @@ -433,7 +433,7 @@ macro_rules! impl_query_filter_tuple { Or(($($filter::init(world),)*)) } - fn update_component_access(&self, access: &mut FilteredAccess) { + fn update_component_access(&self, access: &mut FilteredAccess) { let ($($filter,)*) = &self.0; // We do not unconditionally add `$filter`'s `with`/`without` accesses to `access` @@ -470,7 +470,7 @@ macro_rules! impl_query_filter_tuple { $($filter.update_archetype_component_access(archetype, access);)* } - fn matches_component_set(&self, _set_contains_id: &impl Fn(ComponentId) -> bool) -> bool { + fn matches_component_set(&self, _set_contains_id: &impl Fn(DataId) -> bool) -> bool { let ($($filter,)*) = &self.0; false $(|| $filter.matches_component_set(_set_contains_id))* } @@ -511,7 +511,7 @@ macro_rules! impl_tick_filter { #[doc(hidden)] $(#[$state_meta])* pub struct $state_name { - component_id: ComponentId, + component_id: DataId, marker: PhantomData, } @@ -533,7 +533,7 @@ macro_rules! impl_tick_filter { } #[inline] - fn update_component_access(&self, access: &mut FilteredAccess) { + fn update_component_access(&self, access: &mut FilteredAccess) { if access.access().has_write(self.component_id) { panic!("$state_name<{}> conflicts with a previous access in this query. Shared access cannot coincide with exclusive access.", std::any::type_name::()); @@ -552,7 +552,7 @@ macro_rules! impl_tick_filter { } } - fn matches_component_set(&self, set_contains_id: &impl Fn(ComponentId) -> bool) -> bool { + fn matches_component_set(&self, set_contains_id: &impl Fn(DataId) -> bool) -> bool { set_contains_id(self.component_id) } } diff --git a/crates/bevy_ecs/src/query/state.rs b/crates/bevy_ecs/src/query/state.rs index 64a80313c69f1..ab1b9bf321791 100644 --- a/crates/bevy_ecs/src/query/state.rs +++ b/crates/bevy_ecs/src/query/state.rs @@ -1,6 +1,6 @@ use crate::{ archetype::{Archetype, ArchetypeComponentId, ArchetypeGeneration, ArchetypeId}, - component::ComponentId, + component::DataId, entity::Entity, prelude::FromWorld, query::{ @@ -26,7 +26,7 @@ pub struct QueryState { pub(crate) matched_tables: FixedBitSet, pub(crate) matched_archetypes: FixedBitSet, pub(crate) archetype_component_access: Access, - pub(crate) component_access: FilteredAccess, + pub(crate) component_access: FilteredAccess, // NOTE: we maintain both a TableId bitset and a vec because iterating the vec is faster pub(crate) matched_table_ids: Vec, // NOTE: we maintain both a ArchetypeId bitset and a vec because iterating the vec is faster diff --git a/crates/bevy_ecs/src/schedule/stage.rs b/crates/bevy_ecs/src/schedule/stage.rs index ff26ced892a6f..4af7a2b4a321e 100644 --- a/crates/bevy_ecs/src/schedule/stage.rs +++ b/crates/bevy_ecs/src/schedule/stage.rs @@ -1,6 +1,6 @@ use crate::{ change_detection::CHECK_TICK_THRESHOLD, - component::ComponentId, + component::DataId, prelude::IntoSystem, schedule::{ graph_utils::{self, DependencyGraphError}, @@ -501,7 +501,7 @@ impl SystemStage { fn write_display_names_of_pairs( string: &mut String, systems: &[impl SystemContainer], - mut ambiguities: Vec<(usize, usize, Vec)>, + mut ambiguities: Vec<(usize, usize, Vec)>, world: &World, ) { for (index_a, index_b, conflicts) in ambiguities.drain(..) { @@ -515,7 +515,7 @@ impl SystemStage { if !conflicts.is_empty() { let names = conflicts .iter() - .map(|id| world.components().get_info(*id).unwrap().name()) + .map(|id| world.data().get_info(*id).unwrap().name()) .collect::>(); writeln!(string, " conflicts: {:?}", names).unwrap(); } @@ -689,7 +689,7 @@ fn process_systems( /// Returns vector containing all pairs of indices of systems with ambiguous execution order, /// along with specific components that have triggered the warning. /// Systems must be topologically sorted beforehand. -fn find_ambiguities(systems: &[impl SystemContainer]) -> Vec<(usize, usize, Vec)> { +fn find_ambiguities(systems: &[impl SystemContainer]) -> Vec<(usize, usize, Vec)> { let mut ambiguity_set_labels = HashMap::default(); for set in systems.iter().flat_map(|c| c.ambiguity_sets()) { let len = ambiguity_set_labels.len(); diff --git a/crates/bevy_ecs/src/schedule/system_container.rs b/crates/bevy_ecs/src/schedule/system_container.rs index 108e391d606f8..16ae9e0b55b43 100644 --- a/crates/bevy_ecs/src/schedule/system_container.rs +++ b/crates/bevy_ecs/src/schedule/system_container.rs @@ -1,5 +1,5 @@ use crate::{ - component::ComponentId, + component::DataId, query::Access, schedule::{ BoxedAmbiguitySetLabel, BoxedRunCriteriaLabel, BoxedSystemLabel, ExclusiveSystemDescriptor, @@ -21,7 +21,7 @@ pub trait SystemContainer: GraphNode