diff options
author | HampusM <hampus@hampusmat.com> | 2025-04-07 22:20:46 +0200 |
---|---|---|
committer | HampusM <hampus@hampusmat.com> | 2025-04-07 22:20:46 +0200 |
commit | 58dd1d5d79070c3066f50975c918de291bbdf162 (patch) | |
tree | c693c2360e1d8866987c1384168b9edb393d00f0 /ecs/src/component.rs | |
parent | 9faa8b8f530f3640e1a604a4888cc3fa7beafd5f (diff) |
refactor(ecs): make FromLockedOptional not take Lock
Diffstat (limited to 'ecs/src/component.rs')
-rw-r--r-- | ecs/src/component.rs | 149 |
1 files changed, 94 insertions, 55 deletions
diff --git a/ecs/src/component.rs b/ecs/src/component.rs index 9ec962d..c01fd75 100644 --- a/ecs/src/component.rs +++ b/ecs/src/component.rs @@ -1,4 +1,5 @@ use std::any::{type_name, Any}; +use std::error::Error; use std::fmt::Debug; use std::ops::{Deref, DerefMut}; @@ -11,7 +12,6 @@ use crate::event::component::{ }; use crate::lock::{ Error as LockError, - Lock, MappedReadGuard, MappedWriteGuard, ReadGuard, @@ -20,7 +20,7 @@ use crate::lock::{ use crate::system::Input as SystemInput; use crate::uid::Uid; use crate::util::Array; -use crate::World; +use crate::{EntityComponentRef, World}; pub mod local; @@ -33,11 +33,11 @@ pub trait Component: SystemInput + Any where Self: Sized; - type HandleMut<'component>: FromLockedOptional<'component> + type HandleMut<'component>: HandleFromEntityComponentRef<'component> where Self: Sized; - type Handle<'component>: FromLockedOptional<'component> + type Handle<'component>: HandleFromEntityComponentRef<'component> where Self: Sized; @@ -97,8 +97,8 @@ impl Debug for dyn Component impl<ComponentT> Component for Option<ComponentT> where ComponentT: Component, - for<'a> Option<ComponentT::Handle<'a>>: FromLockedOptional<'a>, - for<'a> Option<ComponentT::HandleMut<'a>>: FromLockedOptional<'a>, + 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>>; @@ -155,7 +155,7 @@ pub trait Sequence pub trait Ref { type Component: Component; - type Handle<'component>: FromLockedOptional<'component>; + type Handle<'component>: HandleFromEntityComponentRef<'component>; } impl<ComponentT> Ref for &ComponentT @@ -201,16 +201,15 @@ impl Metadata } } -pub trait FromLockedOptional<'comp>: Sized +pub trait HandleFromEntityComponentRef<'comp>: Sized { - /// Converts a reference to a optional locked boxed component to a instance of `Self`. - /// - /// # Errors - /// Returns `Err` if taking the lock (in a non-blocking way) fails. - fn from_locked_optional_component( - optional_component: Option<&'comp Lock<Box<dyn Component>>>, + type Error: Error; + + /// Creates a new handle instance from a [`EntityComponentRef`]. + fn from_entity_component_ref( + entity_component_ref: Option<EntityComponentRef<'comp>>, world: &'comp World, - ) -> Result<Self, LockError>; + ) -> Result<Self, Self::Error>; } #[derive(Debug)] @@ -236,36 +235,49 @@ impl<'a, ComponentT: Component> Handle<'a, ComponentT> } } -impl<'component, ComponentT: Component> FromLockedOptional<'component> - for Handle<'component, ComponentT> +impl<'comp, ComponentT: Component> HandleFromEntityComponentRef<'comp> + for Handle<'comp, ComponentT> { - fn from_locked_optional_component( - optional_component: Option<&'component crate::lock::Lock<Box<dyn Component>>>, - _world: &'component World, - ) -> Result<Self, LockError> - { - let component = optional_component.unwrap_or_else(|| { - panic!( - "Component {} was not found in entity", - type_name::<ComponentT>() - ); - }); + type Error = HandleError; - Ok(Self::new(component.read_nonblock()?)) + 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<'comp, ComponentT> FromLockedOptional<'comp> for Option<Handle<'comp, ComponentT>> +impl<'comp, ComponentT> HandleFromEntityComponentRef<'comp> + for Option<Handle<'comp, ComponentT>> where ComponentT: Component, { - fn from_locked_optional_component( - optional_component: Option<&'comp Lock<Box<dyn Component>>>, + type Error = HandleError; + + fn from_entity_component_ref( + entity_component_ref: Option<EntityComponentRef<'comp>>, _world: &'comp World, - ) -> Result<Self, LockError> + ) -> Result<Self, Self::Error> { - optional_component - .map(|lock| Ok(Handle::new(lock.read_nonblock()?))) + entity_component_ref + .map(|entity_comp| { + Ok(Handle::new( + entity_comp + .component() + .read_nonblock() + .map_err(AcquireComponentLockFailed)?, + )) + }) .transpose() } } @@ -303,36 +315,49 @@ impl<'a, ComponentT: Component> HandleMut<'a, ComponentT> } } -impl<'component, ComponentT: Component> FromLockedOptional<'component> - for HandleMut<'component, ComponentT> +impl<'comp, ComponentT: Component> HandleFromEntityComponentRef<'comp> + for HandleMut<'comp, ComponentT> { - fn from_locked_optional_component( - optional_component: Option<&'component Lock<Box<dyn Component>>>, - _world: &'component World, - ) -> Result<Self, LockError> - { - let component = optional_component.unwrap_or_else(|| { - panic!( - "Component {} was not found in entity", - type_name::<ComponentT>() - ); - }); + type Error = HandleError; - Ok(Self::new(component.write_nonblock()?)) + 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<'comp, ComponentT> FromLockedOptional<'comp> for Option<HandleMut<'comp, ComponentT>> +impl<'comp, ComponentT> HandleFromEntityComponentRef<'comp> + for Option<HandleMut<'comp, ComponentT>> where ComponentT: Component, { - fn from_locked_optional_component( - optional_component: Option<&'comp Lock<Box<dyn Component>>>, + type Error = HandleError; + + fn from_entity_component_ref( + entity_component_ref: Option<EntityComponentRef<'comp>>, _world: &'comp World, - ) -> Result<Self, LockError> + ) -> Result<Self, Self::Error> { - optional_component - .map(|lock| Ok(HandleMut::new(lock.write_nonblock()?))) + entity_component_ref + .map(|entity_comp| { + Ok(HandleMut::new( + entity_comp + .component() + .write_nonblock() + .map_err(AcquireComponentLockFailed)?, + )) + }) .transpose() } } @@ -355,6 +380,20 @@ impl<ComponentT: Component> DerefMut for HandleMut<'_, ComponentT> } } +#[derive(Debug, thiserror::Error)] +pub enum HandleError +{ + #[error(transparent)] + AcquireComponentLockFailed(#[from] AcquireComponentLockFailed), + + #[error("Component does not exist")] + ComponentDoesNotExist, +} + +#[derive(Debug, thiserror::Error)] +#[error(transparent)] +pub struct AcquireComponentLockFailed(LockError); + macro_rules! inner { ($c: tt) => { seq!(I in 0..=$c { |