From 7e44b37d81cc5ece85230445584c98be408e70df Mon Sep 17 00:00:00 2001 From: Zicklag Date: Sun, 4 Oct 2020 12:25:05 -0500 Subject: [PATCH] Implement Custom Component Ids This replaces the use of TypeId for identifying components and instead uses ComponentId which is an enum that can represent either a Rust TypeId or an external id represented by a u64. --- crates/bevy_ecs/hecs/macros/src/lib.rs | 22 +++--- crates/bevy_ecs/hecs/src/archetype.rs | 73 ++++++++++++------- crates/bevy_ecs/hecs/src/bundle.rs | 29 ++++---- crates/bevy_ecs/hecs/src/entity_builder.rs | 23 +++--- crates/bevy_ecs/hecs/src/lib.rs | 4 +- crates/bevy_ecs/hecs/src/world.rs | 65 +++++++++++++++-- .../bevy_ecs/src/resource/resource_query.rs | 8 +- crates/bevy_ecs/src/resource/resources.rs | 4 +- crates/bevy_ecs/src/system/system.rs | 14 ++-- crates/bevy_render/src/draw.rs | 16 ++-- crates/bevy_scene/src/scene.rs | 7 +- crates/bevy_scene/src/scene_spawner.rs | 2 +- 12 files changed, 179 insertions(+), 88 deletions(-) diff --git a/crates/bevy_ecs/hecs/macros/src/lib.rs b/crates/bevy_ecs/hecs/macros/src/lib.rs index 56660c1e899d0..826b7fcb4cb98 100644 --- a/crates/bevy_ecs/hecs/macros/src/lib.rs +++ b/crates/bevy_ecs/hecs/macros/src/lib.rs @@ -58,7 +58,7 @@ pub fn derive_bundle(input: TokenStream) -> TokenStream { let n = tys.len(); let code = quote! { impl #path::DynamicBundle for #ident { - fn with_ids(&self, f: impl FnOnce(&[std::any::TypeId]) -> T) -> T { + fn with_ids(&self, f: impl FnOnce(&[#path::ComponentId]) -> T) -> T { Self::with_static_ids(f) } @@ -66,9 +66,9 @@ pub fn derive_bundle(input: TokenStream) -> TokenStream { Self::static_type_info() } - unsafe fn put(mut self, mut f: impl FnMut(*mut u8, std::any::TypeId, usize) -> bool) { + unsafe fn put(mut self, mut f: impl FnMut(*mut u8, #path::ComponentId, usize) -> bool) { #( - if f((&mut self.#fields as *mut #tys).cast::(), std::any::TypeId::of::<#tys>(), std::mem::size_of::<#tys>()) { + if f((&mut self.#fields as *mut #tys).cast::(), std::any::TypeId::of::<#tys>().into(), std::mem::size_of::<#tys>()) { #[allow(clippy::forget_copy)] std::mem::forget(self.#fields); } @@ -77,22 +77,22 @@ pub fn derive_bundle(input: TokenStream) -> TokenStream { } impl #path::Bundle for #ident { - fn with_static_ids(f: impl FnOnce(&[std::any::TypeId]) -> T) -> T { + fn with_static_ids(f: impl FnOnce(&[#path::ComponentId]) -> T) -> T { use std::any::TypeId; use std::mem; #path::lazy_static::lazy_static! { - static ref ELEMENTS: [TypeId; #n] = { + static ref ELEMENTS: [#path::ComponentId; #n] = { let mut dedup = #path::bevy_utils::HashSet::default(); - for &(ty, name) in [#((std::any::TypeId::of::<#tys>(), std::any::type_name::<#tys>())),*].iter() { + for &(ty, name) in [#((#path::ComponentId::from(std::any::TypeId::of::<#tys>()), std::any::type_name::<#tys>())),*].iter() { if !dedup.insert(ty) { panic!("{} has multiple {} fields; each type must occur at most once!", stringify!(#ident), name); } } - let mut tys = [#((mem::align_of::<#tys>(), TypeId::of::<#tys>())),*]; + let mut tys = [#((mem::align_of::<#tys>(), #path::ComponentId::from(TypeId::of::<#tys>()))),*]; tys.sort_unstable_by(|x, y| x.0.cmp(&y.0).reverse().then(x.1.cmp(&y.1))); - let mut ids = [TypeId::of::<()>(); #n]; + let mut ids: [#path::ComponentId; #n] = [TypeId::of::<()>().into(); #n]; for (id, info) in ids.iter_mut().zip(tys.iter()) { *id = info.1; } @@ -104,16 +104,16 @@ pub fn derive_bundle(input: TokenStream) -> TokenStream { } fn static_type_info() -> Vec<#path::TypeInfo> { - let mut info = vec![#(#path::TypeInfo::of::<#tys>()),*]; + let mut info = vec![#(#path::TypeInfo::of::<#tys>().into()),*]; info.sort_unstable(); info } unsafe fn get( - mut f: impl FnMut(std::any::TypeId, usize) -> Option>, + mut f: impl FnMut(#path::ComponentId, usize) -> Option>, ) -> Result { #( - let #fields = f(std::any::TypeId::of::<#tys>(), std::mem::size_of::<#tys>()) + let #fields = f(std::any::TypeId::of::<#tys>().into(), std::mem::size_of::<#tys>()) .ok_or_else(#path::MissingComponent::new::<#tys>)? .cast::<#tys>() .as_ptr(); diff --git a/crates/bevy_ecs/hecs/src/archetype.rs b/crates/bevy_ecs/hecs/src/archetype.rs index 6e2847aef1ea9..438d59b6ae205 100644 --- a/crates/bevy_ecs/hecs/src/archetype.rs +++ b/crates/bevy_ecs/hecs/src/archetype.rs @@ -19,11 +19,12 @@ use crate::{ alloc::{alloc, dealloc, Layout}, vec::Vec, }, + world::ComponentId, Entity, }; use bevy_utils::{HashMap, HashMapExt}; use core::{ - any::{type_name, TypeId}, + any::TypeId, cell::UnsafeCell, mem, ptr::{self, NonNull}, @@ -38,7 +39,7 @@ use crate::{borrow::AtomicBorrow, query::Fetch, Access, Component, Query}; #[derive(Debug)] pub struct Archetype { types: Vec, - state: HashMap, + state: HashMap, len: usize, entities: Vec, // UnsafeCell allows unique references into `data` to be constructed while shared references @@ -93,23 +94,23 @@ impl Archetype { #[allow(missing_docs)] #[inline] pub fn has(&self) -> bool { - self.has_dynamic(TypeId::of::()) + self.has_dynamic(TypeId::of::().into()) } #[allow(missing_docs)] #[inline] - pub fn has_type(&self, ty: TypeId) -> bool { + pub fn has_component(&self, ty: ComponentId) -> bool { self.has_dynamic(ty) } - pub(crate) fn has_dynamic(&self, id: TypeId) -> bool { + pub(crate) fn has_dynamic(&self, id: ComponentId) -> bool { self.state.contains_key(&id) } #[allow(missing_docs)] #[inline] pub fn get(&self) -> Option> { - let state = self.state.get(&TypeId::of::())?; + let state = self.state.get(&TypeId::of::().into())?; Some(unsafe { NonNull::new_unchecked( (*self.data.get()).as_ptr().add(state.offset).cast::() as *mut T @@ -120,7 +121,7 @@ impl Archetype { #[allow(missing_docs)] #[inline] pub fn get_with_type_state(&self) -> Option<(NonNull, &TypeState)> { - let state = self.state.get(&TypeId::of::())?; + let state = self.state.get(&TypeId::of::().into())?; Some(unsafe { ( NonNull::new_unchecked( @@ -132,43 +133,57 @@ impl Archetype { } #[allow(missing_docs)] - pub fn get_type_state(&self, ty: TypeId) -> Option<&TypeState> { + pub fn get_type_state(&self, ty: ComponentId) -> Option<&TypeState> { self.state.get(&ty) } #[allow(missing_docs)] - pub fn get_type_state_mut(&mut self, ty: TypeId) -> Option<&mut TypeState> { + pub fn get_type_state_mut(&mut self, ty: ComponentId) -> Option<&mut TypeState> { self.state.get_mut(&ty) } #[allow(missing_docs)] #[inline] pub fn borrow(&self) { - if self - .state - .get(&TypeId::of::()) - .map_or(false, |x| !x.borrow.borrow()) - { - panic!("{} already borrowed uniquely", type_name::()); + self.borrow_component(std::any::TypeId::of::().into()) + } + + #[allow(missing_docs)] + #[inline] + pub fn borrow_component(&self, id: ComponentId) { + if self.state.get(&id).map_or(false, |x| !x.borrow.borrow()) { + panic!("{:?} already borrowed uniquely", id); } } #[allow(missing_docs)] #[inline] pub fn borrow_mut(&self) { + self.borrow_component_mut(std::any::TypeId::of::().into()) + } + + #[allow(missing_docs)] + #[inline] + pub fn borrow_component_mut(&self, id: ComponentId) { if self .state - .get(&TypeId::of::()) + .get(&id) .map_or(false, |x| !x.borrow.borrow_mut()) { - panic!("{} already borrowed", type_name::()); + panic!("{:?} already borrowed", id); } } #[allow(missing_docs)] #[inline] pub fn release(&self) { - if let Some(x) = self.state.get(&TypeId::of::()) { + self.release_component(std::any::TypeId::of::().into()); + } + + #[allow(missing_docs)] + #[inline] + pub fn release_component(&self, id: ComponentId) { + if let Some(x) = self.state.get(&id) { x.borrow.release(); } } @@ -176,7 +191,13 @@ impl Archetype { #[allow(missing_docs)] #[inline] pub fn release_mut(&self) { - if let Some(x) = self.state.get(&TypeId::of::()) { + self.release_component_mut(std::any::TypeId::of::().into()) + } + + #[allow(missing_docs)] + #[inline] + pub fn release_component_mut(&self, id: ComponentId) { + if let Some(x) = self.state.get(&id) { x.borrow.release_mut(); } } @@ -216,7 +237,7 @@ impl Archetype { /// `index` must be in-bounds pub(crate) unsafe fn get_dynamic( &self, - ty: TypeId, + ty: ComponentId, size: usize, index: usize, ) -> Option> { @@ -356,7 +377,7 @@ impl Archetype { pub(crate) unsafe fn move_to( &mut self, index: usize, - mut f: impl FnMut(*mut u8, TypeId, usize, bool, bool), + mut f: impl FnMut(*mut u8, ComponentId, usize, bool, bool), ) -> Option { let last = self.len - 1; for ty in &self.types { @@ -400,7 +421,7 @@ impl Archetype { pub unsafe fn put_dynamic( &mut self, component: *mut u8, - ty: TypeId, + ty: ComponentId, size: usize, index: usize, added: bool, @@ -484,7 +505,7 @@ impl TypeState { /// Metadata required to store a component #[derive(Debug, Copy, Clone)] pub struct TypeInfo { - id: TypeId, + id: ComponentId, layout: Layout, drop: unsafe fn(*mut u8), } @@ -497,7 +518,7 @@ impl TypeInfo { } Self { - id: TypeId::of::(), + id: TypeId::of::().into(), layout: Layout::new::(), drop: drop_ptr::, } @@ -505,7 +526,7 @@ impl TypeInfo { #[allow(missing_docs)] #[inline] - pub fn id(&self) -> TypeId { + pub fn id(&self) -> ComponentId { self.id } @@ -527,7 +548,7 @@ impl PartialOrd for TypeInfo { } impl Ord for TypeInfo { - /// Order by alignment, descending. Ties broken with TypeId. + /// Order by alignment, descending. Ties broken with ComponentId. fn cmp(&self, other: &Self) -> core::cmp::Ordering { self.layout .align() diff --git a/crates/bevy_ecs/hecs/src/bundle.rs b/crates/bevy_ecs/hecs/src/bundle.rs index 87b5f05667e3c..ced9312251d3b 100644 --- a/crates/bevy_ecs/hecs/src/bundle.rs +++ b/crates/bevy_ecs/hecs/src/bundle.rs @@ -14,7 +14,10 @@ // modified by Bevy contributors -use crate::alloc::{vec, vec::Vec}; +use crate::{ + alloc::{vec, vec::Vec}, + world::ComponentId, +}; use core::{ any::{type_name, TypeId}, fmt, mem, @@ -27,7 +30,7 @@ use crate::{archetype::TypeInfo, Component}; pub trait DynamicBundle { /// Invoke a callback on the fields' type IDs, sorted by descending alignment then id #[doc(hidden)] - fn with_ids(&self, f: impl FnOnce(&[TypeId]) -> T) -> T; + fn with_ids(&self, f: impl FnOnce(&[ComponentId]) -> T) -> T; /// Obtain the fields' TypeInfos, sorted by descending alignment then id #[doc(hidden)] fn type_info(&self) -> Vec; @@ -36,13 +39,13 @@ pub trait DynamicBundle { /// Must invoke `f` only with a valid pointer, its type, and the pointee's size. A `false` /// return value indicates that the value was not moved and should be dropped. #[doc(hidden)] - unsafe fn put(self, f: impl FnMut(*mut u8, TypeId, usize) -> bool); + unsafe fn put(self, f: impl FnMut(*mut u8, ComponentId, usize) -> bool); } /// A statically typed collection of components pub trait Bundle: DynamicBundle { #[doc(hidden)] - fn with_static_ids(f: impl FnOnce(&[TypeId]) -> T) -> T; + fn with_static_ids(f: impl FnOnce(&[ComponentId]) -> T) -> T; /// Obtain the fields' TypeInfos, sorted by descending alignment then id #[doc(hidden)] @@ -56,7 +59,7 @@ pub trait Bundle: DynamicBundle { /// pointers if any call to `f` returns `None`. #[doc(hidden)] unsafe fn get( - f: impl FnMut(TypeId, usize) -> Option>, + f: impl FnMut(ComponentId, usize) -> Option>, ) -> Result where Self: Sized; @@ -85,7 +88,7 @@ impl std::error::Error for MissingComponent {} macro_rules! tuple_impl { ($($name: ident),*) => { impl<$($name: Component),*> DynamicBundle for ($($name,)*) { - fn with_ids(&self, f: impl FnOnce(&[TypeId]) -> T) -> T { + fn with_ids(&self, f: impl FnOnce(&[ComponentId]) -> T) -> T { Self::with_static_ids(f) } @@ -94,13 +97,13 @@ macro_rules! tuple_impl { } #[allow(unused_variables, unused_mut)] - unsafe fn put(self, mut f: impl FnMut(*mut u8, TypeId, usize) -> bool) { + unsafe fn put(self, mut f: impl FnMut(*mut u8, ComponentId, usize) -> bool) { #[allow(non_snake_case)] let ($(mut $name,)*) = self; $( if f( (&mut $name as *mut $name).cast::(), - TypeId::of::<$name>(), + TypeId::of::<$name>().into(), mem::size_of::<$name>() ) { mem::forget($name) @@ -110,11 +113,11 @@ macro_rules! tuple_impl { } impl<$($name: Component),*> Bundle for ($($name,)*) { - fn with_static_ids(f: impl FnOnce(&[TypeId]) -> T) -> T { + fn with_static_ids(f: impl FnOnce(&[ComponentId]) -> T) -> T { const N: usize = count!($($name),*); - let mut xs: [(usize, TypeId); N] = [$((mem::align_of::<$name>(), TypeId::of::<$name>())),*]; + let mut xs: [(usize, ComponentId); N] = [$((mem::align_of::<$name>(), TypeId::of::<$name>().into())),*]; xs.sort_unstable_by(|x, y| x.0.cmp(&y.0).reverse().then(x.1.cmp(&y.1))); - let mut ids = [TypeId::of::<()>(); N]; + let mut ids = [TypeId::of::<()>().into(); N]; for (slot, &(_, id)) in ids.iter_mut().zip(xs.iter()) { *slot = id; } @@ -128,10 +131,10 @@ macro_rules! tuple_impl { } #[allow(unused_variables, unused_mut)] - unsafe fn get(mut f: impl FnMut(TypeId, usize) -> Option>) -> Result { + unsafe fn get(mut f: impl FnMut(ComponentId, usize) -> Option>) -> Result { #[allow(non_snake_case)] let ($(mut $name,)*) = ($( - f(TypeId::of::<$name>(), mem::size_of::<$name>()).ok_or_else(MissingComponent::new::<$name>)? + f(TypeId::of::<$name>().into(), mem::size_of::<$name>()).ok_or_else(MissingComponent::new::<$name>)? .as_ptr() .cast::<$name>(),)* ); diff --git a/crates/bevy_ecs/hecs/src/entity_builder.rs b/crates/bevy_ecs/hecs/src/entity_builder.rs index a27d7722cc1fb..28b24cd0ab498 100644 --- a/crates/bevy_ecs/hecs/src/entity_builder.rs +++ b/crates/bevy_ecs/hecs/src/entity_builder.rs @@ -14,11 +14,14 @@ // modified by Bevy contributors -use crate::alloc::{ - alloc::{alloc, dealloc, Layout}, - boxed::Box, - vec, - vec::Vec, +use crate::{ + alloc::{ + alloc::{alloc, dealloc, Layout}, + boxed::Box, + vec, + vec::Vec, + }, + world::ComponentId, }; use bevy_utils::HashSet; @@ -47,8 +50,8 @@ pub struct EntityBuilder { storage: Box<[MaybeUninit]>, cursor: usize, info: Vec<(TypeInfo, usize)>, - ids: Vec, - id_set: HashSet, + ids: Vec, + id_set: HashSet, } impl EntityBuilder { @@ -65,7 +68,7 @@ impl EntityBuilder { /// Add `component` to the entity pub fn add(&mut self, component: T) -> &mut Self { - if !self.id_set.insert(TypeId::of::()) { + if !self.id_set.insert(TypeId::of::().into()) { return self; } let end = self.cursor + mem::size_of::(); @@ -166,7 +169,7 @@ pub struct BuiltEntity<'a> { } impl DynamicBundle for BuiltEntity<'_> { - fn with_ids(&self, f: impl FnOnce(&[TypeId]) -> T) -> T { + fn with_ids(&self, f: impl FnOnce(&[ComponentId]) -> T) -> T { f(&self.builder.ids) } @@ -175,7 +178,7 @@ impl DynamicBundle for BuiltEntity<'_> { self.builder.info.iter().map(|x| x.0).collect() } - unsafe fn put(self, mut f: impl FnMut(*mut u8, TypeId, usize) -> bool) { + unsafe fn put(self, mut f: impl FnMut(*mut u8, ComponentId, usize) -> bool) { for (ty, offset) in self.builder.info.drain(..) { let ptr = self.builder.storage.as_mut_ptr().add(offset).cast(); if !f(ptr, ty.id(), ty.layout().size()) { diff --git a/crates/bevy_ecs/hecs/src/lib.rs b/crates/bevy_ecs/hecs/src/lib.rs index 7191b4358e13e..9dd23e973f262 100644 --- a/crates/bevy_ecs/hecs/src/lib.rs +++ b/crates/bevy_ecs/hecs/src/lib.rs @@ -85,7 +85,9 @@ pub use query::{ ReadOnlyFetch, With, Without, }; pub use query_one::QueryOne; -pub use world::{ArchetypesGeneration, Component, ComponentError, SpawnBatchIter, World}; +pub use world::{ + ArchetypesGeneration, Component, ComponentError, ComponentId, SpawnBatchIter, World, +}; // Unstable implementation details needed by the macros #[doc(hidden)] diff --git a/crates/bevy_ecs/hecs/src/world.rs b/crates/bevy_ecs/hecs/src/world.rs index 4613ffba79bac..fbd68544a7e56 100644 --- a/crates/bevy_ecs/hecs/src/world.rs +++ b/crates/bevy_ecs/hecs/src/world.rs @@ -19,7 +19,11 @@ use crate::{ EntityReserver, Mut, RefMut, }; use bevy_utils::{HashMap, HashSet}; -use core::{any::TypeId, fmt, mem, ptr}; +use core::{ + any::TypeId, + cmp::{Ord, Ordering}, + fmt, mem, ptr, +}; #[cfg(feature = "std")] use std::error::Error; @@ -41,8 +45,8 @@ use crate::{ #[derive(Debug)] pub struct World { entities: Entities, - index: HashMap, u32>, - removed_components: HashMap>, + index: HashMap, u32>, + removed_components: HashMap>, #[allow(missing_docs)] pub archetypes: Vec, archetype_generation: u64, @@ -219,10 +223,10 @@ impl World { } /// Returns true if the given entity has a component with the given type id. - pub fn has_component_type(&self, entity: Entity, ty: TypeId) -> bool { + pub fn has_component_type(&self, entity: Entity, ty: ComponentId) -> bool { self.get_entity_location(entity) .map(|location| &self.archetypes[location.archetype as usize]) - .map(|archetype| archetype.has_type(ty)) + .map(|archetype| archetype.has_component(ty)) .unwrap_or(false) } @@ -487,8 +491,13 @@ impl World { #[allow(missing_docs)] pub fn removed(&self) -> &[Entity] { + self.removed_component(std::any::TypeId::of::().into()) + } + + #[allow(missing_docs)] + pub fn removed_component(&self, id: ComponentId) -> &[Entity] { self.removed_components - .get(&TypeId::of::()) + .get(&id) .map_or(&[], |entities| entities.as_slice()) } @@ -904,6 +913,50 @@ impl From for ComponentError { } } +/// Uniquely identifies a type of component. This is conceptually similar to +/// Rust's [`TypeId`], but allows for external type IDs to be defined. +#[derive(Eq, PartialEq, Hash, Debug, Clone, Copy)] +pub enum ComponentId { + /// A Rust-native [`TypeId`] + RustTypeId(TypeId), + /// An arbitrary ID that allows you to identify types defined outside of + /// this Rust compilation + ExternalId(u64), +} + +impl Ord for ComponentId { + fn cmp(&self, other: &Self) -> Ordering { + if self == other { + Ordering::Equal + } else { + // Sort RustTypeId's as greater than external ids and then sort + // matching types by their default Ord implementation. + match self { + ComponentId::RustTypeId(lhs_rid) => match other { + ComponentId::RustTypeId(rhs_rid) => lhs_rid.cmp(rhs_rid), + ComponentId::ExternalId(_) => Ordering::Less, + }, + ComponentId::ExternalId(lhs_eid) => match other { + ComponentId::RustTypeId(_) => Ordering::Greater, + ComponentId::ExternalId(rhs_edi) => lhs_eid.cmp(rhs_edi), + }, + } + } + } +} + +impl PartialOrd for ComponentId { + fn partial_cmp(&self, other: &Self) -> Option { + Some(self.cmp(other)) + } +} + +impl From for ComponentId { + fn from(item: TypeId) -> Self { + ComponentId::RustTypeId(item) + } +} + /// Types that can be components, implemented automatically for all `Send + Sync + 'static` types /// /// This is just a convenient shorthand for `Send + Sync + 'static`, and never needs to be diff --git a/crates/bevy_ecs/src/resource/resource_query.rs b/crates/bevy_ecs/src/resource/resource_query.rs index 012116f9659b5..eb38cfeb9e8ee 100644 --- a/crates/bevy_ecs/src/resource/resource_query.rs +++ b/crates/bevy_ecs/src/resource/resource_query.rs @@ -219,7 +219,7 @@ impl<'a, T: Resource> FetchResource<'a> for FetchResourceRead { fn access() -> TypeAccess { let mut access = TypeAccess::default(); - access.immutable.insert(TypeId::of::()); + access.immutable.insert(TypeId::of::().into()); access } } @@ -253,7 +253,7 @@ impl<'a, T: Resource> FetchResource<'a> for FetchResourceChanged { fn access() -> TypeAccess { let mut access = TypeAccess::default(); - access.immutable.insert(TypeId::of::()); + access.immutable.insert(TypeId::of::().into()); access } } @@ -284,7 +284,7 @@ impl<'a, T: Resource> FetchResource<'a> for FetchResourceWrite { fn access() -> TypeAccess { let mut access = TypeAccess::default(); - access.mutable.insert(TypeId::of::()); + access.mutable.insert(TypeId::of::().into()); access } } @@ -325,7 +325,7 @@ impl<'a, T: Resource + FromResources> FetchResource<'a> for FetchResourceLocalMu fn access() -> TypeAccess { let mut access = TypeAccess::default(); - access.mutable.insert(TypeId::of::()); + access.mutable.insert(TypeId::of::().into()); access } } diff --git a/crates/bevy_ecs/src/resource/resources.rs b/crates/bevy_ecs/src/resource/resources.rs index 4b2992bc1834f..9f9b70199fa37 100644 --- a/crates/bevy_ecs/src/resource/resources.rs +++ b/crates/bevy_ecs/src/resource/resources.rs @@ -104,7 +104,7 @@ impl Resources { let resource_ptr = (&mut resource as *mut T).cast::(); archetype.put_dynamic( resource_ptr, - type_id, + type_id.into(), core::mem::size_of::(), index, added, @@ -203,7 +203,7 @@ impl Resources { ) -> (NonNull, NonNull) { self.get_resource_data_index::(resource_index) .and_then(|(data, index)| { - let type_state = data.archetype.get_type_state(TypeId::of::())?; + let type_state = data.archetype.get_type_state(TypeId::of::().into())?; Some(( NonNull::new_unchecked(type_state.added().as_ptr().add(index)), NonNull::new_unchecked(type_state.mutated().as_ptr().add(index)), diff --git a/crates/bevy_ecs/src/system/system.rs b/crates/bevy_ecs/src/system/system.rs index 983190470f52c..4fdf767bc3df2 100644 --- a/crates/bevy_ecs/src/system/system.rs +++ b/crates/bevy_ecs/src/system/system.rs @@ -1,8 +1,8 @@ use crate::resource::Resources; -use bevy_hecs::{Access, Query, World}; +use bevy_hecs::{Access, ComponentId, Query, World}; use bevy_utils::HashSet; use fixedbitset::FixedBitSet; -use std::{any::TypeId, borrow::Cow}; +use std::borrow::Cow; /// Determines the strategy used to run the `run_thread_local` function in a [System] #[derive(Copy, Clone, Eq, PartialEq, Debug)] @@ -81,8 +81,8 @@ impl ArchetypeAccess { /// Provides information about the types a [System] reads and writes #[derive(Debug, Default, Eq, PartialEq, Clone)] pub struct TypeAccess { - pub immutable: HashSet, - pub mutable: HashSet, + pub immutable: HashSet, + pub mutable: HashSet, } impl TypeAccess { @@ -145,9 +145,9 @@ mod tests { let access = <<(Res, ResMut, Res) as ResourceQuery>::Fetch as FetchResource>::access(); let mut expected_access = TypeAccess::default(); - expected_access.immutable.insert(TypeId::of::()); - expected_access.immutable.insert(TypeId::of::()); - expected_access.mutable.insert(TypeId::of::()); + expected_access.immutable.insert(TypeId::of::().into()); + expected_access.immutable.insert(TypeId::of::().into()); + expected_access.mutable.insert(TypeId::of::().into()); assert_eq!(access, expected_access); } } diff --git a/crates/bevy_render/src/draw.rs b/crates/bevy_render/src/draw.rs index a54db24fcee3c..aaacdfa187721 100644 --- a/crates/bevy_render/src/draw.rs +++ b/crates/bevy_render/src/draw.rs @@ -215,16 +215,20 @@ impl<'a> FetchResource<'a> for FetchDrawContext { let mut access = TypeAccess::default(); access .mutable - .insert(TypeId::of::>()); - access.mutable.insert(TypeId::of::>()); - access.mutable.insert(TypeId::of::()); + .insert(TypeId::of::>().into()); + access.mutable.insert(TypeId::of::>().into()); + access + .mutable + .insert(TypeId::of::().into()); + access + .immutable + .insert(TypeId::of::>().into()); access .immutable - .insert(TypeId::of::>()); + .insert(TypeId::of::().into()); access .immutable - .insert(TypeId::of::()); - access.immutable.insert(TypeId::of::()); + .insert(TypeId::of::().into()); access } } diff --git a/crates/bevy_scene/src/scene.rs b/crates/bevy_scene/src/scene.rs index 1db5561e3bcf4..10e115104269a 100644 --- a/crates/bevy_scene/src/scene.rs +++ b/crates/bevy_scene/src/scene.rs @@ -28,7 +28,12 @@ impl Scene { }) } for type_info in archetype.types() { - if let Some(component_registration) = component_registry.get(&type_info.id()) { + if let Some(component_registration) = + component_registry.get(&match type_info.id() { + bevy_ecs::ComponentId::RustTypeId(id) => id, + _ => todo!("Handle external ids in component registry"), + }) + { let properties = component_registration.get_component_properties(&archetype, index); diff --git a/crates/bevy_scene/src/scene_spawner.rs b/crates/bevy_scene/src/scene_spawner.rs index 4c581d91569b5..65a0c646ee095 100644 --- a/crates/bevy_scene/src/scene_spawner.rs +++ b/crates/bevy_scene/src/scene_spawner.rs @@ -111,7 +111,7 @@ impl SceneSpawner { .ok_or(SceneSpawnError::UnregisteredComponent { type_name: component.type_name.to_string(), })?; - if world.has_component_type(entity, component_registration.ty) { + if world.has_component_type(entity, component_registration.ty.into()) { if component.type_name != "Camera" { component_registration.apply_component_to_entity(world, entity, component); }