diff --git a/examples/custom_component.rs b/examples/custom_component.rs new file mode 100644 index 00000000..ea13584e --- /dev/null +++ b/examples/custom_component.rs @@ -0,0 +1,73 @@ +use shipyard::*; +use std::convert::TryInto; + +use std::collections::HashMap; + +struct Nothing; + +struct ScriptSystem { + name: String, +} + +fn main() { + // This stores our components by name + let mut components: HashMap = HashMap::new(); + + // Insert our custom components + components.insert( + "position".into(), + CustomComponent { + size: 32.try_into().unwrap(), + id: 0, + }, + ); + + components.insert( + "velocity".into(), + CustomComponent { + size: 16.try_into().unwrap(), + id: 1, + }, + ); + + // Create a custom system + let insert_pos_vel_sys = DynamicSystem { + data: (), + system_fn: |_, borrows| {}, + borrow_intents: vec![ + CustomComponentBorrowIntent { + component: components.get("velocity").unwrap().clone(), + mutation: Mutation::Shared, + }, + CustomComponentBorrowIntent { + component: components.get("position").unwrap().clone(), + mutation: Mutation::Unique, + }, + ], + }; + + let pos_vel_sys = DynamicSystem { + data: (), + system_fn: |_, borrows| { + // Need to do something like this, but I cant! + let velocities = borrows.get(0).unwrap().downcast::>().unwrap(); + let positions = borrows.get(1).unwrap().downcast::>().unwrap(); + + dbg!(velocities, positions); + }, + borrow_intents: vec![ + CustomComponentBorrowIntent { + component: components.get("velocity").unwrap().clone(), + mutation: Mutation::Shared, + }, + CustomComponentBorrowIntent { + component: components.get("position").unwrap().clone(), + mutation: Mutation::Unique, + }, + ], + }; + + let world = World::new(); + world.run(insert_pos_vel_sys); + world.run(pos_vel_sys); +} diff --git a/examples/hello_world.rs b/examples/hello_world.rs new file mode 100644 index 00000000..a2d36ac5 --- /dev/null +++ b/examples/hello_world.rs @@ -0,0 +1,45 @@ +use shipyard::*; + +#[derive(Debug)] +struct Position { + x: f32, + y: f32, +} + +struct Velocity { + x: f32, + y: f32, +} + +fn position_printer(positions: View) { + for pos in positions.iter() { + println!("position: {:?}", pos); + } +} + +fn velocity_handler(mut positions: ViewMut, velocities: View) { + for (mut pos, vel) in (&mut positions, &velocities).iter() { + pos.x += vel.x; + pos.y += vel.y; + } +} + +fn main() { + let world = World::new(); + + world.run( + |mut entities: EntitiesViewMut, + mut positions: ViewMut, + mut velocities: ViewMut| { + entities.add_entity( + (&mut positions, &mut velocities), + (Position { x: 10., y: 10. }, Velocity { x: 10., y: 10. }), + ); + }, + ); + + loop { + world.run(velocity_handler); + world.run(position_printer); + } +} diff --git a/src/borrow/mod.rs b/src/borrow/mod.rs index e57b01bb..02d45366 100644 --- a/src/borrow/mod.rs +++ b/src/borrow/mod.rs @@ -18,11 +18,12 @@ pub use non_sync::NonSync; use crate::atomic_refcell::AtomicRefCell; use crate::error; -use crate::storage::{AllStorages, Entities}; +use crate::storage::{AllStorages, Entities, StorageId}; #[cfg(feature = "parallel")] use crate::view::ThreadPoolView; use crate::view::{ - AllStoragesViewMut, EntitiesView, EntitiesViewMut, UniqueView, UniqueViewMut, View, ViewMut, + AllStoragesViewMut, DynamicView, DynamicViewMut, EntitiesView, EntitiesViewMut, UniqueView, + UniqueViewMut, View, ViewMut, }; use alloc::vec::Vec; use core::any::TypeId; @@ -34,6 +35,74 @@ pub enum Mutation { Unique, } +/// Like [`Borrow`] but it takes a reference to `self` so that the return values of the functions +/// can be based on the *instance* of the borrow object instead of the *type*. +pub trait DynamicBorrow<'a> { + fn try_borrow( + &self, + all_storages: &'a AtomicRefCell, + #[cfg(feature = "parallel")] thread_pool: &'a rayon::ThreadPool, + ) -> Result + where + Self: Sized; + + fn borrow_infos(&self, infos: &mut Vec<(StorageId, Mutation)>); + + fn is_send_sync(&self) -> bool; +} + +impl<'a, T: 'static + Send + Sync> DynamicBorrow<'a> for DynamicView<'a, T> { + fn try_borrow( + &self, + all_storages: &'a AtomicRefCell, + #[cfg(feature = "parallel")] thread_pool: &'a rayon::ThreadPool, + ) -> Result + where + Self: Sized, + { + Self::from_storage_atomic_ref( + all_storages + .try_borrow() + .map_err(error::GetStorage::AllStoragesBorrow)?, + self.storage_id, + ) + } + + fn borrow_infos(&self, infos: &mut Vec<(StorageId, Mutation)>) { + infos.push((self.storage_id, Mutation::Shared)); + } + + fn is_send_sync(&self) -> bool { + true + } +} + +impl<'a, T: 'static + Send + Sync> DynamicBorrow<'a> for DynamicViewMut<'a, T> { + fn try_borrow( + &self, + all_storages: &'a AtomicRefCell, + #[cfg(feature = "parallel")] thread_pool: &'a rayon::ThreadPool, + ) -> Result + where + Self: Sized, + { + Self::from_storage_atomic_ref( + all_storages + .try_borrow() + .map_err(error::GetStorage::AllStoragesBorrow)?, + self.storage_id, + ) + } + + fn borrow_infos(&self, infos: &mut Vec<(StorageId, Mutation)>) { + infos.push((self.storage_id, Mutation::Unique)); + } + + fn is_send_sync(&self) -> bool { + true + } +} + pub trait Borrow<'a> { fn try_borrow( all_storages: &'a AtomicRefCell, @@ -42,7 +111,7 @@ pub trait Borrow<'a> { where Self: Sized; - fn borrow_infos(infos: &mut Vec<(TypeId, Mutation)>); + fn borrow_infos(infos: &mut Vec<(StorageId, Mutation)>); fn is_send_sync() -> bool; } @@ -58,7 +127,7 @@ impl<'a> Borrow<'a> for () { Ok(()) } - fn borrow_infos(_: &mut Vec<(TypeId, Mutation)>) {} + fn borrow_infos(_: &mut Vec<(StorageId, Mutation)>) {} fn is_send_sync() -> bool { true @@ -73,8 +142,8 @@ impl<'a> Borrow<'a> for AllStoragesViewMut<'a> { all_storages.try_into() } - fn borrow_infos(infos: &mut Vec<(TypeId, Mutation)>) { - infos.push((TypeId::of::(), Mutation::Unique)); + fn borrow_infos(infos: &mut Vec<(StorageId, Mutation)>) { + infos.push((TypeId::of::().into(), Mutation::Unique)); } fn is_send_sync() -> bool { @@ -93,8 +162,8 @@ impl<'a> Borrow<'a> for EntitiesView<'a> { .try_into() } - fn borrow_infos(infos: &mut Vec<(TypeId, Mutation)>) { - infos.push((TypeId::of::(), Mutation::Shared)); + fn borrow_infos(infos: &mut Vec<(StorageId, Mutation)>) { + infos.push((TypeId::of::().into(), Mutation::Shared)); } fn is_send_sync() -> bool { @@ -113,8 +182,8 @@ impl<'a> Borrow<'a> for EntitiesViewMut<'a> { .try_into() } - fn borrow_infos(infos: &mut Vec<(TypeId, Mutation)>) { - infos.push((TypeId::of::(), Mutation::Unique)); + fn borrow_infos(infos: &mut Vec<(StorageId, Mutation)>) { + infos.push((TypeId::of::().into(), Mutation::Unique)); } fn is_send_sync() -> bool { @@ -131,7 +200,7 @@ impl<'a> Borrow<'a> for ThreadPoolView<'a> { Ok(ThreadPoolView(thread_pool)) } - fn borrow_infos(_: &mut Vec<(TypeId, Mutation)>) {} + fn borrow_infos(_: &mut Vec<(StorageId, Mutation)>) {} fn is_send_sync() -> bool { true @@ -149,8 +218,8 @@ impl<'a, T: 'static + Send + Sync> Borrow<'a> for View<'a, T> { .try_into() } - fn borrow_infos(infos: &mut Vec<(TypeId, Mutation)>) { - infos.push((TypeId::of::(), Mutation::Shared)); + fn borrow_infos(infos: &mut Vec<(StorageId, Mutation)>) { + infos.push((TypeId::of::().into(), Mutation::Shared)); } fn is_send_sync() -> bool { @@ -169,8 +238,8 @@ impl<'a, T: 'static + Send + Sync> Borrow<'a> for ViewMut<'a, T> { .try_into() } - fn borrow_infos(infos: &mut Vec<(TypeId, Mutation)>) { - infos.push((TypeId::of::(), Mutation::Unique)); + fn borrow_infos(infos: &mut Vec<(StorageId, Mutation)>) { + infos.push((TypeId::of::().into(), Mutation::Unique)); } fn is_send_sync() -> bool { @@ -189,7 +258,7 @@ impl<'a, T: 'static + Send + Sync> Borrow<'a> for UniqueView<'a, T> { .try_into() } - fn borrow_infos(infos: &mut Vec<(TypeId, Mutation)>) { + fn borrow_infos(infos: &mut Vec<(StorageId, Mutation)>) { as Borrow>::borrow_infos(infos) } @@ -209,7 +278,7 @@ impl<'a, T: 'static + Send + Sync> Borrow<'a> for UniqueViewMut<'a, T> { .try_into() } - fn borrow_infos(infos: &mut Vec<(TypeId, Mutation)>) { + fn borrow_infos(infos: &mut Vec<(StorageId, Mutation)>) { as Borrow>::borrow_infos(infos) } @@ -232,8 +301,8 @@ impl<'a, T: 'static + Sync> Borrow<'a> for NonSend> { .map(NonSend) } - fn borrow_infos(infos: &mut Vec<(TypeId, Mutation)>) { - infos.push((TypeId::of::(), Mutation::Unique)); + fn borrow_infos(infos: &mut Vec<(StorageId, Mutation)>) { + infos.push((TypeId::of::().into(), Mutation::Unique)); } fn is_send_sync() -> bool { @@ -255,8 +324,8 @@ impl<'a, T: 'static + Sync> Borrow<'a> for NonSend> { .map(NonSend) } - fn borrow_infos(infos: &mut Vec<(TypeId, Mutation)>) { - infos.push((TypeId::of::(), Mutation::Unique)); + fn borrow_infos(infos: &mut Vec<(StorageId, Mutation)>) { + infos.push((TypeId::of::().into(), Mutation::Unique)); } fn is_send_sync() -> bool { @@ -277,7 +346,7 @@ impl<'a, T: 'static + Sync> Borrow<'a> for NonSend> { .map(NonSend) } - fn borrow_infos(infos: &mut Vec<(TypeId, Mutation)>) { + fn borrow_infos(infos: &mut Vec<(StorageId, Mutation)>) { > as Borrow>::borrow_infos(infos) } @@ -299,7 +368,7 @@ impl<'a, T: 'static + Sync> Borrow<'a> for NonSend> { .map(NonSend) } - fn borrow_infos(infos: &mut Vec<(TypeId, Mutation)>) { + fn borrow_infos(infos: &mut Vec<(StorageId, Mutation)>) { > as Borrow>::borrow_infos(infos) } @@ -322,8 +391,8 @@ impl<'a, T: 'static + Send> Borrow<'a> for NonSync> { .map(NonSync) } - fn borrow_infos(infos: &mut Vec<(TypeId, Mutation)>) { - infos.push((TypeId::of::(), Mutation::Unique)); + fn borrow_infos(infos: &mut Vec<(StorageId, Mutation)>) { + infos.push((TypeId::of::().into(), Mutation::Unique)); } fn is_send_sync() -> bool { @@ -345,8 +414,8 @@ impl<'a, T: 'static + Send> Borrow<'a> for NonSync> { .map(NonSync) } - fn borrow_infos(infos: &mut Vec<(TypeId, Mutation)>) { - infos.push((TypeId::of::(), Mutation::Unique)); + fn borrow_infos(infos: &mut Vec<(StorageId, Mutation)>) { + infos.push((TypeId::of::().into(), Mutation::Unique)); } fn is_send_sync() -> bool { @@ -367,7 +436,7 @@ impl<'a, T: 'static + Send> Borrow<'a> for NonSync> { .map(NonSync) } - fn borrow_infos(infos: &mut Vec<(TypeId, Mutation)>) { + fn borrow_infos(infos: &mut Vec<(StorageId, Mutation)>) { > as Borrow>::borrow_infos(infos) } @@ -389,7 +458,7 @@ impl<'a, T: 'static + Send> Borrow<'a> for NonSync> { .map(NonSync) } - fn borrow_infos(infos: &mut Vec<(TypeId, Mutation)>) { + fn borrow_infos(infos: &mut Vec<(StorageId, Mutation)>) { > as Borrow>::borrow_infos(infos) } @@ -412,8 +481,8 @@ impl<'a, T: 'static> Borrow<'a> for NonSendSync> { .map(NonSendSync) } - fn borrow_infos(infos: &mut Vec<(TypeId, Mutation)>) { - infos.push((TypeId::of::(), Mutation::Unique)); + fn borrow_infos(infos: &mut Vec<(StorageId, Mutation)>) { + infos.push((TypeId::of::().into(), Mutation::Unique)); } fn is_send_sync() -> bool { @@ -435,8 +504,8 @@ impl<'a, T: 'static> Borrow<'a> for NonSendSync> { .map(NonSendSync) } - fn borrow_infos(infos: &mut Vec<(TypeId, Mutation)>) { - infos.push((TypeId::of::(), Mutation::Unique)); + fn borrow_infos(infos: &mut Vec<(StorageId, Mutation)>) { + infos.push((TypeId::of::().into(), Mutation::Unique)); } fn is_send_sync() -> bool { @@ -456,7 +525,7 @@ impl<'a, T: 'static> Borrow<'a> for NonSendSync> { .try_into() .map(NonSendSync) } - fn borrow_infos(infos: &mut Vec<(TypeId, Mutation)>) { + fn borrow_infos(infos: &mut Vec<(StorageId, Mutation)>) { > as Borrow>::borrow_infos(infos) } @@ -478,7 +547,7 @@ impl<'a, T: 'static> Borrow<'a> for NonSendSync> { .map(NonSendSync) } - fn borrow_infos(infos: &mut Vec<(TypeId, Mutation)>) { + fn borrow_infos(infos: &mut Vec<(StorageId, Mutation)>) { > as Borrow>::borrow_infos(infos) } @@ -495,8 +564,8 @@ impl<'a, T: 'static> Borrow<'a> for FakeBorrow { Ok(FakeBorrow::new()) } - fn borrow_infos(infos: &mut Vec<(TypeId, Mutation)>) { - infos.push((TypeId::of::(), Mutation::Unique)) + fn borrow_infos(infos: &mut Vec<(StorageId, Mutation)>) { + infos.push((TypeId::of::().into(), Mutation::Unique)) } fn is_send_sync() -> bool { @@ -525,7 +594,7 @@ macro_rules! impl_borrow { } } - fn borrow_infos(infos: &mut Vec<(TypeId, Mutation)>) { + fn borrow_infos(infos: &mut Vec<(StorageId, Mutation)>) { $( $type::borrow_infos(infos); )+ diff --git a/src/delete.rs b/src/delete.rs index f89ff85b..e8b704b1 100644 --- a/src/delete.rs +++ b/src/delete.rs @@ -55,9 +55,9 @@ macro_rules! impl_delete { fn try_delete(self, entity: EntityId) -> Result<(), error::Remove> { // non packed storages should not pay the price of pack if $(core::mem::discriminant(&self.$index.pack_info.pack) != core::mem::discriminant(&Pack::NoPack) || !self.$index.pack_info.observer_types.is_empty())||+ { - let mut types = [$(TypeId::of::<$type>()),+]; + let mut types = [$(TypeId::of::<$type>().into()),+]; types.sort_unstable(); - let mut add_types = [$(TypeId::of::<$add_type>()),*]; + let mut add_types = [$(TypeId::of::<$add_type>().into()),*]; add_types.sort_unstable(); let mut should_unpack = Vec::with_capacity(types.len() + add_types.len()); @@ -81,7 +81,7 @@ macro_rules! impl_delete { )+ $( - if should_unpack.contains(&TypeId::of::<$add_type>()) { + if should_unpack.contains(&TypeId::of::<$add_type>().into()) { self.$add_index.unpack(entity); } )* diff --git a/src/iter/into_abstract.rs b/src/iter/into_abstract.rs index baeef4b3..f66cfc36 100644 --- a/src/iter/into_abstract.rs +++ b/src/iter/into_abstract.rs @@ -1,6 +1,7 @@ use super::abstract_mut::AbstractMut; use crate::not::Not; use crate::sparse_set::{Pack, PackInfo, RawWindowMut, Window, WindowMut}; +use crate::storage::StorageId; use crate::view::{View, ViewMut}; use core::any::TypeId; @@ -14,7 +15,7 @@ pub trait IntoAbstract { fn into_abstract(self) -> Self::AbsView; fn len(&self) -> Option; fn pack_info(&self) -> &PackInfo; - fn type_id(&self) -> TypeId; + fn storage_id(&self) -> StorageId; fn modified(&self) -> usize; fn offset(&self) -> usize; } @@ -31,8 +32,8 @@ impl<'a, T: 'static> IntoAbstract for &'a View<'_, T> { fn pack_info(&self) -> &PackInfo { >::pack_info(self) } - fn type_id(&self) -> TypeId { - TypeId::of::() + fn storage_id(&self) -> StorageId { + TypeId::of::().into() } fn modified(&self) -> usize { core::usize::MAX @@ -54,8 +55,8 @@ impl<'a, T: 'static> IntoAbstract for Window<'a, T> { fn pack_info(&self) -> &PackInfo { self.pack_info() } - fn type_id(&self) -> TypeId { - TypeId::of::() + fn storage_id(&self) -> StorageId { + TypeId::of::().into() } fn modified(&self) -> usize { core::usize::MAX @@ -77,8 +78,8 @@ impl<'a, T: 'static> IntoAbstract for &'a Window<'a, T> { fn pack_info(&self) -> &PackInfo { >::pack_info(self) } - fn type_id(&self) -> TypeId { - TypeId::of::() + fn storage_id(&self) -> StorageId { + TypeId::of::().into() } fn modified(&self) -> usize { core::usize::MAX @@ -100,8 +101,8 @@ impl<'a: 'b, 'b, T: 'static> IntoAbstract for &'b ViewMut<'a, T> { fn pack_info(&self) -> &PackInfo { &self.pack_info } - fn type_id(&self) -> TypeId { - TypeId::of::() + fn storage_id(&self) -> StorageId { + TypeId::of::().into() } fn modified(&self) -> usize { core::usize::MAX @@ -123,8 +124,8 @@ impl<'a: 'b, 'b, T: 'static> IntoAbstract for &'b mut ViewMut<'a, T> { fn pack_info(&self) -> &PackInfo { &self.pack_info } - fn type_id(&self) -> TypeId { - TypeId::of::() + fn storage_id(&self) -> StorageId { + TypeId::of::().into() } fn modified(&self) -> usize { match &self.pack_info.pack { @@ -149,8 +150,8 @@ impl<'a, T: 'static> IntoAbstract for WindowMut<'a, T> { fn pack_info(&self) -> &PackInfo { self.pack_info() } - fn type_id(&self) -> TypeId { - TypeId::of::() + fn storage_id(&self) -> StorageId { + TypeId::of::().into() } fn modified(&self) -> usize { match &self.pack_info().pack { @@ -175,8 +176,8 @@ impl<'a: 'b, 'b, T: 'static> IntoAbstract for &'b WindowMut<'a, T> { fn pack_info(&self) -> &PackInfo { >::pack_info(self) } - fn type_id(&self) -> TypeId { - TypeId::of::() + fn storage_id(&self) -> StorageId { + TypeId::of::().into() } fn modified(&self) -> usize { core::usize::MAX @@ -198,8 +199,8 @@ impl<'a: 'b, 'b, T: 'static> IntoAbstract for &'b mut WindowMut<'a, T> { fn pack_info(&self) -> &PackInfo { >::pack_info(self) } - fn type_id(&self) -> TypeId { - TypeId::of::() + fn storage_id(&self) -> StorageId { + TypeId::of::().into() } fn modified(&self) -> usize { match &self.pack_info().pack { @@ -224,8 +225,8 @@ impl<'a: 'b, 'b, T: 'static> IntoAbstract for Not<&'b View<'a, T>> { fn pack_info(&self) -> &PackInfo { self.0.pack_info() } - fn type_id(&self) -> TypeId { - TypeId::of::() + fn storage_id(&self) -> StorageId { + TypeId::of::().into() } fn modified(&self) -> usize { core::usize::MAX @@ -247,8 +248,8 @@ impl<'a: 'b, 'b, T: 'static> IntoAbstract for Not<&'b ViewMut<'a, T>> { fn pack_info(&self) -> &PackInfo { &self.0.pack_info } - fn type_id(&self) -> TypeId { - TypeId::of::() + fn storage_id(&self) -> StorageId { + TypeId::of::().into() } fn modified(&self) -> usize { core::usize::MAX @@ -270,8 +271,8 @@ impl<'a: 'b, 'b, T: 'static> IntoAbstract for Not<&'b mut ViewMut<'a, T>> { fn pack_info(&self) -> &PackInfo { &self.0.pack_info } - fn type_id(&self) -> TypeId { - TypeId::of::() + fn storage_id(&self) -> StorageId { + TypeId::of::().into() } fn modified(&self) -> usize { core::usize::MAX diff --git a/src/iter/into_iter/multiple.rs b/src/iter/into_iter/multiple.rs index 6e29c156..b05793c1 100644 --- a/src/iter/into_iter/multiple.rs +++ b/src/iter/into_iter/multiple.rs @@ -26,8 +26,8 @@ macro_rules! impl_iterators { None, } - let mut type_ids = [$(self.$index.type_id()),+]; - type_ids.sort_unstable(); + let mut storage_ids = [$(self.$index.storage_id().into()),+]; + storage_ids.sort_unstable(); let mut smallest_index = core::usize::MAX; let mut smallest = core::usize::MAX; let mut i = 0; @@ -38,8 +38,8 @@ macro_rules! impl_iterators { if pack_iter == PackIter::None || pack_iter == PackIter::Update { match (&self.$index.pack_info().pack, is_offseted) { (Pack::Tight(pack), false) => { - if let Ok(types) = pack.is_packable(&type_ids) { - if types.len() == type_ids.len() { + if let Ok(types) = pack.is_packable(&storage_ids) { + if types.len() == storage_ids.len() { pack_iter = PackIter::Tight; smallest = pack.len; } else if pack.len < smallest { @@ -54,8 +54,8 @@ macro_rules! impl_iterators { } } (Pack::Loose(pack), false) => { - if pack.is_packable(&type_ids).is_ok() { - if pack.tight_types.len() + pack.loose_types.len() == type_ids.len() { + if pack.is_packable(&storage_ids).is_ok() { + if pack.tight_types.len() + pack.loose_types.len() == storage_ids.len() { pack_iter = PackIter::Loose; smallest = pack.len; smallest_index = i; diff --git a/src/lib.rs b/src/lib.rs index 4948e3c0..71688f93 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -170,7 +170,7 @@ pub use crate::borrow::NonSendSync; pub use crate::borrow::NonSync; #[doc(hidden)] pub use crate::borrow::{AllStoragesBorrow, Borrow}; -pub use borrow::FakeBorrow; +pub use borrow::{FakeBorrow, Mutation}; pub use delete::Delete; pub use get::Get; pub use iter::{ @@ -186,7 +186,10 @@ pub use sparse_set::{ }; pub use storage::{AllStorages, DeleteAny, Entities, EntityId}; #[doc(hidden)] -pub use system::{AllSystem, Nothing, System}; +pub use system::{ + AllSystem, CustomComponent, CustomComponentBorrowIntent, CustomComponentSize, + CustomComponentSizeError, DynamicSystem, Nothing, System, +}; #[cfg(feature = "parallel")] pub use view::ThreadPoolView; pub use view::{ diff --git a/src/pack/loose.rs b/src/pack/loose.rs index dd68050c..26c3e955 100644 --- a/src/pack/loose.rs +++ b/src/pack/loose.rs @@ -66,11 +66,11 @@ macro_rules! impl_loose_pack { )+ // we gather and sort all TypeId - let mut tight_types: Box<[_]> = Box::new([$(TypeId::of::<$tight>()),+]); + let mut tight_types: Box<[_]> = Box::new([$(TypeId::of::<$tight>().into()),+]); tight_types.sort_unstable(); let tight_types: Arc<[_]> = tight_types.into(); - let mut loose_types: Box<[_]> = Box::new([$(TypeId::of::<$loose>()),+]); + let mut loose_types: Box<[_]> = Box::new([$(TypeId::of::<$loose>().into()),+]); loose_types.sort_unstable(); let loose_types: Arc<[_]> = loose_types.into(); diff --git a/src/pack/tight.rs b/src/pack/tight.rs index 20978593..ab8d1268 100644 --- a/src/pack/tight.rs +++ b/src/pack/tight.rs @@ -47,7 +47,7 @@ macro_rules! impl_tight_pack { #[allow(clippy::useless_let_if_seq)] impl<$($type: 'static),+> TightPack for ($(&mut ViewMut<'_, $type>,)+) { fn try_tight_pack(self) -> Result<(), error::Pack> { - let mut type_ids: Box<[_]> = Box::new([$(TypeId::of::<$type>(),)+]); + let mut type_ids: Box<[_]> = Box::new([$(TypeId::of::<$type>().into(),)+]); type_ids.sort_unstable(); let type_ids: Arc<[_]> = type_ids.into(); diff --git a/src/remove.rs b/src/remove.rs index 1807db3e..2f4429f2 100644 --- a/src/remove.rs +++ b/src/remove.rs @@ -106,9 +106,9 @@ macro_rules! impl_remove { fn try_remove(self, entity: EntityId) -> Result<<($($type,)+) as Removable>::Out, error::Remove> { // non packed storages should not pay the price of pack if $(core::mem::discriminant(&self.$index.pack_info.pack) != core::mem::discriminant(&Pack::NoPack) || !self.$index.pack_info.observer_types.is_empty())||+ { - let mut types = [$(TypeId::of::<$type>()),+]; + let mut types = [$(TypeId::of::<$type>().into()),+]; types.sort_unstable(); - let mut add_types = [$(TypeId::of::<$add_type>()),*]; + let mut add_types = [$(TypeId::of::<$add_type>().into()),*]; add_types.sort_unstable(); let mut should_unpack = Vec::with_capacity(types.len() + add_types.len()); @@ -132,7 +132,7 @@ macro_rules! impl_remove { )+ $( - if should_unpack.contains(&TypeId::of::<$add_type>()) { + if should_unpack.contains(&TypeId::of::<$add_type>().into()) { self.$add_index.unpack(entity); } )* diff --git a/src/sparse_set/add_component.rs b/src/sparse_set/add_component.rs index f0003668..cf21ee7c 100644 --- a/src/sparse_set/add_component.rs +++ b/src/sparse_set/add_component.rs @@ -1,6 +1,6 @@ use crate::error; use crate::sparse_set::Pack; -use crate::storage::EntityId; +use crate::storage::{EntityId, StorageId}; use crate::view::ViewMut; use alloc::vec::Vec; use core::any::{type_name, TypeId}; @@ -96,24 +96,24 @@ macro_rules! impl_add_component_unchecked { let mut should_pack = Vec::new(); // non packed storages should not pay the price of pack if $(core::mem::discriminant(&self.$index.pack_info.pack) != core::mem::discriminant(&Pack::NoPack) || !self.$index.pack_info.observer_types.is_empty())||+ { - let mut type_ids = [$(TypeId::of::<$type>()),+]; - type_ids.sort_unstable(); - let mut add_types = [$(TypeId::of::<$add_type>()),*]; + let mut storage_ids = [$(StorageId::TypeId(TypeId::of::<$type>().into())),+]; + storage_ids.sort_unstable(); + let mut add_types = [$(TypeId::of::<$add_type>().into()),*]; add_types.sort_unstable(); - let mut real_types = Vec::with_capacity(type_ids.len() + add_types.len()); - real_types.extend_from_slice(&type_ids); + let mut real_types = Vec::with_capacity(storage_ids.len() + add_types.len()); + real_types.extend_from_slice(&storage_ids); $( if self.$add_index.contains(entity) { - real_types.push(TypeId::of::<$add_type>()); + real_types.push(TypeId::of::<$add_type>().into()); } )* real_types.sort_unstable(); should_pack.reserve(real_types.len()); $( - if self.$index.pack_info.has_all_storages(&type_ids, &add_types) { - if !should_pack.contains(&TypeId::of::<$type>()) { + if self.$index.pack_info.has_all_storages(&storage_ids, &add_types) { + if !should_pack.contains(&TypeId::of::<$type>().into()) { match &self.$index.pack_info.pack { Pack::Tight(pack) => if let Ok(types) = pack.is_packable(&real_types) { should_pack.extend_from_slice(types); @@ -131,7 +131,7 @@ macro_rules! impl_add_component_unchecked { )+ $( - if should_pack.contains(&TypeId::of::<$add_type>()) { + if should_pack.contains(&TypeId::of::<$add_type>().into()) { self.$add_index.pack(entity); } )* @@ -139,7 +139,7 @@ macro_rules! impl_add_component_unchecked { $( self.$index.insert(component.$index, entity); - if should_pack.contains(&TypeId::of::<$type>()) { + if should_pack.contains(&TypeId::of::<$type>().into()) { self.$index.pack(entity); } )+ diff --git a/src/sparse_set/mod.rs b/src/sparse_set/mod.rs index a63f40bc..35f55727 100644 --- a/src/sparse_set/mod.rs +++ b/src/sparse_set/mod.rs @@ -14,11 +14,11 @@ pub(crate) use view_add_entity::ViewAddEntity; pub(crate) use windows::RawWindowMut; use crate::error; -use crate::storage::EntityId; +use crate::storage::{EntityId, StorageId}; use crate::unknown_storage::UnknownStorage; use alloc::boxed::Box; use alloc::vec::Vec; -use core::any::{type_name, Any, TypeId}; +use core::any::{type_name, Any}; use core::ptr; pub(crate) const BUCKET_SIZE: usize = 128 / core::mem::size_of::(); @@ -1116,7 +1116,7 @@ impl core::ops::IndexMut for SparseSet { } impl UnknownStorage for SparseSet { - fn delete(&mut self, entity: EntityId, storage_to_unpack: &mut Vec) { + fn delete(&mut self, entity: EntityId, storage_to_unpack: &mut Vec) { self.actual_delete(entity); storage_to_unpack.reserve(self.pack_info.observer_types.len()); diff --git a/src/sparse_set/pack_info.rs b/src/sparse_set/pack_info.rs index 0dac0eaf..c7ac97f2 100644 --- a/src/sparse_set/pack_info.rs +++ b/src/sparse_set/pack_info.rs @@ -1,7 +1,6 @@ -use crate::storage::EntityId; +use crate::storage::{EntityId, StorageId}; use alloc::sync::Arc; use alloc::vec::Vec; -use core::any::TypeId; #[allow(clippy::enum_variant_names)] pub(crate) enum Pack { @@ -22,7 +21,7 @@ impl Pack { pub struct PackInfo { pub(crate) pack: Pack, - pub(crate) observer_types: Vec, + pub(crate) observer_types: Vec, } impl Default for PackInfo { @@ -36,7 +35,11 @@ impl Default for PackInfo { impl PackInfo { /// Returns `true` if enough storages were passed in - pub(crate) fn has_all_storages(&self, components: &[TypeId], additionals: &[TypeId]) -> bool { + pub(crate) fn has_all_storages( + &self, + components: &[StorageId], + additionals: &[StorageId], + ) -> bool { match &self.pack { Pack::Tight(tight) => { tight.has_all_storages(components, additionals, &self.observer_types) @@ -56,13 +59,13 @@ impl PackInfo { // we know observer types are at most as many as components + additionals so we'll use them to drive the iteration for &observer_type in &self.observer_types { - // we skip components with a lower TypeId + // we skip components with a lower StorageId comp += components[comp..] .iter() .take_while(|&&component| component < observer_type) .count(); - // we also skip additional types with a lower TypeId + // we also skip additional types with a lower StorageId add += additionals[add..] .iter() .take_while(|&&additional| additional < observer_type) @@ -85,16 +88,16 @@ impl PackInfo { } pub(crate) struct TightPack { - pub(crate) types: Arc<[TypeId]>, + pub(crate) types: Arc<[StorageId]>, pub(crate) len: usize, } impl TightPack { - pub(crate) fn new(types: Arc<[TypeId]>) -> Self { + pub(crate) fn new(types: Arc<[StorageId]>) -> Self { TightPack { types, len: 0 } } /// Returns `Ok(packed_types)` if `components` contains at least all components in `self.types` - pub(crate) fn is_packable(&self, components: &[TypeId]) -> Result<&[TypeId], ()> { + pub(crate) fn is_packable(&self, components: &[StorageId]) -> Result<&[StorageId], ()> { // the entity doesn't have enough components to be packed if components.len() < self.types.len() { return Err(()); @@ -105,7 +108,7 @@ impl TightPack { // we know packed types are at most as many as components so we'll use them to drive the iteration for &packed_type in &*self.types { - // we skip components with a lower TypeId + // we skip components with a lower StorageId comp += components[comp..] .iter() .take_while(|&&component| component < packed_type) @@ -125,9 +128,9 @@ impl TightPack { /// Returns `true` if enough storages were passed in fn has_all_storages( &self, - components: &[TypeId], - additionals: &[TypeId], - observer_types: &[TypeId], + components: &[StorageId], + additionals: &[StorageId], + observer_types: &[StorageId], ) -> bool { // both pairs can't have duplicates if components.len() + additionals.len() < self.types.len() + observer_types.len() { @@ -151,13 +154,13 @@ impl TightPack { (Some(&tight_type), observer_type) if observer_type.is_none() || tight_type < *observer_type.unwrap() => { - // we skip components with a lower TypeId + // we skip components with a lower StorageId comp += components[comp..] .iter() .take_while(|&&component| component < tight_type) .count(); - // we also skip additional types with a lower TypeId + // we also skip additional types with a lower StorageId add += additionals[add..] .iter() .take_while(|&&additional| additional < tight_type) @@ -208,13 +211,13 @@ impl TightPack { } pub(crate) struct LoosePack { - pub(crate) tight_types: Arc<[TypeId]>, - pub(crate) loose_types: Arc<[TypeId]>, + pub(crate) tight_types: Arc<[StorageId]>, + pub(crate) loose_types: Arc<[StorageId]>, pub(crate) len: usize, } impl LoosePack { - pub(crate) fn new(tight_types: Arc<[TypeId]>, loose_types: Arc<[TypeId]>) -> Self { + pub(crate) fn new(tight_types: Arc<[StorageId]>, loose_types: Arc<[StorageId]>) -> Self { LoosePack { tight_types, loose_types, @@ -222,7 +225,7 @@ impl LoosePack { } } /// Returns `Ok(packed_types)` if `components` contains at least all components in `self.types` - pub(crate) fn is_packable(&self, components: &[TypeId]) -> Result<&[TypeId], ()> { + pub(crate) fn is_packable(&self, components: &[StorageId]) -> Result<&[StorageId], ()> { if components.len() < self.tight_types.len() + self.loose_types.len() { // the entity doesn't have enough components to be packed return Err(()); @@ -243,7 +246,7 @@ impl LoosePack { (Some(&tight_type), loose_type) if loose_type.is_none() || tight_type < *loose_type.unwrap() => { - // we skip components with a lower TypeId + // we skip components with a lower StorageId comp += components[comp..] .iter() .take_while(|&&component| component < tight_type) @@ -290,9 +293,9 @@ impl LoosePack { /// Returns `true` if enough storages were passed in fn has_all_storages( &self, - components: &[TypeId], - additionals: &[TypeId], - observer_types: &[TypeId], + components: &[StorageId], + additionals: &[StorageId], + observer_types: &[StorageId], ) -> bool { if components.len() + additionals.len() < self.tight_types.len() + self.loose_types.len() + observer_types.len() @@ -322,13 +325,13 @@ impl LoosePack { ) { (Some(&tight_type), Some(&loose_type), Some(&observer_type)) => { if tight_type < loose_type && tight_type < observer_type { - // we skip components with a lower TypeId + // we skip components with a lower StorageId comp += components[comp..] .iter() .take_while(|&&component| component < tight_type) .count(); - // we also skip additional types with a lower TypeId + // we also skip additional types with a lower StorageId add += additionals[add..] .iter() .take_while(|&&additional| additional < tight_type) diff --git a/src/sparse_set/sort/unstable.rs b/src/sparse_set/sort/unstable.rs index 4b11e179..4a39dade 100644 --- a/src/sparse_set/sort/unstable.rs +++ b/src/sparse_set/sort/unstable.rs @@ -81,18 +81,18 @@ macro_rules! impl_unstable_sort { None, } - let mut type_ids = [$(TypeId::of::<$type>()),+]; - type_ids.sort_unstable(); + let mut storage_ids = [$(TypeId::of::<$type>().into()),+]; + storage_ids.sort_unstable(); let mut pack_sort = PackSort::None; $({ if let PackSort::None = pack_sort { match &self.$index.pack_info.pack { Pack::Tight(pack) => { - if let Ok(types) = pack.is_packable(&type_ids) { - if types.len() == type_ids.len() { + if let Ok(types) = pack.is_packable(&storage_ids) { + if types.len() == storage_ids.len() { pack_sort = PackSort::Tight(pack.len); - } else if types.len() < type_ids.len() { + } else if types.len() < storage_ids.len() { return Err(error::Sort::TooManyStorages); } else { return Err(error::Sort::MissingPackStorage); @@ -102,10 +102,10 @@ macro_rules! impl_unstable_sort { } } Pack::Loose(pack) => { - if pack.is_packable(&type_ids).is_ok() { - if pack.tight_types.len() + pack.loose_types.len() == type_ids.len() { + if pack.is_packable(&storage_ids).is_ok() { + if pack.tight_types.len() + pack.loose_types.len() == storage_ids.len() { pack_sort = PackSort::Loose(pack.len); - } else if pack.tight_types.len() + pack.loose_types.len() < type_ids.len() { + } else if pack.tight_types.len() + pack.loose_types.len() < storage_ids.len() { return Err(error::Sort::TooManyStorages); } else { return Err(error::Sort::MissingPackStorage); diff --git a/src/sparse_set/view_add_entity.rs b/src/sparse_set/view_add_entity.rs index 641eb62d..4373d986 100644 --- a/src/sparse_set/view_add_entity.rs +++ b/src/sparse_set/view_add_entity.rs @@ -39,13 +39,13 @@ macro_rules! impl_view_add_entity { sparse_sets.$index.insert(component.$index, entity); )+ - let type_ids = [$(TypeId::of::<$type>()),+]; - let mut sorted_type_ids = type_ids.clone(); + let storage_ids = [$(TypeId::of::<$type>().into()),+]; + let mut sorted_type_ids = storage_ids.clone(); sorted_type_ids.sort_unstable(); - let mut should_pack = Vec::with_capacity(type_ids.len()); + let mut should_pack = Vec::with_capacity(storage_ids.len()); $( - let type_id = type_ids[$index]; + let type_id = storage_ids[$index]; if should_pack.contains(&type_id) { sparse_sets.$index.pack(entity); diff --git a/src/storage/all/delete_any.rs b/src/storage/all/delete_any.rs index aa6ac6c4..97f5b158 100644 --- a/src/storage/all/delete_any.rs +++ b/src/storage/all/delete_any.rs @@ -14,7 +14,7 @@ impl DeleteAny for (T,) { fn delete_any(all_storages: &mut AllStorages) { // we have an exclusive reference so it's ok to not lock and still get a reference let storages = unsafe { &*all_storages.storages.get() }; - if let Some(storage) = storages.get(&TypeId::of::()) { + if let Some(storage) = storages.get(&TypeId::of::().into()) { if let Ok(mut sparse_set) = storage.sparse_set_mut::() { let ids = sparse_set.dense.clone(); sparse_set.clear(); @@ -36,7 +36,7 @@ macro_rules! impl_delete_any { let mut ids: HashSet> = HashSet::default(); $( - if let Some(storage) = storages.get(&TypeId::of::<$type>()) { + if let Some(storage) = storages.get(&TypeId::of::<$type>().into()) { if let Ok(mut sparse_set) = storage.sparse_set_mut::<$type>() { ids.extend(&sparse_set.dense); sparse_set.clear(); diff --git a/src/storage/all/mod.rs b/src/storage/all/mod.rs index 30b17aac..4ed9b1af 100644 --- a/src/storage/all/mod.rs +++ b/src/storage/all/mod.rs @@ -10,11 +10,11 @@ use crate::atomic_refcell::{AtomicRefCell, Ref, RefMut}; use crate::borrow::AllStoragesBorrow; use crate::error; use crate::sparse_set::SparseSet; +use crate::storage::StorageId; use alloc::boxed::Box; use alloc::vec::Vec; use core::any::TypeId; use core::cell::UnsafeCell; -use core::hash::BuildHasherDefault; use hashbrown::{hash_map::Entry, HashMap}; use parking_lot::{lock_api::RawRwLock as _, RawRwLock}; @@ -28,7 +28,8 @@ use parking_lot::{lock_api::RawRwLock as _, RawRwLock}; // we use a HashMap, it can reallocate, but even in this case the storages won't move since they are boxed pub struct AllStorages { lock: RawRwLock, - storages: UnsafeCell>>, + // TODO: Re-include the TypeIdHasher as a StorageIdHasher + storages: UnsafeCell*/>>, #[cfg(feature = "non_send")] thread_id: std::thread::ThreadId, } @@ -42,14 +43,14 @@ impl AllStorages { #[cfg(feature = "std")] { storages.insert( - TypeId::of::(), + TypeId::of::().into(), Storage(Box::new(AtomicRefCell::new(entities, None, true))), ); } #[cfg(not(feature = "std"))] { storages.insert( - TypeId::of::(), + TypeId::of::().into(), Storage(Box::new(AtomicRefCell::new(entities))), ); } @@ -62,12 +63,12 @@ impl AllStorages { } } pub(crate) fn entities(&self) -> Result, error::Borrow> { - let type_id = TypeId::of::(); + let storage_id = TypeId::of::().into(); self.lock.lock_shared(); // SAFE we locked let storages = unsafe { &*self.storages.get() }; // AllStorages is always created with Entities so there's no way to not find it - let storage = &storages[&type_id]; + let storage = &storages[&storage_id]; match storage.entities() { Ok(entities) => { self.lock.unlock_shared(); @@ -80,12 +81,12 @@ impl AllStorages { } } pub(crate) fn entities_mut(&self) -> Result, error::Borrow> { - let type_id = TypeId::of::(); + let storage_id = TypeId::of::().into(); self.lock.lock_shared(); // SAFE we locked let storages = unsafe { &*self.storages.get() }; // AllStorages is always created with Entities so there's no way to not find it - let storage = &storages[&type_id]; + let storage = &storages[&storage_id]; match storage.entities_mut() { Ok(entities) => { self.lock.unlock_shared(); @@ -99,13 +100,13 @@ impl AllStorages { } pub(crate) fn sparse_set( &self, + storage_id: StorageId, ) -> Result>, error::GetStorage> { - let type_id = TypeId::of::(); { self.lock.lock_shared(); // SAFE we locked let storages = unsafe { &*self.storages.get() }; - if let Some(storage) = storages.get(&type_id) { + if let Some(storage) = storages.get(&storage_id) { let sparse_set = storage.sparse_set::(); self.lock.unlock_shared(); return sparse_set; @@ -117,7 +118,7 @@ impl AllStorages { let storages = unsafe { &mut *self.storages.get() }; // another thread might have initialized the storage before this thread so we use entry let sparse_set = storages - .entry(type_id) + .entry(storage_id) .or_insert_with(Storage::new::) .sparse_set::(); self.lock.unlock_exclusive(); @@ -125,13 +126,13 @@ impl AllStorages { } pub(crate) fn sparse_set_mut( &self, + storage_id: StorageId, ) -> Result>, error::GetStorage> { - let type_id = TypeId::of::(); { self.lock.lock_shared(); // SAFE we locked let storages = unsafe { &*self.storages.get() }; - if let Some(storage) = storages.get(&type_id) { + if let Some(storage) = storages.get(&storage_id) { let sparse_set = storage.sparse_set_mut::(); self.lock.unlock_shared(); return sparse_set; @@ -143,7 +144,7 @@ impl AllStorages { let storages = unsafe { &mut *self.storages.get() }; // another thread might have initialized the storage before this thread so we use entry let sparse_set = storages - .entry(type_id) + .entry(storage_id) .or_insert_with(Storage::new::) .sparse_set_mut::(); self.lock.unlock_exclusive(); @@ -154,7 +155,7 @@ impl AllStorages { &self, ) -> Result>, error::GetStorage> { // Sync components can be accessed by any thread with a shared access - let type_id = TypeId::of::(); + let type_id = TypeId::of::().into(); { self.lock.lock_shared(); // SAFE we locked @@ -182,7 +183,7 @@ impl AllStorages { &self, ) -> Result>, error::GetStorage> { // Sync components can only be accessed by the thread they were created in with a unique access - let type_id = TypeId::of::(); + let type_id = TypeId::of::().into(); { self.lock.lock_shared(); // SAFE we locked @@ -210,7 +211,7 @@ impl AllStorages { &self, ) -> Result>, error::GetStorage> { // Send components can be accessed by one thread at a time - let type_id = TypeId::of::(); + let type_id = TypeId::of::().into(); { self.lock.lock_shared(); // SAFE we locked @@ -238,7 +239,7 @@ impl AllStorages { &self, ) -> Result>, error::GetStorage> { // Send components can be accessed by one thread at a time - let type_id = TypeId::of::(); + let type_id = TypeId::of::().into(); { self.lock.lock_shared(); // SAFE we locked @@ -266,7 +267,7 @@ impl AllStorages { &self, ) -> Result>, error::GetStorage> { // !Send + !Sync components can only be accessed by the thread they were created in - let type_id = TypeId::of::(); + let type_id = TypeId::of::().into(); { self.lock.lock_shared(); // SAFE we locked @@ -294,7 +295,7 @@ impl AllStorages { &self, ) -> Result>, error::GetStorage> { // !Send + !Sync components can only be accessed by the thread they were created in - let type_id = TypeId::of::(); + let type_id = TypeId::of::().into(); { self.lock.lock_shared(); // SAFE we locked @@ -318,11 +319,11 @@ impl AllStorages { sparse_set } pub(crate) fn unique(&self) -> Result, error::GetStorage> { - let type_id = TypeId::of::(); + let storage_id = TypeId::of::().into(); self.lock.lock_shared(); // SAFE we locked let storages = unsafe { &*self.storages.get() }; - if let Some(storage) = storages.get(&type_id) { + if let Some(storage) = storages.get(&storage_id) { let unique = storage.unique::(); self.lock.unlock_shared(); unique @@ -332,11 +333,11 @@ impl AllStorages { } } pub(crate) fn unique_mut(&self) -> Result, error::GetStorage> { - let type_id = TypeId::of::(); + let storage_id = TypeId::of::().into(); self.lock.lock_shared(); // SAFE we locked let storages = unsafe { &*self.storages.get() }; - if let Some(storage) = storages.get(&type_id) { + if let Some(storage) = storages.get(&storage_id) { let unique = storage.unique_mut::(); self.lock.unlock_shared(); unique @@ -346,11 +347,11 @@ impl AllStorages { } } pub(crate) fn remove_unique(&self) -> Result { - let type_id = TypeId::of::(); + let storage_id = TypeId::of::().into(); self.lock.lock_exclusive(); // SAFE we locked let storages = unsafe { &mut *self.storages.get() }; - if let Entry::Occupied(entry) = storages.entry(type_id) { + if let Entry::Occupied(entry) = storages.entry(storage_id) { // `.err()` to avoid borrowing `entry` in the `Ok` case if let Some(get_storage) = entry.get().unique_mut::().err() { self.lock.unlock_exclusive(); @@ -381,49 +382,49 @@ impl AllStorages { /// Register a new unique component and create a storage for it. /// Does nothing if a storage already exists. pub(crate) fn register_unique(&self, component: T) { - let type_id = TypeId::of::(); + let storage_id = TypeId::of::().into(); self.lock.lock_exclusive(); // SAFE we locked let storages = unsafe { &mut *self.storages.get() }; // another thread might have initialized the storage before this thread so we use entry storages - .entry(type_id) + .entry(storage_id) .or_insert_with(|| Storage::new_unique::(component)); self.lock.unlock_exclusive(); } #[cfg(feature = "non_send")] pub(crate) fn register_unique_non_send(&self, component: T) { - let type_id = TypeId::of::(); + let storage_id = TypeId::of::().into(); self.lock.lock_exclusive(); // SAFE we locked let storages = unsafe { &mut *self.storages.get() }; // another thread might have initialized the storage before this thread so we use entry storages - .entry(type_id) + .entry(storage_id) .or_insert_with(|| Storage::new_unique_non_send::(component, self.thread_id)); self.lock.unlock_exclusive(); } #[cfg(feature = "non_sync")] pub(crate) fn register_unique_non_sync(&self, component: T) { - let type_id = TypeId::of::(); + let storage_id = TypeId::of::().into(); self.lock.lock_exclusive(); // SAFE we locked let storages = unsafe { &mut *self.storages.get() }; // another thread might have initialized the storage before this thread so we use entry storages - .entry(type_id) + .entry(storage_id) .or_insert_with(|| Storage::new_unique_non_sync::(component)); self.lock.unlock_exclusive(); } #[cfg(all(feature = "non_send", feature = "non_sync"))] pub(crate) fn register_unique_non_send_sync(&self, component: T) { - let type_id = TypeId::of::(); + let storage_id = TypeId::of::().into(); self.lock.lock_exclusive(); // SAFE we locked let storages = unsafe { &mut *self.storages.get() }; // another thread might have initialized the storage before this thread so we use entry storages - .entry(type_id) + .entry(storage_id) .or_insert_with(|| Storage::new_unique_non_send_sync::(component, self.thread_id)); self.lock.unlock_exclusive(); } diff --git a/src/storage/entity/add_component.rs b/src/storage/entity/add_component.rs index 58763e1f..5a21f77c 100644 --- a/src/storage/entity/add_component.rs +++ b/src/storage/entity/add_component.rs @@ -68,24 +68,24 @@ macro_rules! impl_add_component { let mut should_pack = Vec::new(); // non packed storages should not pay the price of pack if $(core::mem::discriminant(&self.$index.pack_info.pack) != core::mem::discriminant(&Pack::NoPack) || !self.$index.pack_info.observer_types.is_empty())||+ { - let mut type_ids = [$(TypeId::of::<$type>()),+]; - type_ids.sort_unstable(); - let mut add_types = [$(TypeId::of::<$add_type>()),*]; + let mut storage_ids = [$(TypeId::of::<$type>().into()),+]; + storage_ids.sort_unstable(); + let mut add_types = [$(TypeId::of::<$add_type>().into()),*]; add_types.sort_unstable(); - let mut real_types = Vec::with_capacity(type_ids.len() + add_types.len()); - real_types.extend_from_slice(&type_ids); + let mut real_types = Vec::with_capacity(storage_ids.len() + add_types.len()); + real_types.extend_from_slice(&storage_ids); $( if self.$add_index.contains(entity) { - real_types.push(TypeId::of::<$add_type>()); + real_types.push(TypeId::of::<$add_type>().into()); } )* real_types.sort_unstable(); should_pack.reserve(real_types.len()); $( - if self.$index.pack_info.has_all_storages(&type_ids, &add_types) { - if !should_pack.contains(&TypeId::of::<$type>()) { + if self.$index.pack_info.has_all_storages(&storage_ids, &add_types) { + if !should_pack.contains(&TypeId::of::<$type>().into()) { match &self.$index.pack_info.pack { Pack::Tight(pack) => if let Ok(types) = pack.is_packable(&real_types) { should_pack.extend_from_slice(types); @@ -103,7 +103,7 @@ macro_rules! impl_add_component { )+ $( - if should_pack.contains(&TypeId::of::<$add_type>()) { + if should_pack.contains(&TypeId::of::<$add_type>().into()) { self.$add_index.pack(entity); } )* @@ -111,7 +111,7 @@ macro_rules! impl_add_component { $( self.$index.insert(component.$index, entity); - if should_pack.contains(&TypeId::of::<$type>()) { + if should_pack.contains(&TypeId::of::<$type>().into()) { self.$index.pack(entity); } )+ diff --git a/src/storage/entity/mod.rs b/src/storage/entity/mod.rs index 64520107..e096feb8 100644 --- a/src/storage/entity/mod.rs +++ b/src/storage/entity/mod.rs @@ -7,10 +7,11 @@ pub use iterator::EntitiesIter; use crate::error; use crate::sparse_set::ViewAddEntity; +use crate::storage::StorageId; use crate::unknown_storage::UnknownStorage; use add_component::AddComponent; use alloc::vec::Vec; -use core::any::{Any, TypeId}; +use core::any::Any; /// Entities holds the EntityIds to all entities: living, removed and dead. /// @@ -191,7 +192,7 @@ impl Entities { } impl UnknownStorage for Entities { - fn delete(&mut self, _entity: EntityId, _: &mut Vec) {} + fn delete(&mut self, _entity: EntityId, _: &mut Vec) {} fn clear(&mut self) { if self.data.is_empty() { return; diff --git a/src/storage/mod.rs b/src/storage/mod.rs index f37b4d4e..a8e650f7 100644 --- a/src/storage/mod.rs +++ b/src/storage/mod.rs @@ -14,14 +14,38 @@ use crate::unknown_storage::UnknownStorage; use alloc::boxed::Box; use alloc::vec::Vec; use core::any::TypeId; +use core::cmp::Ordering; use unique::Unique; /// Currently unused it'll replace `TypeId` in `AllStorages` in a future version. +#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] pub enum StorageId { TypeId(TypeId), Custom(u64), } +// TODO: Currently custom elements sort as less than TypeId +impl Ord for StorageId { + fn cmp(&self, other: &Self) -> Ordering { + match self { + StorageId::TypeId(id) => match other { + StorageId::TypeId(other_id) => id.cmp(other_id), + StorageId::Custom(_) => Ordering::Greater, + }, + StorageId::Custom(id) => match other { + StorageId::Custom(other_id) => id.cmp(other_id), + StorageId::TypeId(_) => Ordering::Less, + }, + } + } +} + +impl PartialOrd for StorageId { + fn partial_cmp(&self, other: &Self) -> Option { + Some(self.cmp(other)) + } +} + impl From for StorageId { fn from(type_id: TypeId) -> Self { StorageId::TypeId(type_id) @@ -206,7 +230,7 @@ impl Storage { pub(crate) fn delete( &mut self, entity: EntityId, - storage_to_unpack: &mut Vec, + storage_to_unpack: &mut Vec, ) -> Result<(), error::Borrow> { self.0.try_borrow_mut()?.delete(entity, storage_to_unpack); Ok(()) diff --git a/src/storage/unique.rs b/src/storage/unique.rs index 8977e6ee..6b16976e 100644 --- a/src/storage/unique.rs +++ b/src/storage/unique.rs @@ -1,12 +1,13 @@ use crate::storage::EntityId; +use crate::storage::StorageId; use crate::unknown_storage::UnknownStorage; use alloc::vec::Vec; -use core::any::{Any, TypeId}; +use core::any::Any; pub(super) struct Unique(pub(crate) T); impl UnknownStorage for Unique { - fn delete(&mut self, _: EntityId, _: &mut Vec) {} + fn delete(&mut self, _: EntityId, _: &mut Vec) {} fn clear(&mut self) {} fn unpack(&mut self, _: EntityId) {} fn any(&self) -> &dyn Any { diff --git a/src/system/mod.rs b/src/system/mod.rs index 5331644c..a67c378c 100644 --- a/src/system/mod.rs +++ b/src/system/mod.rs @@ -3,25 +3,27 @@ mod all_storages; pub use all_storages::AllSystem; use crate::atomic_refcell::AtomicRefCell; -use crate::borrow::Borrow; use crate::borrow::Mutation; +use crate::borrow::{Borrow, DynamicBorrow}; use crate::error; -use crate::storage::AllStorages; +use crate::storage::{AllStorages, StorageId}; +use crate::view::{DynamicView, DynamicViewMut}; use alloc::vec::Vec; -use core::any::TypeId; +use core::convert::TryFrom; pub struct Nothing; pub trait System<'s, Data, B, R> { fn run(self, data: Data, b: B) -> R; fn try_borrow( + &self, all_storages: &'s AtomicRefCell, #[cfg(feature = "parallel")] thread_pool: &'s rayon::ThreadPool, ) -> Result; - fn borrow_infos(infos: &mut Vec<(TypeId, Mutation)>); + fn borrow_infos(&self, infos: &mut Vec<(StorageId, Mutation)>); - fn is_send_sync() -> bool; + fn is_send_sync(&self) -> bool; } // Nothing has to be used and not () to not conflict where A = () @@ -33,15 +35,16 @@ where (self)() } fn try_borrow( + &self, _: &'s AtomicRefCell, #[cfg(feature = "parallel")] _: &'s rayon::ThreadPool, ) -> Result { Ok(Nothing) } - fn borrow_infos(_: &mut Vec<(TypeId, Mutation)>) {} + fn borrow_infos(&self, _: &mut Vec<(StorageId, Mutation)>) {} - fn is_send_sync() -> bool { + fn is_send_sync(&self) -> bool { true } } @@ -55,15 +58,128 @@ where (self)(data) } fn try_borrow( + &self, _: &'s AtomicRefCell, #[cfg(feature = "parallel")] _: &'s rayon::ThreadPool, ) -> Result { Ok(Nothing) } - fn borrow_infos(_: &mut Vec<(TypeId, Mutation)>) {} + fn borrow_infos(&self, _: &mut Vec<(StorageId, Mutation)>) {} - fn is_send_sync() -> bool { + fn is_send_sync(&self) -> bool { + true + } +} + +/// Information necessary to define a custom component +#[derive(Debug, Clone)] +pub struct CustomComponent { + /// The size of the components in bytes + pub size: CustomComponentSize, + /// The unique identifier for the component + pub id: u64, +} + +#[derive(Debug, Clone)] +pub enum CustomComponentSize { + D16, + D32, +} + +#[derive(Debug, Clone)] +pub struct CustomComponentSizeError { + size: u64, +} + +impl TryFrom for CustomComponentSize { + type Error = CustomComponentSizeError; + + fn try_from(size: u64) -> Result { + match size { + x if x <= 16 => Ok(Self::D16), + x if x <= 32 => Ok(Self::D32), + _ => Err(CustomComponentSizeError { size }), + } + } +} + +#[derive(Debug, Clone)] +pub struct CustomComponentBorrowIntent { + pub component: CustomComponent, + pub mutation: Mutation, +} + +type DynamicSystemBorrow<'a> = Vec + 'a>>; + +#[derive(Debug, Clone)] +pub struct DynamicSystem<'a, Data, R> { + pub data: Data, + pub system_fn: fn(Data, DynamicSystemBorrow<'a>) -> R, + pub borrow_intents: Vec, +} + +impl<'s, Data, R> System<'s, Data, DynamicSystemBorrow<'s>, R> for DynamicSystem<'s, Data, R> { + fn run(self, data: Data, borrow: DynamicSystemBorrow<'s>) -> R { + (self.system_fn)(data, borrow) + } + + fn try_borrow( + &self, + all_storages: &'s AtomicRefCell, + #[cfg(feature = "parallel")] _: &'s rayon::ThreadPool, + ) -> Result, error::GetStorage> { + Ok(self + .borrow_intents + .iter() + .map( + |intent| -> Result>, error::GetStorage> { + match intent.component.size { + CustomComponentSize::D16 => match intent.mutation { + Mutation::Shared => { + Ok(Box::new(DynamicView::<[u8; 16]>::from_storage_atomic_ref( + all_storages + .try_borrow() + .map_err(error::GetStorage::AllStoragesBorrow)?, + StorageId::Custom(intent.component.id), + )?)) + } + Mutation::Unique => Ok(Box::new( + DynamicViewMut::<[u8; 16]>::from_storage_atomic_ref( + all_storages + .try_borrow() + .map_err(error::GetStorage::AllStoragesBorrow)?, + StorageId::Custom(intent.component.id), + )?, + )), + }, + CustomComponentSize::D32 => match intent.mutation { + Mutation::Shared => { + Ok(Box::new(DynamicView::<[u8; 32]>::from_storage_atomic_ref( + all_storages + .try_borrow() + .map_err(error::GetStorage::AllStoragesBorrow)?, + StorageId::Custom(intent.component.id), + )?)) + } + Mutation::Unique => Ok(Box::new( + DynamicViewMut::<[u8; 32]>::from_storage_atomic_ref( + all_storages + .try_borrow() + .map_err(error::GetStorage::AllStoragesBorrow)?, + StorageId::Custom(intent.component.id), + )?, + )), + }, + } + }, + ) + .collect::>()?) + } + + fn borrow_infos(&self, _: &mut Vec<(StorageId, Mutation)>) {} + + fn is_send_sync(&self) -> bool { true } } @@ -75,6 +191,7 @@ macro_rules! impl_system { (self)($(b.$index,)+) } fn try_borrow( + &self, all_storages: &'s AtomicRefCell, #[cfg(feature = "parallel")] thread_pool: &'s rayon::ThreadPool ) -> Result<($($type,)+), error::GetStorage> { @@ -87,12 +204,12 @@ macro_rules! impl_system { Ok(($($type::try_borrow(all_storages)?,)+)) } } - fn borrow_infos(infos: &mut Vec<(TypeId, Mutation)>) { + fn borrow_infos(&self, infos: &mut Vec<(StorageId, Mutation)>) { $( $type::borrow_infos(infos); )+ } - fn is_send_sync() -> bool { + fn is_send_sync(&self) -> bool { $( $type::is_send_sync() )&&+ @@ -104,6 +221,7 @@ macro_rules! impl_system { (self)(data, $(b.$index,)+) } fn try_borrow( + &self, all_storages: &'s AtomicRefCell, #[cfg(feature = "parallel")] thread_pool: &'s rayon::ThreadPool ) -> Result<($($type,)+), error::GetStorage> { @@ -116,12 +234,12 @@ macro_rules! impl_system { Ok(($($type::try_borrow(all_storages)?,)+)) } } - fn borrow_infos(infos: &mut Vec<(TypeId, Mutation)>) { + fn borrow_infos(&self,infos: &mut Vec<(StorageId, Mutation)>) { $( $type::borrow_infos(infos); )+ } - fn is_send_sync() -> bool { + fn is_send_sync(&self,) -> bool { $( $type::is_send_sync() )&&+ diff --git a/src/unknown_storage.rs b/src/unknown_storage.rs index 683f651a..cd7289f3 100644 --- a/src/unknown_storage.rs +++ b/src/unknown_storage.rs @@ -1,11 +1,10 @@ use crate::sparse_set::SparseSet; -use crate::storage::Entities; -use crate::storage::EntityId; +use crate::storage::{Entities, EntityId, StorageId}; use alloc::vec::Vec; -use core::any::{Any, TypeId}; +use core::any::Any; pub(super) trait UnknownStorage { - fn delete(&mut self, entity: EntityId, storage_to_unpack: &mut Vec); + fn delete(&mut self, entity: EntityId, storage_to_unpack: &mut Vec); fn clear(&mut self); fn unpack(&mut self, entity: EntityId); fn any(&self) -> &dyn Any; diff --git a/src/view.rs b/src/view.rs index 144a7fb5..ab06d210 100644 --- a/src/view.rs +++ b/src/view.rs @@ -2,7 +2,9 @@ use crate::atomic_refcell::{AtomicRefCell, Borrow}; use crate::atomic_refcell::{Ref, RefMut}; use crate::error; use crate::sparse_set::{SparseSet, Window}; +use crate::storage::StorageId; use crate::{AllStorages, Entities}; +use core::any::TypeId; use core::convert::TryFrom; use core::ops::{Deref, DerefMut}; @@ -137,6 +139,48 @@ impl DerefMut for EntitiesViewMut<'_> { } } +pub struct DynamicView<'a, T> { + pub view: Option>, + pub storage_id: StorageId, +} + +impl<'a, T: 'static + Send + Sync> DynamicView<'a, T> { + pub fn new(storage_id: StorageId) -> Self { + DynamicView { + storage_id, + view: None, + } + } +} + +impl<'a, T: 'static + Send + Sync> DynamicView<'a, T> { + pub fn from_storage_atomic_ref( + all_storages: Ref<'a, AllStorages>, + storage_id: StorageId, + ) -> Result { + Ok(DynamicView { + view: Some(View::<'a, T>::from_storage_atomic_ref( + all_storages, + Some(storage_id), + )?), + storage_id, + }) + } + + pub fn from_storage_ref( + all_storages: &'a AllStorages, + storage_id: StorageId, + ) -> Result { + Ok(DynamicView { + view: Some(View::<'a, T>::from_storage_ref( + all_storages, + Some(storage_id), + )?), + storage_id, + }) + } +} + /// Shared view over a component storage. pub struct View<'a, T> { window: Window<'a, T>, @@ -147,23 +191,49 @@ pub struct View<'a, T> { impl<'a, T: 'static + Send + Sync> TryFrom> for View<'a, T> { type Error = error::GetStorage; fn try_from(all_storages: Ref<'a, AllStorages>) -> Result { + Self::from_storage_atomic_ref(all_storages, None) + } +} + +impl<'a, T: 'static + Send + Sync> TryFrom<&'a AllStorages> for View<'a, T> { + type Error = error::GetStorage; + fn try_from(all_storages: &'a AllStorages) -> Result { + Self::from_storage_ref(all_storages, None) + } +} + +impl<'a, T: 'static + Send + Sync> View<'a, T> { + pub fn from_storage_atomic_ref( + all_storages: Ref<'a, AllStorages>, + storage_id: Option, + ) -> Result { // SAFE all_storages and borrow are dropped before all_borrow let (all_storages, all_borrow) = unsafe { Ref::destructure(all_storages) }; // SAFE window is dropped before borrow - let (sparse_set, borrow) = unsafe { Ref::destructure(all_storages.sparse_set::()?) }; + let (sparse_set, borrow) = unsafe { + Ref::destructure( + all_storages + .sparse_set::(storage_id.unwrap_or_else(|| TypeId::of::().into()))?, + ) + }; Ok(View { window: sparse_set.window(), _borrow: borrow, _all_borrow: all_borrow, }) } -} -impl<'a, T: 'static + Send + Sync> TryFrom<&'a AllStorages> for View<'a, T> { - type Error = error::GetStorage; - fn try_from(all_storages: &'a AllStorages) -> Result { + pub fn from_storage_ref( + all_storages: &'a AllStorages, + storage_id: Option, + ) -> Result { // SAFE window is dropped before borrow - let (sparse_set, borrow) = unsafe { Ref::destructure(all_storages.sparse_set::()?) }; + let (sparse_set, borrow) = unsafe { + Ref::destructure( + all_storages + .sparse_set::(storage_id.unwrap_or_else(|| TypeId::of::().into()))?, + ) + }; Ok(View { window: sparse_set.window(), _borrow: borrow, @@ -275,6 +345,48 @@ impl<'a, T> AsRef> for View<'a, T> { } } +pub struct DynamicViewMut<'a, T> { + pub view_mut: Option>, + pub storage_id: StorageId, +} + +impl<'a, T: 'static + Send + Sync> DynamicViewMut<'a, T> { + pub fn new(storage_id: StorageId) -> Self { + DynamicViewMut { + storage_id, + view_mut: None, + } + } +} + +impl<'a, T: 'static + Send + Sync> DynamicViewMut<'a, T> { + pub fn from_storage_atomic_ref( + all_storages: Ref<'a, AllStorages>, + storage_id: StorageId, + ) -> Result { + Ok(DynamicViewMut { + view_mut: Some(ViewMut::<'a, T>::from_storage_atomic_ref( + all_storages, + Some(storage_id), + )?), + storage_id, + }) + } + + pub fn from_storage_ref( + all_storages: &'a AllStorages, + storage_id: StorageId, + ) -> Result { + Ok(DynamicViewMut { + view_mut: Some(ViewMut::<'a, T>::from_storage_ref( + all_storages, + Some(storage_id), + )?), + storage_id, + }) + } +} + /// Exclusive view over a component storage. pub struct ViewMut<'a, T> { sparse_set: RefMut<'a, SparseSet>, @@ -284,20 +396,38 @@ pub struct ViewMut<'a, T> { impl<'a, T: 'static + Send + Sync> TryFrom> for ViewMut<'a, T> { type Error = error::GetStorage; fn try_from(all_storages: Ref<'a, AllStorages>) -> Result { + Self::from_storage_atomic_ref(all_storages, None) + } +} + +impl<'a, T: 'static + Send + Sync> TryFrom<&'a AllStorages> for ViewMut<'a, T> { + type Error = error::GetStorage; + fn try_from(all_storages: &'a AllStorages) -> Result { + Self::from_storage_ref(all_storages, None) + } +} + +impl<'a, T: 'static + Send + Sync> ViewMut<'a, T> { + pub fn from_storage_atomic_ref( + all_storages: Ref<'a, AllStorages>, + storage_id: Option, + ) -> Result { // SAFE all_storages and sprase_set are dropped before all_borrow let (all_storages, all_borrow) = unsafe { Ref::destructure(all_storages) }; Ok(ViewMut { - sparse_set: all_storages.sparse_set_mut::()?, + sparse_set: all_storages + .sparse_set_mut::(storage_id.unwrap_or_else(|| TypeId::of::().into()))?, _all_borrow: all_borrow, }) } -} -impl<'a, T: 'static + Send + Sync> TryFrom<&'a AllStorages> for ViewMut<'a, T> { - type Error = error::GetStorage; - fn try_from(all_storages: &'a AllStorages) -> Result { + pub fn from_storage_ref( + all_storages: &'a AllStorages, + storage_id: Option, + ) -> Result { Ok(ViewMut { - sparse_set: all_storages.sparse_set_mut::()?, + sparse_set: all_storages + .sparse_set_mut::(storage_id.unwrap_or_else(|| TypeId::of::().into()))?, _all_borrow: Borrow::None, }) } diff --git a/src/world/mod.rs b/src/world/mod.rs index b86422d7..6d8d679b 100644 --- a/src/world/mod.rs +++ b/src/world/mod.rs @@ -578,16 +578,12 @@ world.try_run_with_data(sys1, (EntityId::dead(), [0., 0.])).unwrap(); s: S, data: Data, ) -> Result { - Ok(s.run((data,), { - #[cfg(feature = "parallel")] - { - S::try_borrow(&self.all_storages, &self.thread_pool)? - } - #[cfg(not(feature = "parallel"))] - { - S::try_borrow(&self.all_storages)? - } - })) + #[cfg(feature = "parallel")] + let borrow = s.try_borrow(&self.all_storages, &self.thread_pool)?; + #[cfg(not(feature = "parallel"))] + let borrow = s.try_borrow(&self.all_storages)?; + + Ok(s.run((data,), borrow)) } #[doc = "Borrows the requested storages and runs the function. Data can be passed to the function, this always has to be a single type but you can use a tuple if needed. @@ -844,16 +840,12 @@ let i = world.try_run(sys1).unwrap(); &'s self, s: S, ) -> Result { - Ok(s.run((), { - #[cfg(feature = "parallel")] - { - S::try_borrow(&self.all_storages, &self.thread_pool)? - } - #[cfg(not(feature = "parallel"))] - { - S::try_borrow(&self.all_storages)? - } - })) + #[cfg(feature = "parallel")] + let borrow = s.try_borrow(&self.all_storages, &self.thread_pool)?; + #[cfg(not(feature = "parallel"))] + let borrow = s.try_borrow(&self.all_storages)?; + + Ok(s.run((), borrow)) } #[doc = "Borrows the requested storages and runs the function. Unwraps errors. diff --git a/src/world/scheduler/builder.rs b/src/world/scheduler/builder.rs index 920ba6ce..5217f769 100644 --- a/src/world/scheduler/builder.rs +++ b/src/world/scheduler/builder.rs @@ -2,7 +2,7 @@ use super::Scheduler; use crate::atomic_refcell::RefMut; use crate::borrow::Mutation; use crate::error; -use crate::storage::AllStorages; +use crate::storage::{AllStorages, StorageId}; use crate::system::System; use crate::world::World; use alloc::borrow::Cow; @@ -20,13 +20,13 @@ use hashbrown::hash_map::Entry; pub struct WorkloadBuilder<'a> { scheduler: RefMut<'a, Scheduler>, systems: Vec<( - TypeId, + StorageId, &'static str, Range, bool, Box Result<(), error::Run> + Send + Sync + 'static>, )>, - borrow_info: Vec<(TypeId, Mutation)>, + borrow_info: Vec<(StorageId, Mutation)>, name: Cow<'static, str>, } @@ -93,14 +93,16 @@ impl<'a> WorkloadBuilder<'a> { S: Fn(&World) -> Result<(), error::Run> + Send + Sync + 'static, >( mut self, - (system, _): (S, F), + (system, f): (S, F), ) -> Result, error::InvalidSystem> { let old_len = self.borrow_info.len(); - F::borrow_infos(&mut self.borrow_info); + f.borrow_infos(&mut self.borrow_info); let borrows = &self.borrow_info[old_len..]; - if borrows.contains(&(TypeId::of::(), Mutation::Unique)) && borrows.len() > 1 { + if borrows.contains(&(TypeId::of::().into(), Mutation::Unique)) + && borrows.len() > 1 + { return Err(error::InvalidSystem::AllStorages); } @@ -123,9 +125,9 @@ impl<'a> WorkloadBuilder<'a> { } } - let is_send_sync = F::is_send_sync(); + let is_send_sync = f.is_send_sync(); self.systems.push(( - core::any::TypeId::of::(), + core::any::TypeId::of::().into(), type_name::(), old_len..self.borrow_info.len(), is_send_sync, @@ -284,8 +286,9 @@ impl<'a> WorkloadBuilder<'a> { { if type_id == batch_type_id && mutation == Mutation::Unique - || type_id == TypeId::of::() - || batch_type_id == TypeId::of::() + || type_id == TypeId::of::().into() + || batch_type_id + == TypeId::of::().into() { conflict = true; break; @@ -295,8 +298,9 @@ impl<'a> WorkloadBuilder<'a> { { if type_id == batch_type_id && mutation == Mutation::Unique - || type_id == TypeId::of::() - || batch_type_id == TypeId::of::() + || type_id == TypeId::of::().into() + || batch_type_id + == TypeId::of::().into() { conflict = true; break; @@ -309,8 +313,9 @@ impl<'a> WorkloadBuilder<'a> { #[cfg(feature = "parallel")] { if type_id == batch_type_id - || type_id == TypeId::of::() - || batch_type_id == TypeId::of::() + || type_id == TypeId::of::().into() + || batch_type_id + == TypeId::of::().into() { conflict = true; break; @@ -319,8 +324,9 @@ impl<'a> WorkloadBuilder<'a> { #[cfg(not(feature = "parallel"))] { if type_id == batch_type_id - || type_id == TypeId::of::() - || batch_type_id == TypeId::of::() + || type_id == TypeId::of::().into() + || batch_type_id + == TypeId::of::().into() { conflict = true; break; @@ -353,12 +359,13 @@ impl<'a> WorkloadBuilder<'a> { batch_info .last_mut() .unwrap() - .push((TypeId::of::(), Mutation::Unique)); + .push((TypeId::of::().into(), Mutation::Unique)); batch_info.push(Vec::new()); } else { new_batch.push(vec![system_index]); new_batch.push(Vec::new()); - batch_info.push(vec![(TypeId::of::(), Mutation::Unique)]); + batch_info + .push(vec![(TypeId::of::().into(), Mutation::Unique)]); batch_info.push(Vec::new()); } } diff --git a/src/world/scheduler/mod.rs b/src/world/scheduler/mod.rs index fbd5fb91..50626992 100644 --- a/src/world/scheduler/mod.rs +++ b/src/world/scheduler/mod.rs @@ -3,11 +3,11 @@ mod builder; pub use builder::WorkloadBuilder; use crate::error; +use crate::storage::StorageId; use crate::World; use alloc::borrow::Cow; use alloc::boxed::Box; use alloc::vec::Vec; -use core::any::TypeId; use core::ops::Range; use hashbrown::HashMap; @@ -15,7 +15,7 @@ use hashbrown::HashMap; pub(crate) struct Scheduler { pub(super) systems: Vec Result<(), error::Run> + Send + Sync + 'static>>, pub(super) system_names: Vec<&'static str>, - pub(super) lookup_table: HashMap, + pub(super) lookup_table: HashMap, // a batch lists systems that can run in parallel pub(super) batch: Vec>, pub(super) workloads: HashMap, Range>,