summaryrefslogtreecommitdiff
path: root/ecs/src/pair.rs
diff options
context:
space:
mode:
Diffstat (limited to 'ecs/src/pair.rs')
-rw-r--r--ecs/src/pair.rs687
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 {}
-}