diff options
Diffstat (limited to 'engine-ecs/src/pair.rs')
| -rw-r--r-- | engine-ecs/src/pair.rs | 176 |
1 files changed, 123 insertions, 53 deletions
diff --git a/engine-ecs/src/pair.rs b/engine-ecs/src/pair.rs index 00c6a72..3d603a8 100644 --- a/engine-ecs/src/pair.rs +++ b/engine-ecs/src/pair.rs @@ -1,13 +1,9 @@ -use std::any::type_name; +use std::any::{TypeId, 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, + Handle as ComponentHandle, HandleError as ComponentHandleError, HandleMut as ComponentHandleMut, IntoParts as IntoComponentParts, Parts as ComponentParts, }; use crate::entity::{ Handle as EntityHandle, @@ -20,6 +16,7 @@ use crate::query::{ TermsBuilder as QueryTermsBuilder, TermsBuilderInterface, }; +use crate::reflection::Type as TypeReflection; use crate::uid::{PairParams as UidPairParams, Uid, With as WithUid}; use crate::util::impl_multiple; use crate::{Component, EntityComponentRef, World}; @@ -30,6 +27,8 @@ pub struct Builder<Relation, Target> { relation: Relation, target: Target, + relation_metadata: Option<MemberMetadata>, + target_metadata: Option<MemberMetadata>, } impl<Relation, Target> Builder<Relation, Target> @@ -39,12 +38,23 @@ impl<Relation, Target> Builder<Relation, Target> Builder { relation: NewRelation::id(), target: self.target, + relation_metadata: Some(MemberMetadata { + ty: NewRelation::type_reflection(), + ty_id: TypeId::of::<NewRelation>(), + name: type_name::<NewRelation>(), + }), + target_metadata: self.target_metadata, } } pub fn relation_id(self, id: Uid) -> Builder<Uid, Target> { - Builder { relation: id, target: self.target } + Builder { + relation: id, + target: self.target, + relation_metadata: None, + target_metadata: self.target_metadata, + } } pub fn target<NewTarget: Component>(self) -> Builder<Relation, Uid> @@ -52,12 +62,23 @@ impl<Relation, Target> Builder<Relation, Target> Builder { relation: self.relation, target: NewTarget::id(), + relation_metadata: self.relation_metadata, + target_metadata: Some(MemberMetadata { + ty: NewTarget::type_reflection(), + ty_id: TypeId::of::<NewTarget>(), + name: type_name::<NewTarget>(), + }), } } pub fn target_id(self, id: Uid) -> Builder<Relation, Uid> { - Builder { relation: self.relation, target: id } + Builder { + relation: self.relation, + target: id, + relation_metadata: self.relation_metadata, + target_metadata: None, + } } } @@ -73,6 +94,12 @@ impl_multiple!( Builder { relation: self.relation, target: data, + relation_metadata: self.relation_metadata, + target_metadata: Some(MemberMetadata { + ty: NewTarget::type_reflection(), + ty_id: TypeId::of::<NewTarget>(), + name: type_name::<NewTarget>(), + }), } } } @@ -90,6 +117,12 @@ impl_multiple!( Builder { relation: data, target: self.target, + relation_metadata: Some(MemberMetadata { + ty: NewRelation::type_reflection(), + ty_id: TypeId::of::<NewRelation>(), + name: type_name::<NewRelation>(), + }), + target_metadata: self.target_metadata, } } } @@ -109,7 +142,9 @@ impl_multiple!( { Pair { relation: self.relation, - target: self.target + target: self.target, + relation_metadata: self.relation_metadata, + target_metadata: self.target_metadata, } } } @@ -119,7 +154,12 @@ impl Default for Builder<(), ()> { fn default() -> Self { - Self { relation: (), target: () } + Self { + relation: (), + target: (), + relation_metadata: None, + target_metadata: None, + } } } @@ -128,6 +168,8 @@ pub struct Pair<Relation, Target> { relation: Relation, target: Target, + relation_metadata: Option<MemberMetadata>, + target_metadata: Option<MemberMetadata>, } impl Pair<(), ()> @@ -135,7 +177,7 @@ impl Pair<(), ()> #[must_use] pub fn builder() -> Builder<(), ()> { - Builder { relation: (), target: () } + Builder::default() } } @@ -155,7 +197,13 @@ impl IntoComponentParts for Pair<Uid, Uid> { fn into_parts(self) -> ComponentParts { - ComponentParts::builder().name("Pair").build(self.id(), ()) + let id = self.id(); + + ComponentParts::builder() + .name("Pair") + .pair_relation_metadata(self.relation_metadata) + .pair_target_metadata(self.target_metadata) + .build(id, ()) } } @@ -172,6 +220,8 @@ where ComponentParts::builder() .name("Pair") + .pair_relation_metadata(self.relation_metadata) + .pair_target_metadata(self.target_metadata) .build(id, self.target) } } @@ -189,6 +239,8 @@ where ComponentParts::builder() .name("Pair") + .pair_relation_metadata(self.relation_metadata) + .pair_target_metadata(self.target_metadata) .build(id, self.relation) } } @@ -707,55 +759,50 @@ impl ComponentOrWildcard for Wildcard impl sealed::Sealed for Wildcard {} +#[derive(Debug, Clone)] +#[non_exhaustive] +pub struct MemberMetadata +{ + pub ty: Option<&'static TypeReflection>, + pub ty_id: TypeId, + pub name: &'static str, +} + + #[macro_export] macro_rules! pair { - ($relation: ty, $target: ty) => { - $crate::pair!(@build, $relation, $target) - }; - ($relation: ty, { $target: expr }) => { - $crate::pair!(@build, $relation, { $target }) - }; - - ({ $relation: expr }, $target: ty) => { - $crate::pair!(@build, { $relation }, $target) - }; + (Wildcard, $target: tt) => { + { + let pair: $crate::pair::Pair<(), ()> = std::compile_error!( + "Use shorthand * instead of Wildcard as relation" + ); - ({ $relation: expr }, { $target: expr }) => { - $crate::pair!(@build, { $relation }, { $target }) + pair + } }; - ($relation: ty, ={ $target: expr }) => { + ($relation: tt, Wildcard) => { { - fn get_type_uid<T: $crate::pair::ComponentOrWildcard>() - -> $crate::uid::Uid - { - T::uid() - } + let pair: $crate::pair::Pair<(), ()> = std::compile_error!( + "Use shorthand * instead of Wildcard as target" + ); - $crate::pair::Pair::builder() - .relation_id(get_type_uid::<$relation>()) - .target_as_data({ $target }) - .build() + pair } }; - (={ $relation: expr }, $target: ty) => { + (={ $relation: tt }, ={ $target: tt }) => { { - fn get_type_uid<T: $crate::pair::ComponentOrWildcard>() - -> $crate::uid::Uid - { - T::uid() - } + let pair: $crate::pair::Pair<(), ()> = std::compile_error!( + "Cannot use both relation and target as pair data" + ); - $crate::pair::Pair::builder() - .relation_as_data($relation) - .target_id(get_type_uid::<$target>()) - .build() + pair } }; - (@build, $relation: tt, $target: tt) => { + ($relation: tt, $target: tt) => { { #[allow(dead_code)] fn get_type_uid<T: $crate::pair::ComponentOrWildcard>() @@ -764,23 +811,46 @@ macro_rules! pair { T::uid() } - $crate::pair::Pair::builder() - .relation_id($crate::pair!(@get_uid, $relation)) - .target_id($crate::pair!(@get_uid, $target)) - .build() + let builder = $crate::pair::Pair::builder(); + + $crate::pair!(@set_member_in_builder, builder, relation, $relation); + $crate::pair!(@set_member_in_builder, builder, target, $target); + + builder.build() } }; - (@get_uid, $src: ty) => { - get_type_uid::<$src>() + (@set_member_in_builder, $builder: ident, $member: ident, *) => { + $crate::pair::__private::paste! { + let $builder = $builder.[<$member _id>]($crate::uid::Uid::wildcard()); + } + }; + + (@set_member_in_builder, $builder: ident, $member: ident, $src: ty) => { + let $builder = $builder.$member::<$src>(); }; - (@get_uid, { $src: expr }) => { - $src + (@set_member_in_builder, $builder: ident, $member: ident, { $src: expr }) => { + $crate::pair::__private::paste! { + let $builder = $builder.[<$member _id>]($src); + } + }; + + (@set_member_in_builder, $builder: ident, $member: ident, ={ $src: expr }) => { + $crate::pair::__private::paste! { + let $builder = $builder.[<$member _as_data>]($src); + } }; } +#[doc(hidden)] +pub mod __private +{ + pub use paste::paste; +} + mod sealed { pub trait Sealed {} } + |
