use hecs::{Component, Query, With, Without}; #[cfg(feature = "parallel")] use hecs::World; #[cfg(feature = "parallel")] use std::any::TypeId; use crate::QueryMarker; #[cfg(feature = "parallel")] use crate::{ArchetypeSet, ComponentTypeSet}; pub trait QueryExt: Query { #[cfg(feature = "parallel")] const COMPONENT_TYPE_SET_LENGTH: usize; #[cfg(feature = "parallel")] fn insert_component_types(component_type_set: &mut ComponentTypeSet); #[cfg(feature = "parallel")] fn set_archetype_bits(world: &World, archetype_set: &mut ArchetypeSet) where Self: Sized, { archetype_set.set_bits_for_query::(world); } } pub trait QueryBundle { #[cfg(feature = "parallel")] const COMPONENT_TYPE_SET_LENGTH: usize; fn markers() -> Self; #[cfg(feature = "parallel")] fn insert_component_types(component_type_set: &mut ComponentTypeSet); #[cfg(feature = "parallel")] fn set_archetype_bits(world: &World, archetype_set: &mut ArchetypeSet); } impl QueryExt for () { #[cfg(feature = "parallel")] const COMPONENT_TYPE_SET_LENGTH: usize = 0; #[cfg(feature = "parallel")] fn insert_component_types(_: &mut ComponentTypeSet) {} } impl QueryBundle for () { #[cfg(feature = "parallel")] const COMPONENT_TYPE_SET_LENGTH: usize = 0; fn markers() -> Self {} #[cfg(feature = "parallel")] fn insert_component_types(_: &mut ComponentTypeSet) {} #[cfg(feature = "parallel")] fn set_archetype_bits(_: &World, _: &mut ArchetypeSet) {} } impl QueryExt for &'_ C0 where C0: Component, { #[cfg(feature = "parallel")] const COMPONENT_TYPE_SET_LENGTH: usize = 1; #[cfg(feature = "parallel")] fn insert_component_types(component_type_set: &mut ComponentTypeSet) { component_type_set.immutable.insert(TypeId::of::()); } } impl QueryExt for &'_ mut C0 where C0: Component, { #[cfg(feature = "parallel")] const COMPONENT_TYPE_SET_LENGTH: usize = 1; #[cfg(feature = "parallel")] fn insert_component_types(component_type_set: &mut ComponentTypeSet) { component_type_set.mutable.insert(TypeId::of::()); } } impl QueryExt for Option where Q0: QueryExt, { #[cfg(feature = "parallel")] const COMPONENT_TYPE_SET_LENGTH: usize = Q0::COMPONENT_TYPE_SET_LENGTH; #[cfg(feature = "parallel")] fn insert_component_types(component_type_set: &mut ComponentTypeSet) { Q0::insert_component_types(component_type_set); } } impl QueryExt for With where C0: Component, Q0: QueryExt, { #[cfg(feature = "parallel")] const COMPONENT_TYPE_SET_LENGTH: usize = Q0::COMPONENT_TYPE_SET_LENGTH; #[cfg(feature = "parallel")] fn insert_component_types(component_type_set: &mut ComponentTypeSet) { Q0::insert_component_types(component_type_set); } } impl QueryExt for Without where C0: Component, Q0: QueryExt, { #[cfg(feature = "parallel")] const COMPONENT_TYPE_SET_LENGTH: usize = Q0::COMPONENT_TYPE_SET_LENGTH; #[cfg(feature = "parallel")] fn insert_component_types(component_type_set: &mut ComponentTypeSet) { Q0::insert_component_types(component_type_set); } } impl QueryBundle for QueryMarker where Q0: QueryExt, { #[cfg(feature = "parallel")] const COMPONENT_TYPE_SET_LENGTH: usize = Q0::COMPONENT_TYPE_SET_LENGTH; fn markers() -> Self { QueryMarker::new() } #[cfg(feature = "parallel")] fn insert_component_types(component_type_set: &mut ComponentTypeSet) { Q0::insert_component_types(component_type_set); } #[cfg(feature = "parallel")] fn set_archetype_bits(world: &World, archetype_set: &mut ArchetypeSet) { Q0::set_archetype_bits(world, archetype_set); } } impl QueryExt for (Q0,) where Q0: QueryExt, { #[cfg(feature = "parallel")] const COMPONENT_TYPE_SET_LENGTH: usize = Q0::COMPONENT_TYPE_SET_LENGTH; #[cfg(feature = "parallel")] fn insert_component_types(component_type_set: &mut ComponentTypeSet) { Q0::insert_component_types(component_type_set); } } impl QueryBundle for (QueryMarker,) where Q0: Query + QueryExt, { #[cfg(feature = "parallel")] const COMPONENT_TYPE_SET_LENGTH: usize = Q0::COMPONENT_TYPE_SET_LENGTH; fn markers() -> Self { (QueryMarker::new(),) } #[cfg(feature = "parallel")] fn insert_component_types(component_type_set: &mut ComponentTypeSet) { Q0::insert_component_types(component_type_set); } #[cfg(feature = "parallel")] fn set_archetype_bits(world: &World, archetype_set: &mut ArchetypeSet) { Q0::set_archetype_bits(world, archetype_set); } } macro_rules! impl_query_single { ($($letter:ident),*) => { impl<$($letter),*> QueryExt for ($($letter,)*) where $($letter: QueryExt,)* { #[cfg(feature = "parallel")] const COMPONENT_TYPE_SET_LENGTH: usize = 0 $(+ $letter::COMPONENT_TYPE_SET_LENGTH)*; #[cfg(feature = "parallel")] fn insert_component_types(component_type_set: &mut ComponentTypeSet) { $($letter::insert_component_types(component_type_set);)* } } } } impl_for_tuples!(impl_query_single); macro_rules! impl_query_bundle { ($($letter:ident),*) => { impl<$($letter),*> QueryBundle for ($(QueryMarker<$letter>,)*) where $($letter: Query + QueryExt,)* { #[cfg(feature = "parallel")] const COMPONENT_TYPE_SET_LENGTH: usize = 0 $(+ $letter::COMPONENT_TYPE_SET_LENGTH)*; fn markers() -> Self { ($(QueryMarker::<$letter>::new(),)*) } #[cfg(feature = "parallel")] fn insert_component_types(component_type_set: &mut ComponentTypeSet) { $($letter::insert_component_types(component_type_set);)* } #[cfg(feature = "parallel")] fn set_archetype_bits(world: &World, archetype_set: &mut ArchetypeSet) { $($letter::set_archetype_bits(world, archetype_set);)* } } } } impl_for_tuples!(impl_query_bundle);