diff options
author | HampusM <hampus@hampusmat.com> | 2025-04-08 17:19:30 +0200 |
---|---|---|
committer | HampusM <hampus@hampusmat.com> | 2025-04-08 17:19:30 +0200 |
commit | 7276f9c72f53f02820c3238f72d099221daf7afd (patch) | |
tree | d523d0c01a9cd35bcc44401b46d9c8d36bbb10c1 /ecs/src | |
parent | e4818dd4f0a57a2c9af8859253f570607f64bb12 (diff) |
refactor(ecs): replace optional components with Option query term
Diffstat (limited to 'ecs/src')
-rw-r--r-- | ecs/src/component.rs | 118 | ||||
-rw-r--r-- | ecs/src/component/storage/archetype.rs | 4 | ||||
-rw-r--r-- | ecs/src/lib.rs | 5 | ||||
-rw-r--r-- | ecs/src/query.rs | 11 | ||||
-rw-r--r-- | ecs/src/query/term.rs | 42 | ||||
-rw-r--r-- | ecs/src/relationship.rs | 40 |
6 files changed, 41 insertions, 179 deletions
diff --git a/ecs/src/component.rs b/ecs/src/component.rs index f4c29ae..49265b3 100644 --- a/ecs/src/component.rs +++ b/ecs/src/component.rs @@ -51,21 +51,6 @@ pub trait Component: SystemInput + Any /// Returns the component UID of a component event for this component. fn get_event_uid(&self, event_kind: ComponentEventKind) -> Uid; - - /// Returns whether the component `self` is optional. - fn self_is_optional(&self) -> bool - { - false - } - - /// Returns whether this component is optional. - #[must_use] - fn is_optional() -> bool - where - Self: Sized, - { - false - } } impl dyn Component @@ -94,46 +79,6 @@ impl Debug for dyn Component } } -impl<ComponentT> Component for Option<ComponentT> -where - ComponentT: Component, - for<'a> Option<ComponentT::Handle<'a>>: HandleFromEntityComponentRef<'a>, - for<'a> Option<ComponentT::HandleMut<'a>>: HandleFromEntityComponentRef<'a>, -{ - type Component = ComponentT; - type Handle<'component> = Option<ComponentT::Handle<'component>>; - type HandleMut<'component> = Option<ComponentT::HandleMut<'component>>; - - fn id() -> Uid - { - ComponentT::id() - } - - fn name(&self) -> &'static str - { - type_name::<Self>() - } - - fn get_event_uid(&self, event_kind: ComponentEventKind) -> Uid - { - match event_kind { - ComponentEventKind::Removed => ComponentRemovedEvent::<Self>::id(), - } - } - - fn self_is_optional(&self) -> bool - { - true - } - - fn is_optional() -> bool - { - true - } -} - -impl<ComponentT> SystemInput for Option<ComponentT> where ComponentT: Component {} - /// A sequence of components. pub trait Sequence { @@ -180,24 +125,14 @@ where pub struct Metadata { pub id: Uid, - pub is_optional: bool, } impl Metadata { #[must_use] - pub fn new_non_optional(id: Uid) -> Self - { - Self { id, is_optional: false } - } - - #[must_use] pub fn of<ComponentT: Component>() -> Self { - Self { - id: ComponentT::id(), - is_optional: ComponentT::is_optional(), - } + Self { id: ComponentT::id() } } } @@ -257,31 +192,6 @@ impl<'comp, ComponentT: Component> HandleFromEntityComponentRef<'comp> } } -impl<'comp, ComponentT> HandleFromEntityComponentRef<'comp> - for Option<Handle<'comp, ComponentT>> -where - ComponentT: Component, -{ - type Error = HandleError; - - fn from_entity_component_ref( - entity_component_ref: Option<EntityComponentRef<'comp>>, - _world: &'comp World, - ) -> Result<Self, Self::Error> - { - entity_component_ref - .map(|entity_comp| { - Ok(Handle::new( - entity_comp - .component() - .read_nonblock() - .map_err(AcquireComponentLockFailed)?, - )) - }) - .transpose() - } -} - impl<ComponentT: Component> Deref for Handle<'_, ComponentT> { type Target = ComponentT; @@ -337,31 +247,6 @@ impl<'comp, ComponentT: Component> HandleFromEntityComponentRef<'comp> } } -impl<'comp, ComponentT> HandleFromEntityComponentRef<'comp> - for Option<HandleMut<'comp, ComponentT>> -where - ComponentT: Component, -{ - type Error = HandleError; - - fn from_entity_component_ref( - entity_component_ref: Option<EntityComponentRef<'comp>>, - _world: &'comp World, - ) -> Result<Self, Self::Error> - { - entity_component_ref - .map(|entity_comp| { - Ok(HandleMut::new( - entity_comp - .component() - .write_nonblock() - .map_err(AcquireComponentLockFailed)?, - )) - }) - .transpose() - } -} - impl<ComponentT: Component> Deref for HandleMut<'_, ComponentT> { type Target = ComponentT; @@ -422,7 +307,6 @@ macro_rules! inner { #( Metadata { id: IntoComp~I::Component::id(), - is_optional: IntoComp~I::Component::is_optional(), }, )* ] diff --git a/ecs/src/component/storage/archetype.rs b/ecs/src/component/storage/archetype.rs index 58facc9..b8ac826 100644 --- a/ecs/src/component/storage/archetype.rs +++ b/ecs/src/component/storage/archetype.rs @@ -282,10 +282,6 @@ impl Id prev_component_id = Some(comp_metadata.id); - if comp_metadata.is_optional { - continue; - } - comp_metadata.id.hash(&mut hasher); } diff --git a/ecs/src/lib.rs b/ecs/src/lib.rs index ee33bd1..2c88eef 100644 --- a/ecs/src/lib.rs +++ b/ecs/src/lib.rs @@ -493,11 +493,6 @@ impl World ) { for (component_id, component) in components { - debug_assert!( - !component.self_is_optional(), - "Adding a optional component to a entity is not supported" - ); - if let Err(err) = component_storage.add_entity_component( entity_uid, (component_id, component.name(), component), diff --git a/ecs/src/query.rs b/ecs/src/query.rs index f642156..7542f0d 100644 --- a/ecs/src/query.rs +++ b/ecs/src/query.rs @@ -198,10 +198,6 @@ impl_terms_builder! { #[allow(unused_mut)] fn with<ComponentT: Component>(mut self) -> Self { - if ComponentT::is_optional() { - return self; - } - let insert_index = self.required_components .partition_point(|id| *id <= ComponentT::id()); @@ -214,13 +210,6 @@ impl_terms_builder! { #[allow(unused_mut)] fn without<ComponentT: Component>(mut self) -> Self { - if ComponentT::is_optional() { - panic!( - "{}::without cannot take optional component", - type_name::<Self>() - ); - } - let insert_index = self.excluded_components .partition_point(|id| *id <= ComponentT::id()); diff --git a/ecs/src/query/term.rs b/ecs/src/query/term.rs index ce453f0..78668c5 100644 --- a/ecs/src/query/term.rs +++ b/ecs/src/query/term.rs @@ -1,7 +1,13 @@ +use std::any::type_name; use std::marker::PhantomData; -use crate::component::Component; -use crate::query::{TermWithoutField, TermsBuilder, TermsBuilderInterface}; +use crate::component::{Component, HandleFromEntityComponentRef, Ref as ComponentRef}; +use crate::query::{ + TermWithField, + TermWithoutField, + TermsBuilder, + TermsBuilderInterface, +}; pub struct With<ComponentT> where @@ -40,3 +46,35 @@ where terms_builder.without::<ComponentT>(); } } + +impl<ComponentRefT> TermWithField for Option<ComponentRefT> +where + ComponentRefT: ComponentRef, +{ + type Field<'a> = Option<ComponentRefT::Handle<'a>>; + + fn apply_to_terms_builder<const MAX_TERM_CNT: usize>( + _terms_builder: &mut TermsBuilder<MAX_TERM_CNT>, + ) + { + } + + fn get_field<'world>( + entity_handle: &crate::entity::Handle<'world>, + world: &'world crate::World, + ) -> Self::Field<'world> + { + Some( + ComponentRefT::Handle::<'world>::from_entity_component_ref( + Some(entity_handle.get_component(ComponentRefT::Component::id())?), + world, + ) + .unwrap_or_else(|err| { + panic!( + "Creating handle to component {} failed: {err}", + type_name::<ComponentRefT::Component>() + ); + }), + ) + } +} diff --git a/ecs/src/relationship.rs b/ecs/src/relationship.rs index c5399e4..e368dd4 100644 --- a/ecs/src/relationship.rs +++ b/ecs/src/relationship.rs @@ -103,26 +103,6 @@ where } } -impl<'rel_comp, Kind, ComponentT> HandleFromEntityComponentRef<'rel_comp> - for Option<RelationMut<'rel_comp, Kind, ComponentT>> -where - ComponentT: Component, -{ - type Error = ComponentHandleError; - - fn from_entity_component_ref( - entity_component_ref: Option<EntityComponentRef<'rel_comp>>, - world: &'rel_comp World, - ) -> Result<Self, Self::Error> - { - entity_component_ref - .map(|entity_comp| { - RelationMut::from_entity_component_ref(Some(entity_comp), world) - }) - .transpose() - } -} - impl<'rel_comp, Kind, ComponentT> RelationMut<'rel_comp, Kind, ComponentT> where ComponentT: Component, @@ -328,26 +308,6 @@ where } } -impl<'rel_comp, Kind, ComponentT> HandleFromEntityComponentRef<'rel_comp> - for Option<Relation<'rel_comp, Kind, ComponentT>> -where - ComponentT: Component, -{ - type Error = ComponentHandleError; - - fn from_entity_component_ref( - entity_component_ref: Option<EntityComponentRef<'rel_comp>>, - world: &'rel_comp World, - ) -> Result<Self, ComponentHandleError> - { - entity_component_ref - .map(|entity_comp| { - Relation::from_entity_component_ref(Some(entity_comp), world) - }) - .transpose() - } -} - impl<'rel_comp, Kind, ComponentT> Relation<'rel_comp, Kind, ComponentT> where ComponentT: Component, |