diff options
| author | HampusM <hampus@hampusmat.com> | 2026-05-21 17:55:20 +0200 |
|---|---|---|
| committer | HampusM <hampus@hampusmat.com> | 2026-05-21 17:55:20 +0200 |
| commit | 8022e8998290b067b8aa0cb9cba8ba410826bdab (patch) | |
| tree | 7171e79ce530e03079046ee8fd12167160c45480 /ecs/src/pair.rs | |
| parent | 412cee02c252f91bcf0b70a3f5cc5fca6d2b4c62 (diff) | |
chore: rename ecs* crates to engine-ecs*
Diffstat (limited to 'ecs/src/pair.rs')
| -rw-r--r-- | ecs/src/pair.rs | 687 |
1 files changed, 0 insertions, 687 deletions
diff --git a/ecs/src/pair.rs b/ecs/src/pair.rs deleted file mode 100644 index 0d353e3..0000000 --- a/ecs/src/pair.rs +++ /dev/null @@ -1,687 +0,0 @@ -use std::any::type_name; -use std::convert::Infallible; -use std::marker::PhantomData; - -use crate::component::{ - Handle as ComponentHandle, - HandleError as ComponentHandleError, - HandleMut as ComponentHandleMut, - IntoParts as IntoComponentParts, - Parts as ComponentParts, -}; -use crate::entity::{ - Handle as EntityHandle, - MatchingComponentIter as EntityMatchingComponentIter, -}; -use crate::query::{ - TermWithField as QueryTermWithField, - TermsBuilder as QueryTermsBuilder, - TermsBuilderInterface, -}; -use crate::uid::{Kind as UidKind, PairParams as UidPairParams, Uid, With as WithUid}; -use crate::util::impl_multiple; -use crate::{Component, EntityComponentRef, World}; - -/// Pair builder. -#[derive(Debug)] -pub struct Builder<Relation, Target> -{ - relation: Relation, - target: Target, -} - -impl<Relation, Target> Builder<Relation, Target> -{ - pub fn relation<NewRelation: Component>(self) -> Builder<Uid, Target> - { - Builder { - relation: NewRelation::id(), - target: self.target, - } - } - - pub fn relation_id(self, id: Uid) -> Builder<Uid, Target> - { - Builder { relation: id, target: self.target } - } - - pub fn target<NewTarget: Component>(self) -> Builder<Relation, Uid> - { - Builder { - relation: self.relation, - target: NewTarget::id(), - } - } - - pub fn target_id(self, id: Uid) -> Builder<Relation, Uid> - { - Builder { relation: self.relation, target: id } - } -} - -impl_multiple!( - Builder, - (impl<Target> _<><Uid, Target>, impl<Target> _<><(), Target>) - cb=(type_params=(ty_param_1, ty_param_2)) => { - pub fn target_as_data<NewTarget: Component>( - self, - data: NewTarget, - ) -> Builder<$ty_param_1, NewTarget> - { - Builder { - relation: self.relation, - target: data, - } - } - } -); - -impl_multiple!( - Builder, - (impl<Relation> _<><Relation, Uid>, impl<Relation> _<><Relation, ()>) - cb=(type_params=(ty_param_1, ty_param_2)) => { - pub fn relation_as_data<NewRelation: Component>( - self, - data: NewRelation, - ) -> Builder<NewRelation, $ty_param_2> - { - Builder { - relation: data, - target: self.target, - } - } - } -); - -impl_multiple!( - Builder, - ( - impl _<><Uid, Uid>, - impl<Relation: Component> _<><Relation, Uid>, - impl<Target: Component> _<><Uid, Target>, - impl<Relation: Component, Target: Component> _<><Relation, Target> - ) - cb=(type_params=(ty_param_1, ty_param_2)) => { - #[must_use] - pub fn build(self) -> Pair<$ty_param_1, $ty_param_2> - { - Pair { - relation: self.relation, - target: self.target - } - } - } -); - -impl Default for Builder<(), ()> -{ - fn default() -> Self - { - Self { relation: (), target: () } - } -} - -#[derive(Debug)] -pub struct Pair<Relation, Target> -{ - relation: Relation, - target: Target, -} - -impl Pair<(), ()> -{ - #[must_use] - pub fn builder() -> Builder<(), ()> - { - Builder { relation: (), target: () } - } -} - -impl Pair<Uid, Uid> -{ - #[must_use] - pub fn id(&self) -> Uid - { - Uid::new_pair(&UidPairParams { - relation: self.relation, - target: self.target, - }) - } -} - -impl IntoComponentParts for Pair<Uid, Uid> -{ - fn into_parts(self) -> ComponentParts - { - ComponentParts::builder().name("Pair").build(self.id(), ()) - } -} - -impl<Target> IntoComponentParts for Pair<Uid, Target> -where - Target: Component, -{ - fn into_parts(self) -> ComponentParts - { - let id = Uid::new_pair(&UidPairParams { - relation: self.relation, - target: Target::id(), - }); - - ComponentParts::builder() - .name("Pair") - .build(id, self.target) - } -} - -impl<Relation> IntoComponentParts for Pair<Relation, Uid> -where - Relation: Component, -{ - fn into_parts(self) -> ComponentParts - { - let id = Uid::new_pair(&UidPairParams { - relation: Relation::id(), - target: self.target, - }); - - ComponentParts::builder() - .name("Pair") - .build(id, self.relation) - } -} - -impl<Relation, Target> QueryTermWithField for Pair<Relation, &Target> -where - Relation: Component, - Target: Component, -{ - type Field<'a> = ComponentHandle<'a, Target>; - - fn apply_to_terms_builder<const MAX_TERM_CNT: usize>( - terms_builder: &mut QueryTermsBuilder<MAX_TERM_CNT>, - ) - { - terms_builder.with_required([Pair::<Relation, Target>::uid()]); - } - - fn get_field<'world>( - entity_handle: &EntityHandle<'world>, - _world: &'world World, - ) -> Self::Field<'world> - { - let target_component = entity_handle - .get_matching_components(Pair::<Relation, Target>::uid()) - .next() - .expect("Not possible"); - - Self::Field::from_entity_component_ref(&target_component).unwrap_or_else(|err| { - panic!( - "Creating handle to target component {} failed: {err}", - type_name::<Target>() - ); - }) - } -} - -impl<Relation, Target> QueryTermWithField for Pair<Relation, &mut Target> -where - Relation: Component, - Target: Component, -{ - type Field<'a> = ComponentHandleMut<'a, Target>; - - fn apply_to_terms_builder<const MAX_TERM_CNT: usize>( - terms_builder: &mut QueryTermsBuilder<MAX_TERM_CNT>, - ) - { - terms_builder.with_required([Pair::<Relation, Target>::uid()]); - } - - fn get_field<'world>( - entity_handle: &EntityHandle<'world>, - world: &'world World, - ) -> Self::Field<'world> - { - let target_component = entity_handle - .get_matching_components(Pair::<Relation, Target>::uid()) - .next() - .expect("Not possible"); - - Self::Field::from_entity_component_ref(&target_component, world).unwrap_or_else( - |err| { - panic!( - "Creating handle to target component {} failed: {err}", - type_name::<Target>() - ); - }, - ) - } -} - -// TODO: implement QueryTermWithField for Pair<&Relation, Target> (or equivalent) -// TODO: implement QueryTermWithField for Pair<&mut Relation, Target> (or equivalent) - -impl<Relation> QueryTermWithField for Pair<Relation, Wildcard> -where - Relation: Component, -{ - type Field<'a> = WithWildcard<'a, Relation, Wildcard>; - - fn apply_to_terms_builder<const MAX_TERM_CNT: usize>( - terms_builder: &mut QueryTermsBuilder<MAX_TERM_CNT>, - ) - { - terms_builder.with_required([Self::uid()]); - } - - fn get_field<'world>( - entity_handle: &EntityHandle<'world>, - world: &'world World, - ) -> Self::Field<'world> - { - let first_matching_comp = entity_handle - .get_matching_components(Self::uid()) - .next() - .expect("Not possible"); - - WithWildcard { - world, - component_ref: first_matching_comp, - _pd: PhantomData, - } - } -} - -impl<Relation, Target> WithUid for Pair<Relation, Target> -where - Relation: Component, - Target: Component, -{ - fn uid() -> Uid - { - Uid::new_pair(&UidPairParams { - relation: Relation::id(), - target: Target::id(), - }) - } -} - -impl<Relation> WithUid for Pair<Relation, Wildcard> -where - Relation: Component, -{ - fn uid() -> Uid - { - Uid::new_pair(&UidPairParams { - relation: Relation::id(), - target: Wildcard::uid(), - }) - } -} - -impl<Relation> QueryTermWithField for &'_ [Pair<Relation, Wildcard>] -where - Relation: Component, -{ - type Field<'a> = MultipleWithWildcard<'a, Relation, Wildcard>; - - fn apply_to_terms_builder<const MAX_TERM_CNT: usize>( - _terms_builder: &mut QueryTermsBuilder<MAX_TERM_CNT>, - ) - { - } - - fn get_field<'world>( - entity_handle: &EntityHandle<'world>, - world: &'world World, - ) -> Self::Field<'world> - { - MultipleWithWildcard { - entity_handle: entity_handle.clone(), - world, - _pd: PhantomData, - } - } -} - -/// Reference to a pair with a wildcard relation/target. -#[derive(Debug)] -pub struct WithWildcard<'world, Relation, Target> -{ - world: &'world World, - component_ref: EntityComponentRef<'world>, - _pd: PhantomData<(Relation, Target)>, -} - -impl<'world, Relation, Target> WithWildcard<'world, Relation, Target> -{ - /// Returns a new `WithWildcard`. - /// - /// # Panics - /// This function will panic if: - /// - The given component's ID is not a pair ID. - /// - `Relation::uid()` is not wildcard and does not equal to the relation of the - /// given component's ID - /// - `Target::uid()` is not wildcard and does not equal to the target of the given - /// component's ID - /// - Both `Relation::uid()` and `Target::uid()` are wildcards - /// - Neither `Relation::uid()` or `Target::uid()` are wildcards - pub fn new(world: &'world World, component_ref: EntityComponentRef<'world>) -> Self - where - Relation: ComponentOrWildcard, - Target: ComponentOrWildcard, - { - let component_id = component_ref.id(); - - assert!(component_id.kind() == UidKind::Pair); - - assert!( - Relation::uid() == Wildcard::uid() - || component_id.relation_component() == Relation::uid() - ); - - assert!( - Target::uid() == Wildcard::uid() - || component_id.target_component() == Target::uid() - ); - - assert!(Relation::uid() == Wildcard::uid() || Target::uid() == Wildcard::uid()); - - assert!( - !(Relation::uid() == Wildcard::uid() && Target::uid() == Wildcard::uid()) - ); - - WithWildcard { - world, - component_ref, - _pd: PhantomData, - } - } - - /// Returns the [`Uid`] of the pair. - #[must_use] - pub fn id(&self) -> Uid - { - self.component_ref.id() - } - - /// Attempts to get the component data of this pair, returning `None` if the `Data` - /// type is incorrect. - /// - /// # Panics - /// Will panic if the component data is mutably borrowed elsewhere. - #[must_use] - pub fn get_data<Data>(&self) -> Option<ComponentHandle<'_, Data>> - where - Data: 'static, - { - ComponentHandle::<Data>::from_entity_component_ref(&self.component_ref) - .map_or_else( - |err| match err { - ComponentHandleError::IncorrectType => None, - err @ ComponentHandleError::AcquireLockFailed(_) => { - panic!( - "Creating handle to pair data as component {} failed: {err}", - type_name::<Data>() - ); - } - }, - Some, - ) - } - - /// Attempts to get the component data of this pair, returning `None` if the `Data` - /// type is incorrect. - /// - /// # Panics - /// Will panic if the component data is borrowed elsewhere. - #[must_use] - pub fn get_data_mut<Data>(&self) -> Option<ComponentHandleMut<'_, Data>> - where - Data: 'static, - { - ComponentHandleMut::<Data>::from_entity_component_ref( - &self.component_ref, - self.world, - ) - .map_or_else( - |err| match err { - ComponentHandleError::IncorrectType => None, - err @ ComponentHandleError::AcquireLockFailed(_) => { - panic!( - "Creating handle to pair data as component {} failed: {err}", - type_name::<Data>() - ); - } - }, - Some, - ) - } -} - -impl<'world, Relation> WithWildcard<'world, Relation, Wildcard> -where - Relation: Component, -{ - /// Attempts to retrieve the target as a entity, returning `None` if not found. - #[must_use] - pub fn get_target_ent(&self) -> Option<EntityHandle<'world>> - { - let archetype = self - .world - .data - .component_storage - .get_entity_archetype(self.component_ref.id().target_entity())?; - - let Some(archetype_entity) = - archetype.get_entity_by_id(self.component_ref.id().target_entity()) - else { - unreachable!(); - }; - - Some(EntityHandle::new(archetype, archetype_entity, self.world)) - } - - /// Attempts to get the component data of this pair, returning `None` if the - /// `Relation` type is incorrect. - /// - /// # Panics - /// Will panic if the component data is mutably borrowed elsewhere. - #[must_use] - pub fn get_data_as_relation(&self) -> Option<ComponentHandle<'_, Relation>> - { - ComponentHandle::<Relation>::from_entity_component_ref(&self.component_ref) - .map_or_else( - |err| match err { - ComponentHandleError::IncorrectType => None, - err @ ComponentHandleError::AcquireLockFailed(_) => { - panic!( - "Creating handle to pair data as component {} failed: {err}", - type_name::<Relation>() - ); - } - }, - Some, - ) - } - - /// Attempts to get the component data of this pair, returning `None` if the - /// `Relation` type is incorrect. - /// - /// # Panics - /// Will panic if the component data is borrowed elsewhere. - #[must_use] - pub fn get_data_as_relation_mut(&self) -> Option<ComponentHandleMut<'_, Relation>> - { - ComponentHandleMut::<Relation>::from_entity_component_ref( - &self.component_ref, - self.world, - ) - .map_or_else( - |err| match err { - ComponentHandleError::IncorrectType => None, - err @ ComponentHandleError::AcquireLockFailed(_) => { - panic!( - "Creating handle to pair data as component {} failed: {err}", - type_name::<Relation>() - ); - } - }, - Some, - ) - } -} - -/// Used to access matching pairs in a entity containing zero or more matching pairs. -#[derive(Debug)] -pub struct MultipleWithWildcard<'a, Relation, Target> -{ - entity_handle: EntityHandle<'a>, - world: &'a World, - _pd: PhantomData<(Relation, Target)>, -} - -impl<'world, Relation, Target> MultipleWithWildcard<'world, Relation, Target> -{ - /// Returns a new `MultipleWithWildcard`. - /// - /// # Panics - /// This function will panic if: - /// - Both `Relation::uid()` and `Target::uid()` are wildcards - /// - Neither `Relation::uid()` or `Target::uid()` are wildcards - pub fn new(world: &'world World, entity_handle: EntityHandle<'world>) -> Self - where - Relation: ComponentOrWildcard, - Target: ComponentOrWildcard, - { - assert!(Relation::uid() == Wildcard::uid() || Target::uid() == Wildcard::uid()); - - assert!( - !(Relation::uid() == Wildcard::uid() && Target::uid() == Wildcard::uid()) - ); - - MultipleWithWildcard { - entity_handle, - world, - _pd: PhantomData, - } - } -} - -impl<'a, Relation: Component> MultipleWithWildcard<'a, Relation, Wildcard> -{ - #[must_use] - pub fn get_with_target_id( - &self, - target_id: Uid, - ) -> Option<WithWildcard<'a, Relation, Wildcard>> - { - Some(WithWildcard { - world: self.world, - component_ref: self - .entity_handle - .get_matching_components( - Pair::builder() - .relation::<Relation>() - .target_id(target_id) - .build() - .id(), - ) - .next()?, - _pd: PhantomData, - }) - } -} - -impl<'a, Relation: Component> IntoIterator - for MultipleWithWildcard<'a, Relation, Wildcard> -{ - type IntoIter = WithWildcardIter<'a, Relation, Wildcard>; - type Item = <Self::IntoIter as Iterator>::Item; - - fn into_iter(self) -> Self::IntoIter - { - WithWildcardIter { - inner: self - .entity_handle - .get_matching_components(Pair::<Relation, Wildcard>::uid()), - world: self.world, - _pd: PhantomData, - } - } -} - -/// Iterator of matching pairs in a entity. -pub struct WithWildcardIter<'a, Relation, Target> -{ - inner: EntityMatchingComponentIter<'a>, - world: &'a World, - _pd: PhantomData<(Relation, Target)>, -} - -impl<'a, Relation, Target> Iterator for WithWildcardIter<'a, Relation, Target> -{ - type Item = WithWildcard<'a, Relation, Target>; - - fn next(&mut self) -> Option<Self::Item> - { - let matching_comp = self.inner.next()?; - - Some(WithWildcard { - world: self.world, - component_ref: matching_comp, - _pd: PhantomData, - }) - } -} - -/// Relation denoting a dependency to another entity -#[derive(Debug, Default, Clone, Copy, Component)] -pub struct DependsOn; - -/// Relation denoting being the child of another entity. -#[derive(Debug, Default, Clone, Copy, Component)] -pub struct ChildOf; - -#[derive(Debug)] -pub struct Wildcard(Infallible); - -impl Wildcard -{ - #[must_use] - pub fn uid() -> Uid - { - Uid::wildcard() - } -} - -pub trait ComponentOrWildcard: sealed::Sealed -{ - fn uid() -> Uid; -} - -impl<ComponentT: Component> ComponentOrWildcard for ComponentT -{ - fn uid() -> Uid - { - ComponentT::id() - } -} - -impl<ComponentT: Component> sealed::Sealed for ComponentT {} - -impl ComponentOrWildcard for Wildcard -{ - fn uid() -> Uid - { - Wildcard::uid() - } -} - -impl sealed::Sealed for Wildcard {} - -mod sealed -{ - pub trait Sealed {} -} |
