diff options
author | HampusM <hampus@hampusmat.com> | 2025-09-25 22:41:18 +0200 |
---|---|---|
committer | HampusM <hampus@hampusmat.com> | 2025-09-25 22:42:35 +0200 |
commit | 0fe88ca6d34aee03e5b84fdf181c1a7cb2bd32af (patch) | |
tree | 868f0af62baf659005b59fd8676fa313c3f442c3 /ecs | |
parent | 3bac271d4baa73844d4a0949946c6d9386d0db46 (diff) |
feat(ecs): add support for pairs with relation component as data
Diffstat (limited to 'ecs')
-rw-r--r-- | ecs/src/pair.rs | 116 |
1 files changed, 95 insertions, 21 deletions
diff --git a/ecs/src/pair.rs b/ecs/src/pair.rs index 985a2b3..f6d33d2 100644 --- a/ecs/src/pair.rs +++ b/ecs/src/pair.rs @@ -78,6 +78,23 @@ impl_multiple!( impl_multiple!( Builder, + (impl<Relation> _<Relation, Uid>, impl<Relation> _<Relation, ()>) + (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>, @@ -157,6 +174,23 @@ where } } +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, @@ -168,7 +202,7 @@ where terms_builder: &mut QueryTermsBuilder<MAX_TERM_CNT>, ) { - terms_builder.with_required([Self::uid()]); + terms_builder.with_required([Pair::<Relation, Target>::uid()]); } fn get_field<'world>( @@ -177,7 +211,7 @@ where ) -> Self::Field<'world> { let target_component = entity_handle - .get_matching_components(Self::uid()) + .get_matching_components(Pair::<Relation, Target>::uid()) .next() .expect("Not possible"); @@ -201,7 +235,7 @@ where terms_builder: &mut QueryTermsBuilder<MAX_TERM_CNT>, ) { - terms_builder.with_required([Self::uid()]); + terms_builder.with_required([Pair::<Relation, Target>::uid()]); } fn get_field<'world>( @@ -210,7 +244,7 @@ where ) -> Self::Field<'world> { let target_component = entity_handle - .get_matching_components(Self::uid()) + .get_matching_components(Pair::<Relation, Target>::uid()) .next() .expect("Not possible"); @@ -225,6 +259,9 @@ where } } +// 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, @@ -256,21 +293,7 @@ where } } -impl<Relation, Target> WithUid for Pair<Relation, &Target> -where - Relation: Component, - Target: Component, -{ - fn uid() -> Uid - { - Uid::new_pair(&UidPairParams { - relation: Relation::uid(), - target: Target::uid(), - }) - } -} - -impl<Relation, Target> WithUid for Pair<Relation, &mut Target> +impl<Relation, Target> WithUid for Pair<Relation, Target> where Relation: Component, Target: Component, @@ -349,7 +372,7 @@ impl<Relation, Target> WithWildcard<'_, Relation, Target> ComponentHandleError::IncorrectType => None, err @ ComponentHandleError::AcquireLockFailed(_) => { panic!( - "Creating handle to component {} failed: {err}", + "Creating handle to pair data as component {} failed: {err}", type_name::<Data>() ); } @@ -377,7 +400,7 @@ impl<Relation, Target> WithWildcard<'_, Relation, Target> ComponentHandleError::IncorrectType => None, err @ ComponentHandleError::AcquireLockFailed(_) => { panic!( - "Creating handle to component {} failed: {err}", + "Creating handle to pair data as component {} failed: {err}", type_name::<Data>() ); } @@ -388,6 +411,8 @@ impl<Relation, Target> WithWildcard<'_, Relation, Target> } impl<Relation> WithWildcard<'_, Relation, Wildcard> +where + Relation: Component, { /// Attempts to retrieve the target as a entity, returning `None` if not found. #[must_use] @@ -407,6 +432,55 @@ impl<Relation> WithWildcard<'_, Relation, Wildcard> 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. |