diff options
| author | HampusM <hampus@hampusmat.com> | 2026-05-21 17:55:20 +0200 |
|---|---|---|
| committer | HampusM <hampus@hampusmat.com> | 2026-05-21 17:55:20 +0200 |
| commit | 8022e8998290b067b8aa0cb9cba8ba410826bdab (patch) | |
| tree | 7171e79ce530e03079046ee8fd12167160c45480 /ecs/src/component.rs | |
| parent | 412cee02c252f91bcf0b70a3f5cc5fca6d2b4c62 (diff) | |
chore: rename ecs* crates to engine-ecs*
Diffstat (limited to 'ecs/src/component.rs')
| -rw-r--r-- | ecs/src/component.rs | 324 |
1 files changed, 0 insertions, 324 deletions
diff --git a/ecs/src/component.rs b/ecs/src/component.rs deleted file mode 100644 index 17b279b..0000000 --- a/ecs/src/component.rs +++ /dev/null @@ -1,324 +0,0 @@ -use std::any::{type_name, Any}; -use std::fmt::Debug; -use std::ops::{Deref, DerefMut}; - -use seq_macro::seq; - -use crate::event::component::Changed; -use crate::event::Submitter as EventSubmitter; -use crate::lock::{ - Error as LockError, - MappedReadGuard, - MappedWriteGuard, - ReadGuard, - WriteGuard, -}; -use crate::pair::Pair; -use crate::system::Input as SystemInput; -use crate::uid::Uid; -use crate::util::Array; -use crate::{EntityComponentRef, World}; - -pub mod local; - -pub(crate) mod storage; - -pub trait Component: SystemInput + Any -{ - /// Returns the ID of this component. - fn id() -> Uid - where - Self: Sized; - - /// Returns the name of this component. - fn name(&self) -> &'static str; -} - -impl dyn Component -{ - pub fn downcast_mut<Real: 'static>(&mut self) -> Option<&mut Real> - { - (self as &mut dyn Any).downcast_mut() - } - - pub fn downcast_ref<Real: 'static>(&self) -> Option<&Real> - { - (self as &dyn Any).downcast_ref() - } - - pub fn is<Other: 'static>(&self) -> bool - { - (self as &dyn Any).is::<Other>() - } -} - -impl Debug for dyn Component -{ - fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result - { - formatter.debug_struct("Component").finish_non_exhaustive() - } -} - -/// A sequence of components. -pub trait Sequence -{ - /// The number of components in this component sequence. - const COUNT: usize; - - type PartsArray: Array<Parts>; - - fn into_parts_array(self) -> Self::PartsArray; -} - -#[derive(Debug)] -pub struct Handle<'a, DataT: 'static> -{ - inner: MappedReadGuard<'a, DataT>, -} - -impl<'comp, DataT: 'static> Handle<'comp, DataT> -{ - /// Creates a new handle instance from a [`EntityComponentRef`]. - /// - /// # Errors - /// Will return `Err` if acquiring the component's lock fails. - pub fn from_entity_component_ref( - entity_component_ref: &EntityComponentRef<'comp>, - ) -> Result<Self, HandleError> - { - Self::new( - entity_component_ref - .component() - .read_nonblock() - .map_err(AcquireLockError)?, - ) - } - - fn new(inner: ReadGuard<'comp, Box<dyn Any>>) -> Result<Self, HandleError> - { - Ok(Self { - inner: ReadGuard::try_map(inner, |component| { - component.downcast_ref::<DataT>() - }) - .map_err(|_| HandleError::IncorrectType)?, - }) - } -} - -impl<DataT: 'static> Deref for Handle<'_, DataT> -{ - type Target = DataT; - - fn deref(&self) -> &Self::Target - { - &self.inner - } -} - -#[derive(Debug)] -pub struct HandleMut<'a, DataT: 'static> -{ - entity_component_ref: EntityComponentRef<'a>, - inner: MappedWriteGuard<'a, DataT>, - event_submitter: EventSubmitter<'a>, -} - -impl<'comp, DataT: 'static> HandleMut<'comp, DataT> -{ - /// Creates a new handle instance from a [`EntityComponentRef`]. - /// - /// # Errors - /// Will return `Err` if acquiring the component's lock fails. - pub fn from_entity_component_ref( - entity_component_ref: &EntityComponentRef<'comp>, - world: &'comp World, - ) -> Result<Self, HandleError> - { - let inner = entity_component_ref - .component() - .write_nonblock() - .map_err(AcquireLockError)?; - - Ok(Self { - entity_component_ref: entity_component_ref.clone(), - inner: WriteGuard::try_map(inner, |component| { - component.downcast_mut::<DataT>() - }) - .map_err(|_| HandleError::IncorrectType)?, - event_submitter: world.event_submitter(), - }) - } - - pub fn set_changed(&self) - { - self.event_submitter.submit_event( - &Pair::builder() - .relation::<Changed>() - .target_id(self.entity_component_ref.id()) - .build(), - self.entity_component_ref.entity_id(), - ); - } -} - -impl<DataT: 'static> Deref for HandleMut<'_, DataT> -{ - type Target = DataT; - - fn deref(&self) -> &Self::Target - { - &self.inner - } -} - -impl<DataT: 'static> DerefMut for HandleMut<'_, DataT> -{ - fn deref_mut(&mut self) -> &mut Self::Target - { - &mut self.inner - } -} - -#[derive(Debug, thiserror::Error)] -pub enum HandleError -{ - #[error(transparent)] - AcquireLockFailed(#[from] AcquireLockError), - - #[error("Incorrect component type")] - IncorrectType, -} - -#[derive(Debug, thiserror::Error)] -#[error("Failed to acquire component lock")] -pub struct AcquireLockError(#[source] LockError); - -macro_rules! inner { - ($c: tt) => { - seq!(I in 0..=$c { - impl<#(IntoCompParts~I: IntoParts,)*> Sequence for (#(IntoCompParts~I,)*) - { - const COUNT: usize = $c + 1; - - type PartsArray = [Parts; $c + 1]; - - fn into_parts_array(self) -> Self::PartsArray - { - [#({ - self.I.into_parts() - },)*] - } - } - }); - }; -} - -seq!(C in 0..=16 { - inner!(C); -}); - -impl Sequence for () -{ - type PartsArray = [Parts; 0]; - - const COUNT: usize = 0; - - fn into_parts_array(self) -> Self::PartsArray - { - [] - } -} - -pub trait IntoParts -{ - fn into_parts(self) -> Parts; -} - -impl<ComponentT> IntoParts for ComponentT -where - ComponentT: Component, -{ - fn into_parts(self) -> Parts - { - Parts::builder() - .name(type_name::<Self>()) - .build(Self::id(), self) - } -} - -/// The parts of a component. -#[derive(Debug)] -#[non_exhaustive] -pub struct Parts -{ - id: Uid, - name: &'static str, - data: Box<dyn Any>, -} - -impl Parts -{ - #[must_use] - pub fn id(&self) -> Uid - { - self.id - } - - #[must_use] - pub fn name(&self) -> &'static str - { - self.name - } - - #[must_use] - pub fn builder() -> PartsBuilder - { - PartsBuilder::default() - } - - pub(crate) fn into_data(self) -> Box<dyn Any> - { - self.data - } -} - -#[derive(Debug)] -pub struct PartsBuilder -{ - name: &'static str, -} - -impl PartsBuilder -{ - #[must_use] - pub fn name(mut self, name: &'static str) -> Self - { - self.name = name; - self - } - - #[must_use] - pub fn build<Data: 'static>(self, id: Uid, data: Data) -> Parts - { - Parts { - id, - name: self.name, - data: Box::new(data), - } - } - - #[must_use] - pub fn build_with_any_data(self, id: Uid, data: Box<dyn Any>) -> Parts - { - Parts { id, name: self.name, data } - } -} - -impl Default for PartsBuilder -{ - fn default() -> Self - { - Self { name: "(unspecified)" } - } -} |
