summaryrefslogtreecommitdiff
path: root/ecs/src
diff options
context:
space:
mode:
authorHampusM <hampus@hampusmat.com>2025-04-08 17:19:30 +0200
committerHampusM <hampus@hampusmat.com>2025-04-08 17:19:30 +0200
commit7276f9c72f53f02820c3238f72d099221daf7afd (patch)
treed523d0c01a9cd35bcc44401b46d9c8d36bbb10c1 /ecs/src
parente4818dd4f0a57a2c9af8859253f570607f64bb12 (diff)
refactor(ecs): replace optional components with Option query term
Diffstat (limited to 'ecs/src')
-rw-r--r--ecs/src/component.rs118
-rw-r--r--ecs/src/component/storage/archetype.rs4
-rw-r--r--ecs/src/lib.rs5
-rw-r--r--ecs/src/query.rs11
-rw-r--r--ecs/src/query/term.rs42
-rw-r--r--ecs/src/relationship.rs40
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,