diff options
Diffstat (limited to 'ecs/src/component.rs')
-rw-r--r-- | ecs/src/component.rs | 170 |
1 files changed, 76 insertions, 94 deletions
diff --git a/ecs/src/component.rs b/ecs/src/component.rs index a0ed752..5a8cd0b 100644 --- a/ecs/src/component.rs +++ b/ecs/src/component.rs @@ -1,8 +1,9 @@ use std::any::{type_name, Any}; -use std::error::Error; use std::fmt::Debug; use std::ops::{Deref, DerefMut}; +use ecs_macros::Component; +use hashbrown::HashSet; use seq_macro::seq; use crate::lock::{ @@ -15,7 +16,7 @@ use crate::lock::{ use crate::system::Input as SystemInput; use crate::uid::Uid; use crate::util::Array; -use crate::{EntityComponentRef, World}; +use crate::EntityComponentRef; pub mod local; @@ -23,14 +24,6 @@ pub(crate) mod storage; pub trait Component: SystemInput + Any { - type HandleMut<'component>: HandleFromEntityComponentRef<'component> - where - Self: Sized; - - type Handle<'component>: HandleFromEntityComponentRef<'component> - where - Self: Sized; - /// Returns the ID of this component. fn id() -> Uid where @@ -77,46 +70,31 @@ pub trait Sequence fn into_parts_array(self) -> Self::PartsArray; } -/// [`Component`] metadata. -#[derive(Debug, Clone)] -#[non_exhaustive] -pub struct Metadata -{ - pub id: Uid, -} - -impl Metadata +#[derive(Debug)] +pub struct Handle<'a, ComponentData: 'static> { - #[must_use] - pub fn of<ComponentT: Component>() -> Self - { - Self { id: ComponentT::id() } - } + inner: MappedReadGuard<'a, ComponentData>, } -pub trait HandleFromEntityComponentRef<'comp>: Sized +impl<'comp, ComponentData: 'static> Handle<'comp, ComponentData> { - type Error: Error; - /// Creates a new handle instance from a [`EntityComponentRef`]. /// /// # Errors - /// See the implementation's [`Self::Error`] type. - fn from_entity_component_ref( - entity_component_ref: Option<EntityComponentRef<'comp>>, - world: &'comp World, - ) -> Result<Self, Self::Error>; -} - -#[derive(Debug)] -pub struct Handle<'a, ComponentData: 'static> -{ - inner: MappedReadGuard<'a, ComponentData>, -} + /// Will return `Err` if acquiring the component's lock fails. + pub fn from_entity_component_ref( + entity_component_ref: EntityComponentRef<'comp>, + ) -> Result<Self, HandleError> + { + Ok(Self::new( + entity_component_ref + .component() + .read_nonblock() + .map_err(AcquireLockError)?, + )) + } -impl<'a, ComponentData: 'static> Handle<'a, ComponentData> -{ - pub(crate) fn new(inner: ReadGuard<'a, Box<dyn Any>>) -> Self + pub(crate) fn new(inner: ReadGuard<'comp, Box<dyn Any>>) -> Self { Self { inner: inner.map(|component| { @@ -133,28 +111,6 @@ impl<'a, ComponentData: 'static> Handle<'a, ComponentData> } } -impl<'comp, ComponentData: 'static> HandleFromEntityComponentRef<'comp> - for Handle<'comp, ComponentData> -{ - type Error = HandleError; - - fn from_entity_component_ref( - entity_component_ref: Option<EntityComponentRef<'comp>>, - _world: &'comp World, - ) -> Result<Self, Self::Error> - { - let entity_comp = - entity_component_ref.ok_or(HandleError::ComponentDoesNotExist)?; - - Ok(Self::new( - entity_comp - .component() - .read_nonblock() - .map_err(AcquireComponentLockFailed)?, - )) - } -} - impl<ComponentData: 'static> Deref for Handle<'_, ComponentData> { type Target = ComponentData; @@ -171,9 +127,25 @@ pub struct HandleMut<'a, ComponentData: 'static> inner: MappedWriteGuard<'a, ComponentData>, } -impl<'a, ComponentData: 'static> HandleMut<'a, ComponentData> +impl<'comp, ComponentData: 'static> HandleMut<'comp, ComponentData> { - pub(crate) fn new(inner: WriteGuard<'a, Box<dyn Any>>) -> Self + /// 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> + { + Ok(Self::new( + entity_component_ref + .component() + .write_nonblock() + .map_err(AcquireLockError)?, + )) + } + + pub(crate) fn new(inner: WriteGuard<'comp, Box<dyn Any>>) -> Self { Self { inner: inner.map(|component| { @@ -190,28 +162,6 @@ impl<'a, ComponentData: 'static> HandleMut<'a, ComponentData> } } -impl<'comp, ComponentData: 'static> HandleFromEntityComponentRef<'comp> - for HandleMut<'comp, ComponentData> -{ - type Error = HandleError; - - fn from_entity_component_ref( - entity_component_ref: Option<EntityComponentRef<'comp>>, - _world: &'comp World, - ) -> Result<Self, Self::Error> - { - let entity_comp = - entity_component_ref.ok_or(HandleError::ComponentDoesNotExist)?; - - Ok(Self::new( - entity_comp - .component() - .write_nonblock() - .map_err(AcquireComponentLockFailed)?, - )) - } -} - impl<ComponentData: 'static> Deref for HandleMut<'_, ComponentData> { type Target = ComponentData; @@ -234,15 +184,12 @@ impl<ComponentData: 'static> DerefMut for HandleMut<'_, ComponentData> pub enum HandleError { #[error(transparent)] - AcquireComponentLockFailed(#[from] AcquireComponentLockFailed), - - #[error("Component does not exist")] - ComponentDoesNotExist, + AcquireLockFailed(#[from] AcquireLockError), } #[derive(Debug, thiserror::Error)] -#[error(transparent)] -pub struct AcquireComponentLockFailed(LockError); +#[error("Failed to acquire component lock")] +pub struct AcquireLockError(#[source] LockError); macro_rules! inner { ($c: tt) => { @@ -366,3 +313,38 @@ impl Default for PartsBuilder Self { name: "(unspecified)" } } } + +/// Pending component removals for a entity. +#[derive(Debug, Clone, Component)] +pub struct Removals +{ + component_ids: HashSet<Uid>, +} + +impl Removals +{ + pub fn contains<ComponentT: Component>(&self) -> bool + { + self.contains_id(ComponentT::id()) + } + + pub fn contains_id(&self, component_id: Uid) -> bool + { + self.component_ids.contains(&component_id) + } + + pub(crate) fn add_ids(&mut self, ids: impl IntoIterator<Item = Uid>) + { + self.component_ids.extend(ids) + } +} + +impl FromIterator<Uid> for Removals +{ + fn from_iter<T: IntoIterator<Item = Uid>>(iter: T) -> Self + { + Self { + component_ids: iter.into_iter().collect(), + } + } +} |