summaryrefslogtreecommitdiff
path: root/ecs/src/component.rs
diff options
context:
space:
mode:
authorHampusM <hampus@hampusmat.com>2025-04-07 22:20:46 +0200
committerHampusM <hampus@hampusmat.com>2025-04-07 22:20:46 +0200
commit58dd1d5d79070c3066f50975c918de291bbdf162 (patch)
treec693c2360e1d8866987c1384168b9edb393d00f0 /ecs/src/component.rs
parent9faa8b8f530f3640e1a604a4888cc3fa7beafd5f (diff)
refactor(ecs): make FromLockedOptional not take Lock
Diffstat (limited to 'ecs/src/component.rs')
-rw-r--r--ecs/src/component.rs149
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 {