diff options
Diffstat (limited to 'ecs/src/pair.rs')
-rw-r--r-- | ecs/src/pair.rs | 83 |
1 files changed, 78 insertions, 5 deletions
diff --git a/ecs/src/pair.rs b/ecs/src/pair.rs index 600c6e4..8bef70a 100644 --- a/ecs/src/pair.rs +++ b/ecs/src/pair.rs @@ -18,7 +18,7 @@ use crate::query::{ TermsBuilder as QueryTermsBuilder, TermsBuilderInterface, }; -use crate::uid::{PairParams as UidPairParams, Uid, With as WithUid}; +use crate::uid::{Kind as UidKind, PairParams as UidPairParams, Uid, With as WithUid}; use crate::util::impl_multiple; use crate::{Component, EntityComponentRef, World}; @@ -301,8 +301,8 @@ where fn uid() -> Uid { Uid::new_pair(&UidPairParams { - relation: Relation::uid(), - target: Target::uid(), + relation: Relation::id(), + target: Target::id(), }) } } @@ -314,7 +314,7 @@ where fn uid() -> Uid { Uid::new_pair(&UidPairParams { - relation: Relation::uid(), + relation: Relation::id(), target: Wildcard::uid(), }) } @@ -354,8 +354,51 @@ pub struct WithWildcard<'world, Relation, Target> _pd: PhantomData<(Relation, Target)>, } -impl<Relation, Target> WithWildcard<'_, 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 @@ -585,3 +628,33 @@ impl Wildcard 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 {} +} |