From b982b205373f445db9ced7f3cf13c1156ad8a40a Mon Sep 17 00:00:00 2001 From: HampusM Date: Tue, 8 Apr 2025 20:20:33 +0200 Subject: feat(ecs): add support for component data not implementing Component --- ecs/src/component.rs | 197 +++++++++++++++++++++++++++------------------------ 1 file changed, 104 insertions(+), 93 deletions(-) (limited to 'ecs/src/component.rs') diff --git a/ecs/src/component.rs b/ecs/src/component.rs index 4516b93..207c329 100644 --- a/ecs/src/component.rs +++ b/ecs/src/component.rs @@ -5,11 +5,7 @@ use std::ops::{Deref, DerefMut}; use seq_macro::seq; -use crate::event::component::{ - Added as ComponentAddedEvent, - Kind as ComponentEventKind, - Removed as ComponentRemovedEvent, -}; +use crate::event::component::Kind as ComponentEventKind; use crate::lock::{ Error as LockError, MappedReadGuard, @@ -80,15 +76,9 @@ pub trait Sequence /// The number of components in this component sequence. const COUNT: usize; - type Array: Array<(Uid, Box)>; - - fn into_array(self) -> Self::Array; - - fn metadata() -> impl Array; + type PartsArray: Array; - fn added_event_ids() -> Vec; - - fn removed_event_ids() -> Vec; + fn into_parts_array(self) -> Self::PartsArray; } /// A mutable or immutable reference to a component. @@ -143,30 +133,32 @@ pub trait HandleFromEntityComponentRef<'comp>: Sized } #[derive(Debug)] -pub struct Handle<'a, ComponentT: Component> +pub struct Handle<'a, ComponentData: 'static> { - inner: MappedReadGuard<'a, ComponentT>, + inner: MappedReadGuard<'a, ComponentData>, } -impl<'a, ComponentT: Component> Handle<'a, ComponentT> +impl<'a, ComponentData: 'static> Handle<'a, ComponentData> { pub(crate) fn new(inner: ReadGuard<'a, Box>) -> Self { Self { inner: inner.map(|component| { - component.downcast_ref::().unwrap_or_else(|| { - panic!( - "Failed to downcast component to type {}", - type_name::() - ); - }) + component + .downcast_ref::() + .unwrap_or_else(|| { + panic!( + "Failed to downcast component to type {}", + type_name::() + ); + }) }), } } } -impl<'comp, ComponentT: Component> HandleFromEntityComponentRef<'comp> - for Handle<'comp, ComponentT> +impl<'comp, ComponentData: 'static> HandleFromEntityComponentRef<'comp> + for Handle<'comp, ComponentData> { type Error = HandleError; @@ -187,9 +179,9 @@ impl<'comp, ComponentT: Component> HandleFromEntityComponentRef<'comp> } } -impl Deref for Handle<'_, ComponentT> +impl Deref for Handle<'_, ComponentData> { - type Target = ComponentT; + type Target = ComponentData; fn deref(&self) -> &Self::Target { @@ -198,30 +190,32 @@ impl Deref for Handle<'_, ComponentT> } #[derive(Debug)] -pub struct HandleMut<'a, ComponentT: Component> +pub struct HandleMut<'a, ComponentData: 'static> { - inner: MappedWriteGuard<'a, ComponentT>, + inner: MappedWriteGuard<'a, ComponentData>, } -impl<'a, ComponentT: Component> HandleMut<'a, ComponentT> +impl<'a, ComponentData: 'static> HandleMut<'a, ComponentData> { pub(crate) fn new(inner: WriteGuard<'a, Box>) -> Self { Self { inner: inner.map(|component| { - component.downcast_mut::().unwrap_or_else(|| { - panic!( - "Failed to downcast component to type {}", - type_name::() - ); - }) + component + .downcast_mut::() + .unwrap_or_else(|| { + panic!( + "Failed to downcast component to type {}", + type_name::() + ); + }) }), } } } -impl<'comp, ComponentT: Component> HandleFromEntityComponentRef<'comp> - for HandleMut<'comp, ComponentT> +impl<'comp, ComponentData: 'static> HandleFromEntityComponentRef<'comp> + for HandleMut<'comp, ComponentData> { type Error = HandleError; @@ -242,9 +236,9 @@ impl<'comp, ComponentT: Component> HandleFromEntityComponentRef<'comp> } } -impl Deref for HandleMut<'_, ComponentT> +impl Deref for HandleMut<'_, ComponentData> { - type Target = ComponentT; + type Target = ComponentData; fn deref(&self) -> &Self::Target { @@ -252,7 +246,7 @@ impl Deref for HandleMut<'_, ComponentT> } } -impl DerefMut for HandleMut<'_, ComponentT> +impl DerefMut for HandleMut<'_, ComponentData> { fn deref_mut(&mut self) -> &mut Self::Target { @@ -277,49 +271,18 @@ pub struct AcquireComponentLockFailed(LockError); macro_rules! inner { ($c: tt) => { seq!(I in 0..=$c { - impl<#(IntoComp~I,)*> Sequence for (#(IntoComp~I,)*) - where - #( - for<'comp> IntoComp~I: Into, - )* + impl<#(IntoCompParts~I: IntoParts,)*> Sequence for (#(IntoCompParts~I,)*) { const COUNT: usize = $c + 1; - type Array = [(Uid, Box); $c + 1]; + type PartsArray = [Parts; $c + 1]; - fn into_array(self) -> Self::Array + fn into_parts_array(self) -> Self::PartsArray { [#({ - let (id, component) = self.I.into_component(); - - (id, Box::new(component)) + self.I.into_parts() },)*] } - - fn metadata() -> impl Array - { - [ - #( - Metadata { - id: IntoComp~I::Component::id(), - }, - )* - ] - } - - fn added_event_ids() -> Vec - { - vec![ - #(ComponentAddedEvent::::id(),)* - ] - } - - fn removed_event_ids() -> Vec - { - vec![ - #(ComponentRemovedEvent::::id(),)* - ] - } } }); }; @@ -331,46 +294,94 @@ seq!(C in 0..=16 { impl Sequence for () { - type Array = [(Uid, Box); 0]; + type PartsArray = [Parts; 0]; const COUNT: usize = 0; - fn into_array(self) -> Self::Array + fn into_parts_array(self) -> Self::PartsArray { [] } +} + +pub trait IntoParts +{ + fn into_parts(self) -> Parts; +} - fn metadata() -> impl Array +impl IntoParts for ComponentT +where + ComponentT: Component, +{ + fn into_parts(self) -> Parts { - [] + Parts::builder() + .name(type_name::()) + .build(Self::id(), self) } +} - fn added_event_ids() -> Vec +/// The parts of a component. +#[derive(Debug)] +#[non_exhaustive] +pub struct Parts +{ + id: Uid, + name: &'static str, + data: Box, +} + +impl Parts +{ + pub fn id(&self) -> Uid + { + self.id + } + + pub fn name(&self) -> &'static str + { + self.name + } + + pub fn builder() -> PartsBuilder { - Vec::new() + PartsBuilder::default() } - fn removed_event_ids() -> Vec + pub(crate) fn into_data(self) -> Box { - Vec::new() + self.data } } -pub trait Into +#[derive(Debug)] +pub struct PartsBuilder { - type Component; - - fn into_component(self) -> (Uid, Self::Component); + name: &'static str, } -impl Into for ComponentT -where - ComponentT: Component, +impl PartsBuilder { - type Component = Self; + pub fn name(mut self, name: &'static str) -> Self + { + self.name = name; + self + } - fn into_component(self) -> (Uid, Self::Component) + pub fn build(self, id: Uid, data: Data) -> Parts + { + Parts { + id, + name: self.name, + data: Box::new(data), + } + } +} + +impl Default for PartsBuilder +{ + fn default() -> Self { - (Self::id(), self) + Self { name: "(unspecified)" } } } -- cgit v1.2.3-18-g5258