summaryrefslogtreecommitdiff
path: root/engine-ecs/src
diff options
context:
space:
mode:
authorHampusM <hampus@hampusmat.com>2026-08-03 14:28:41 +0200
committerHampusM <hampus@hampusmat.com>2026-08-03 17:03:02 +0200
commit7d578700747928fca0f0f1a4fae2c0cde0fe74f6 (patch)
tree1403ece3be1a44d56e6286b9da75d8d470280f9d /engine-ecs/src
parent22f2a5321162dc42d652949eda36cff63e3ebe64 (diff)
feat(engine-ecs): create component info ents for components from pairsHEADmaster
Diffstat (limited to 'engine-ecs/src')
-rw-r--r--engine-ecs/src/component.rs43
-rw-r--r--engine-ecs/src/lib.rs36
-rw-r--r--engine-ecs/src/pair.rs176
-rw-r--r--engine-ecs/src/query.rs3
4 files changed, 188 insertions, 70 deletions
diff --git a/engine-ecs/src/component.rs b/engine-ecs/src/component.rs
index 30869b5..9220ffb 100644
--- a/engine-ecs/src/component.rs
+++ b/engine-ecs/src/component.rs
@@ -14,7 +14,8 @@ use crate::lock::{
ReadGuard,
WriteGuard,
};
-use crate::pair::Pair;
+use crate::pair::{MemberMetadata as PairMemberMetadata, Pair};
+use crate::reflection::Type as TypeReflection;
use crate::system::Input as SystemInput;
use crate::uid::Uid;
use crate::util::Array;
@@ -31,7 +32,7 @@ pub trait Component: SystemInput + Any + IntoParts
where
Self: Sized;
- fn type_reflection() -> Option<&'static crate::reflection::Type>
+ fn type_reflection() -> Option<&'static TypeReflection>
where
Self: Sized;
@@ -293,8 +294,10 @@ pub struct Parts
{
pub id: Uid,
pub name: &'static str,
- pub type_reflection: Option<&'static crate::reflection::Type>,
+ pub type_reflection: Option<&'static TypeReflection>,
pub data: Box<dyn Any>,
+ pub pair_relation_metadata: Option<PairMemberMetadata>,
+ pub pair_target_metadata: Option<PairMemberMetadata>,
}
impl Parts
@@ -310,7 +313,9 @@ impl Parts
pub struct PartsBuilder
{
name: &'static str,
- type_reflection: Option<&'static crate::reflection::Type>,
+ type_reflection: Option<&'static TypeReflection>,
+ pair_relation_metadata: Option<PairMemberMetadata>,
+ pair_target_metadata: Option<PairMemberMetadata>,
}
impl PartsBuilder
@@ -325,7 +330,7 @@ impl PartsBuilder
#[must_use]
pub fn type_reflection(
mut self,
- type_reflection: Option<&'static crate::reflection::Type>,
+ type_reflection: Option<&'static TypeReflection>,
) -> Self
{
self.type_reflection = type_reflection;
@@ -333,6 +338,26 @@ impl PartsBuilder
}
#[must_use]
+ pub fn pair_relation_metadata(
+ mut self,
+ metadata: Option<PairMemberMetadata>,
+ ) -> Self
+ {
+ self.pair_relation_metadata = metadata;
+ self
+ }
+
+ #[must_use]
+ pub fn pair_target_metadata(
+ mut self,
+ metadata: Option<PairMemberMetadata>,
+ ) -> Self
+ {
+ self.pair_target_metadata = metadata;
+ self
+ }
+
+ #[must_use]
pub fn build<Data: 'static>(self, id: Uid, data: Data) -> Parts
{
Parts {
@@ -340,6 +365,8 @@ impl PartsBuilder
name: self.name,
type_reflection: self.type_reflection,
data: Box::new(data),
+ pair_relation_metadata: self.pair_relation_metadata,
+ pair_target_metadata: self.pair_target_metadata,
}
}
@@ -351,6 +378,8 @@ impl PartsBuilder
name: self.name,
type_reflection: self.type_reflection,
data,
+ pair_relation_metadata: self.pair_relation_metadata,
+ pair_target_metadata: self.pair_target_metadata,
}
}
}
@@ -362,6 +391,8 @@ impl Default for PartsBuilder
Self {
name: "(unspecified)",
type_reflection: None,
+ pair_relation_metadata: None,
+ pair_target_metadata: None,
}
}
}
@@ -370,7 +401,7 @@ impl Default for PartsBuilder
#[non_exhaustive]
pub struct Info
{
- pub type_reflection: Option<&'static crate::reflection::Type>,
+ pub type_reflection: Option<&'static TypeReflection>,
pub ty_id: TypeId,
pub name: &'static str,
}
diff --git a/engine-ecs/src/lib.rs b/engine-ecs/src/lib.rs
index 039661a..fcb9a8d 100644
--- a/engine-ecs/src/lib.rs
+++ b/engine-ecs/src/lib.rs
@@ -1,6 +1,6 @@
#![deny(clippy::all, clippy::pedantic)]
-use std::any::{Any, TypeId};
+use std::any::{Any, TypeId, type_name};
use std::borrow::Cow;
use std::fmt::Debug;
use std::hint::cold_path;
@@ -660,6 +660,26 @@ impl World
}
if comp_id.is_pair() {
+ if let Some(pair_relation_metadata) = &component_parts.pair_relation_metadata {
+ Self::create_component_info_entity_if_missing(
+ comp_id.relation(),
+ pair_relation_metadata.name,
+ pair_relation_metadata.ty,
+ pair_relation_metadata.ty_id,
+ component_storage,
+ );
+ }
+
+ if let Some(pair_target_metadata) = &component_parts.pair_target_metadata {
+ Self::create_component_info_entity_if_missing(
+ comp_id.target(),
+ pair_target_metadata.name,
+ pair_target_metadata.ty,
+ pair_target_metadata.ty_id,
+ component_storage,
+ );
+ }
+
continue;
}
@@ -702,12 +722,7 @@ impl World
}
}
- let ComponentParts {
- id: comp_info_id,
- name: comp_info_name,
- type_reflection: _,
- data: comp_info_data,
- } = ComponentInfo {
+ let comp_info_parts = ComponentInfo {
type_reflection,
name: comp_name,
ty_id: type_id,
@@ -715,9 +730,12 @@ impl World
.into_parts();
if let Err(err) = component_storage
- .add_entity_component(comp_id, (comp_info_id, comp_info_name, comp_info_data))
+ .add_entity_component(comp_id, (comp_info_parts.id, comp_info_parts.name, comp_info_parts.data))
{
- tracing::error!("Failed to add component {comp_info_name} to entity: {err}");
+ tracing::error!(
+ component = %type_name::<ComponentInfo>(),
+ "Failed to add component to entity: {err}"
+ );
}
}
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 {}
}
+
diff --git a/engine-ecs/src/query.rs b/engine-ecs/src/query.rs
index 10260f2..555380e 100644
--- a/engine-ecs/src/query.rs
+++ b/engine-ecs/src/query.rs
@@ -11,7 +11,6 @@ use crate::component::{
HandleMut as ComponentHandleMut,
};
use crate::entity::Handle as EntityHandle;
-use crate::pair::Wildcard;
use crate::query::flexible::{Iter as FlexibleQueryIter, Query as FlexibleQuery};
use crate::system::{Metadata as SystemMetadata, Param as SystemParam};
use crate::tuple::{Concat, Tuple};
@@ -271,7 +270,7 @@ impl_terms_builder! {
self.present(
traversals
- .map(|traversal| pair!({ traversal.relation }, Wildcard).id())
+ .map(|traversal| pair!({ traversal.relation }, *).id())
)
}
}