summaryrefslogtreecommitdiff
path: root/ecs
diff options
context:
space:
mode:
Diffstat (limited to 'ecs')
-rw-r--r--ecs/src/component.rs185
-rw-r--r--ecs/src/component/storage.rs44
-rw-r--r--ecs/src/component/storage/archetype.rs6
-rw-r--r--ecs/src/component/storage/graph.rs17
-rw-r--r--ecs/src/lib.rs58
-rw-r--r--ecs/src/lock.rs95
-rw-r--r--ecs/src/query.rs10
-rw-r--r--ecs/src/relationship.rs72
-rw-r--r--ecs/src/sole.rs11
-rw-r--r--ecs/src/system/stateful.rs7
-rw-r--r--ecs/src/type_name.rs15
11 files changed, 242 insertions, 278 deletions
diff --git a/ecs/src/component.rs b/ecs/src/component.rs
index 525bd98..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,34 +12,32 @@ use crate::event::component::{
};
use crate::lock::{
Error as LockError,
- Lock,
MappedReadGuard,
MappedWriteGuard,
ReadGuard,
WriteGuard,
};
use crate::system::Input as SystemInput;
-use crate::type_name::TypeName;
use crate::uid::Uid;
use crate::util::Array;
-use crate::World;
+use crate::{EntityComponentRef, World};
pub mod local;
pub(crate) mod storage;
-pub trait Component: SystemInput + Any + TypeName
+pub trait Component: SystemInput + Any
{
/// The component type in question. Will usually be `Self`
type Component: Component
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;
@@ -47,6 +46,9 @@ pub trait Component: SystemInput + Any + TypeName
where
Self: Sized;
+ /// Returns the name of this component.
+ fn name(&self) -> &'static str;
+
/// Returns the component UID of a component event for this component.
fn get_event_uid(&self, event_kind: ComponentEventKind) -> Uid;
@@ -92,19 +94,11 @@ impl Debug for dyn Component
}
}
-impl TypeName for Box<dyn Component>
-{
- fn type_name(&self) -> &'static str
- {
- self.as_ref().type_name()
- }
-}
-
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>>;
@@ -115,6 +109,11 @@ where
ComponentT::id()
}
+ fn name(&self) -> &'static str
+ {
+ type_name::<Self>()
+ }
+
fn get_event_uid(&self, event_kind: ComponentEventKind) -> Uid
{
match event_kind {
@@ -133,16 +132,6 @@ where
}
}
-impl<ComponentT> TypeName for Option<ComponentT>
-where
- ComponentT: Component,
-{
- fn type_name(&self) -> &'static str
- {
- type_name::<Self>()
- }
-}
-
impl<ComponentT> SystemInput for Option<ComponentT> where ComponentT: Component {}
/// A sequence of components.
@@ -166,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
@@ -212,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)]
@@ -238,8 +226,7 @@ impl<'a, ComponentT: Component> Handle<'a, ComponentT>
inner: inner.map(|component| {
component.downcast_ref::<ComponentT>().unwrap_or_else(|| {
panic!(
- "Cannot downcast component {} to type {}",
- component.type_name(),
+ "Failed to downcast component to type {}",
type_name::<ComponentT>()
);
})
@@ -248,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()
}
}
@@ -304,11 +304,9 @@ impl<'a, ComponentT: Component> HandleMut<'a, ComponentT>
{
Self {
inner: inner.map(|component| {
- let component_type_name = component.type_name();
-
component.downcast_mut::<ComponentT>().unwrap_or_else(|| {
panic!(
- "Cannot downcast component {component_type_name} to type {}",
+ "Failed to downcast component to type {}",
type_name::<ComponentT>()
);
})
@@ -317,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()
}
}
@@ -369,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 {
diff --git a/ecs/src/component/storage.rs b/ecs/src/component/storage.rs
index 40909fb..14aa191 100644
--- a/ecs/src/component/storage.rs
+++ b/ecs/src/component/storage.rs
@@ -1,4 +1,3 @@
-use std::any::type_name;
use std::array::IntoIter as ArrayIter;
use std::cell::RefCell;
use std::vec::IntoIter as VecIntoIter;
@@ -18,7 +17,6 @@ use crate::component::storage::graph::{
Graph,
};
use crate::component::Component;
-use crate::type_name::TypeName;
use crate::uid::{Kind as UidKind, Uid};
use crate::util::{BorrowedOrOwned, Either, StreamingIterator, VecExt};
@@ -161,11 +159,13 @@ impl Storage
pub fn add_entity_component(
&mut self,
entity_uid: Uid,
- component: (Uid, Box<dyn Component>),
+ (component_id, component_name, component): (
+ Uid,
+ &'static str,
+ Box<dyn Component>,
+ ),
) -> Result<(), Error>
{
- let (component_id, component) = component;
-
debug_assert!(
!component.self_is_optional(),
"Adding a optional component to a entity is not supported"
@@ -212,17 +212,12 @@ impl Storage
None => {
let archetype_node = self
.graph
- .get_node_by_id_mut(archetype_id)
+ .get_node_by_id(archetype_id)
.expect("Archetype should exist");
let (add_edge_id, add_edge_comp_ids) =
archetype_node.make_add_edge(component_id);
- archetype_node
- .get_edges_mut(component_id)
- .expect("Edges for component in archetype should exist")
- .add = Some(add_edge_id);
-
if !self.graph.contains_archetype(add_edge_id) {
self.graph.create_node(add_edge_id, &add_edge_comp_ids);
}
@@ -231,18 +226,6 @@ impl Storage
}
};
- {
- let add_edge_archetype_node = self
- .graph
- .get_node_by_id_mut(add_edge_archetype_id)
- .expect("Add edge archetype should exist");
-
- let add_edge_archetype_edges = add_edge_archetype_node
- .get_or_insert_edges(component_id, ArchetypeEdges::default);
-
- add_edge_archetype_edges.remove = Some(archetype_id);
- }
-
let archetype_node = self
.graph
.get_node_by_id_mut(archetype_id)
@@ -261,7 +244,7 @@ impl Storage
entity.insert_component(
component_id,
- ArchetypeEntityComponent::new(component),
+ ArchetypeEntityComponent::new(component, component_name),
add_edge_archetype,
);
@@ -312,11 +295,6 @@ impl Storage
let (remove_edge_id, remove_edge_comp_ids) =
archetype_node.make_remove_edge(component_id);
- archetype_node
- .get_edges_mut(component_id)
- .expect("Edges for component in archetype should exist")
- .remove = Some(remove_edge_id);
-
if !self.graph.contains_archetype(remove_edge_id) {
self.graph
.create_node(remove_edge_id, &remove_edge_comp_ids);
@@ -415,14 +393,6 @@ impl Storage
}
}
-impl TypeName for Storage
-{
- fn type_name(&self) -> &'static str
- {
- type_name::<Self>()
- }
-}
-
#[cfg(feature = "vizoxide")]
impl Storage
{
diff --git a/ecs/src/component/storage/archetype.rs b/ecs/src/component/storage/archetype.rs
index 5306cf9..8d48e13 100644
--- a/ecs/src/component/storage/archetype.rs
+++ b/ecs/src/component/storage/archetype.rs
@@ -215,11 +215,11 @@ pub struct EntityComponent
impl EntityComponent
{
- pub fn new(component: Box<dyn Component>) -> Self
+ pub fn new(component: Box<dyn Component>, component_name: &'static str) -> Self
{
Self {
- name: component.type_name(),
- component: Lock::new(component),
+ name: component_name,
+ component: Lock::new(component, component_name),
}
}
diff --git a/ecs/src/component/storage/graph.rs b/ecs/src/component/storage/graph.rs
index 11160e7..d38223a 100644
--- a/ecs/src/component/storage/graph.rs
+++ b/ecs/src/component/storage/graph.rs
@@ -140,7 +140,7 @@ impl Graph
}
fn create_missing_subset_node_edges(
- target_node: &ArchetypeNode,
+ target_node: &mut ArchetypeNode,
subset_node: &mut ArchetypeNode,
)
{
@@ -153,6 +153,14 @@ impl Graph
subset_node
.get_or_insert_edges(uniq_comp_id, ArchetypeEdges::default)
.add = Some(subset_node.make_add_edge(uniq_comp_id).0);
+
+ if target_node.archetype().component_cnt()
+ == subset_node.archetype().component_cnt() + 1
+ {
+ target_node
+ .get_or_insert_edges(uniq_comp_id, ArchetypeEdges::default)
+ .remove = Some(subset_node.archetype().id());
+ }
}
fn create_missing_superset_node_edges(
@@ -245,13 +253,6 @@ impl ArchetypeNode
self.edges.iter()
}
- pub fn get_edges_mut(&mut self, component_id: Uid) -> Option<&mut ArchetypeEdges>
- {
- debug_assert_eq!(component_id.kind(), UidKind::Component);
-
- self.edges.get_mut(&component_id)
- }
-
pub fn make_add_edge(&self, component_id: Uid) -> (ArchetypeId, Vec<Uid>)
{
let mut edge_comp_ids = self
diff --git a/ecs/src/lib.rs b/ecs/src/lib.rs
index 32d82bc..3f0042c 100644
--- a/ecs/src/lib.rs
+++ b/ecs/src/lib.rs
@@ -31,7 +31,6 @@ use crate::relationship::{ChildOf, DependsOn, Relationship};
use crate::sole::Sole;
use crate::stats::Stats;
use crate::system::{System, SystemComponent};
-use crate::type_name::TypeName;
use crate::uid::{Kind as UidKind, Uid};
pub mod actions;
@@ -39,7 +38,7 @@ pub mod component;
pub mod entity;
pub mod event;
pub mod extension;
-pub mod lock;
+mod lock;
pub mod phase;
pub mod query;
pub mod relationship;
@@ -47,7 +46,6 @@ pub mod sole;
pub mod stats;
pub mod system;
pub mod tuple;
-pub mod type_name;
pub mod uid;
pub mod util;
@@ -511,9 +509,10 @@ impl World
)
{
for (component_id, component) in components {
- if let Err(err) = component_storage
- .add_entity_component(entity_uid, (component_id, component))
- {
+ if let Err(err) = component_storage.add_entity_component(
+ entity_uid,
+ (component_id, component.name(), component),
+ ) {
tracing::error!("Failed to add component to entity: {err}");
}
}
@@ -588,7 +587,7 @@ pub enum StepResult
Stop,
}
-#[derive(Debug, Default)]
+#[derive(Debug)]
pub struct WorldData
{
component_storage: Arc<Lock<ComponentStorage>>,
@@ -596,6 +595,21 @@ pub struct WorldData
action_queue: Arc<ActionQueue>,
}
+impl Default for WorldData
+{
+ fn default() -> Self
+ {
+ Self {
+ component_storage: Arc::new(Lock::new(
+ ComponentStorage::default(),
+ type_name::<ComponentStorage>(),
+ )),
+ sole_storage: SoleStorage::default(),
+ action_queue: Arc::new(ActionQueue::default()),
+ }
+ }
+}
+
#[derive(Debug)]
pub struct EntityComponentRef<'a>
{
@@ -604,7 +618,7 @@ pub struct EntityComponentRef<'a>
impl<'a> EntityComponentRef<'a>
{
- pub fn component(&self) -> &'a Lock<Box<dyn Component>>
+ fn component(&self) -> &'a Lock<Box<dyn Component>>
{
self.comp.component()
}
@@ -623,7 +637,7 @@ enum ActiveActionQueue
B,
}
-#[derive(Debug, Default)]
+#[derive(Debug)]
struct ActionQueue
{
queue_a: Lock<Vec<Action>>,
@@ -650,11 +664,15 @@ impl ActionQueue
}
}
-impl TypeName for ActionQueue
+impl Default for ActionQueue
{
- fn type_name(&self) -> &'static str
+ fn default() -> Self
{
- type_name::<Self>()
+ Self {
+ queue_a: Lock::new(Vec::new(), type_name::<Vec<Action>>()),
+ queue_b: Lock::new(Vec::new(), type_name::<Vec<Action>>()),
+ active_queue: RefCell::new(ActiveActionQueue::default()),
+ }
}
}
@@ -699,7 +717,7 @@ impl SoleStorage
self.storage.insert(
sole_type_id,
ManuallyDrop::new(StoredSole {
- sole: Arc::new(Lock::new(Box::new(sole))),
+ sole: Arc::new(Lock::new(Box::new(sole), type_name::<SoleT>())),
drop_last,
}),
);
@@ -716,18 +734,9 @@ impl Drop for SoleStorage
for sole in self.storage.values_mut() {
if sole.drop_last {
- tracing::trace!(
- "Sole {} pushed to dropping last queue",
- sole.sole.read_nonblock().unwrap().type_name()
- );
-
soles_to_drop_last.push(sole);
continue;
}
- tracing::trace!(
- "Dropping sole {}",
- sole.sole.read_nonblock().unwrap().type_name()
- );
unsafe {
ManuallyDrop::drop(sole);
@@ -735,11 +744,6 @@ impl Drop for SoleStorage
}
for sole in &mut soles_to_drop_last {
- tracing::trace!(
- "Dropping sole {} last",
- sole.sole.read_nonblock().unwrap().type_name()
- );
-
unsafe {
ManuallyDrop::drop(sole);
}
diff --git a/ecs/src/lock.rs b/ecs/src/lock.rs
index d6ed40e..0b36922 100644
--- a/ecs/src/lock.rs
+++ b/ecs/src/lock.rs
@@ -9,23 +9,21 @@ use parking_lot::{
RwLockWriteGuard,
};
-use crate::type_name::TypeName;
-
-#[derive(Debug, Default)]
+#[derive(Debug)]
pub struct Lock<Value>
-where
- Value: TypeName,
{
inner: RwLock<Value>,
+ value_type_name: &'static str,
}
impl<Value> Lock<Value>
-where
- Value: TypeName,
{
- pub fn new(value: Value) -> Self
+ pub fn new(value: Value, value_type_name: &'static str) -> Self
{
- Self { inner: RwLock::new(value) }
+ Self {
+ inner: RwLock::new(value),
+ value_type_name,
+ }
}
/// Tries to a acquire a handle to the resource with read access.
@@ -36,9 +34,12 @@ where
{
let guard = self.inner.try_read().ok_or(Error::ReadUnavailable)?;
- tracing::trace!("Acquired lock to value of type {}", guard.type_name());
+ tracing::trace!("Acquired lock to value of type {}", self.value_type_name);
- Ok(ReadGuard { inner: guard })
+ Ok(ReadGuard {
+ inner: guard,
+ value_type_name: self.value_type_name,
+ })
}
/// Tries to a acquire a handle to the resource with mutable access.
@@ -51,15 +52,13 @@ where
tracing::trace!(
"Acquired mutable lock to value of type {}",
- guard.type_name()
+ self.value_type_name
);
- Ok(WriteGuard { inner: guard })
- }
-
- pub fn into_inner(self) -> Value
- {
- self.inner.into_inner()
+ Ok(WriteGuard {
+ inner: guard,
+ value_type_name: self.value_type_name,
+ })
}
}
@@ -75,23 +74,20 @@ pub enum Error
#[derive(Debug)]
pub struct ReadGuard<'guard, Value>
-where
- Value: TypeName,
{
inner: RwLockReadGuard<'guard, Value>,
+ value_type_name: &'static str,
}
impl<'guard, Value> ReadGuard<'guard, Value>
-where
- Value: TypeName,
{
pub fn map<NewValue>(
self,
func: impl FnOnce(&Value) -> &NewValue,
) -> MappedReadGuard<'guard, NewValue>
- where
- NewValue: TypeName,
{
+ let value_type_name = self.value_type_name;
+
// The 'inner' field cannot be moved out of ReadGuard in a normal way since
// ReadGuard implements Drop
let inner = unsafe { std::ptr::read(&self.inner) };
@@ -99,13 +95,12 @@ where
MappedReadGuard {
inner: RwLockReadGuard::map(inner, func),
+ value_type_name,
}
}
}
impl<Value> Deref for ReadGuard<'_, Value>
-where
- Value: TypeName,
{
type Target = Value;
@@ -116,26 +111,21 @@ where
}
impl<Value> Drop for ReadGuard<'_, Value>
-where
- Value: TypeName,
{
fn drop(&mut self)
{
- tracing::trace!("Dropped lock to value of type {}", self.type_name());
+ tracing::trace!("Dropped lock to value of type {}", self.value_type_name);
}
}
#[derive(Debug)]
pub struct MappedReadGuard<'guard, Value>
-where
- Value: TypeName,
{
inner: MappedRwLockReadGuard<'guard, Value>,
+ value_type_name: &'static str,
}
impl<Value> Deref for MappedReadGuard<'_, Value>
-where
- Value: TypeName,
{
type Target = Value;
@@ -146,34 +136,32 @@ where
}
impl<Value> Drop for MappedReadGuard<'_, Value>
-where
- Value: TypeName,
{
fn drop(&mut self)
{
- tracing::trace!("Dropped mapped lock to value of type {}", self.type_name());
+ tracing::trace!(
+ "Dropped mapped lock to value of type {}",
+ self.value_type_name
+ );
}
}
#[derive(Debug)]
pub struct WriteGuard<'guard, Value>
-where
- Value: TypeName,
{
inner: RwLockWriteGuard<'guard, Value>,
+ value_type_name: &'static str,
}
impl<'guard, Value> WriteGuard<'guard, Value>
-where
- Value: TypeName,
{
pub fn map<NewValue>(
self,
func: impl FnOnce(&mut Value) -> &mut NewValue,
) -> MappedWriteGuard<'guard, NewValue>
- where
- NewValue: TypeName,
{
+ let value_type_name = self.value_type_name;
+
// The 'inner' field cannot be moved out of ReadGuard in a normal way since
// ReadGuard implements Drop
let inner = unsafe { std::ptr::read(&self.inner) };
@@ -181,13 +169,12 @@ where
MappedWriteGuard {
inner: RwLockWriteGuard::map(inner, func),
+ value_type_name,
}
}
}
impl<Value> Deref for WriteGuard<'_, Value>
-where
- Value: TypeName,
{
type Target = Value;
@@ -198,8 +185,6 @@ where
}
impl<Value> DerefMut for WriteGuard<'_, Value>
-where
- Value: TypeName,
{
fn deref_mut(&mut self) -> &mut Self::Target
{
@@ -208,26 +193,24 @@ where
}
impl<Value> Drop for WriteGuard<'_, Value>
-where
- Value: TypeName,
{
fn drop(&mut self)
{
- tracing::trace!("Dropped mutable lock to value of type {}", self.type_name());
+ tracing::trace!(
+ "Dropped mutable lock to value of type {}",
+ self.value_type_name
+ );
}
}
#[derive(Debug)]
pub struct MappedWriteGuard<'guard, Value>
-where
- Value: TypeName,
{
inner: MappedRwLockWriteGuard<'guard, Value>,
+ value_type_name: &'static str,
}
impl<Value> Deref for MappedWriteGuard<'_, Value>
-where
- Value: TypeName,
{
type Target = Value;
@@ -238,8 +221,6 @@ where
}
impl<Value> DerefMut for MappedWriteGuard<'_, Value>
-where
- Value: TypeName,
{
fn deref_mut(&mut self) -> &mut Self::Target
{
@@ -248,14 +229,12 @@ where
}
impl<Value> Drop for MappedWriteGuard<'_, Value>
-where
- Value: TypeName,
{
fn drop(&mut self)
{
tracing::trace!(
"Dropped mapped mutable lock to value of type {}",
- self.type_name()
+ self.value_type_name
);
}
}
diff --git a/ecs/src/query.rs b/ecs/src/query.rs
index b29db3d..f642156 100644
--- a/ecs/src/query.rs
+++ b/ecs/src/query.rs
@@ -3,7 +3,7 @@ use std::marker::PhantomData;
use seq_macro::seq;
-use crate::component::{Component, FromLockedOptional, Ref as ComponentRef};
+use crate::component::{Component, HandleFromEntityComponentRef, Ref as ComponentRef};
use crate::entity::Handle as EntityHandle;
use crate::query::flexible::{Iter as FlexibleQueryIter, Query as FlexibleQuery};
use crate::system::{Param as SystemParam, System};
@@ -314,15 +314,13 @@ impl<ComponentRefT: ComponentRef> TermWithField for ComponentRefT
world: &'world World,
) -> Self::Field<'world>
{
- Self::Field::from_locked_optional_component(
- entity_handle
- .get_component(ComponentRefT::Component::id())
- .map(|component| component.component()),
+ Self::Field::from_entity_component_ref(
+ entity_handle.get_component(ComponentRefT::Component::id()),
world,
)
.unwrap_or_else(|err| {
panic!(
- "Taking component {} lock failed: {err}",
+ "Creating handle to component {} failed: {err}",
type_name::<ComponentRefT::Component>()
);
})
diff --git a/ecs/src/relationship.rs b/ecs/src/relationship.rs
index 45fa265..c5399e4 100644
--- a/ecs/src/relationship.rs
+++ b/ecs/src/relationship.rs
@@ -6,13 +6,14 @@ use ecs_macros::Component;
use crate::component::storage::Storage as ComponentStorage;
use crate::component::{
Component,
- FromLockedOptional as FromLockedOptionalComponent,
Handle as ComponentHandle,
+ HandleError as ComponentHandleError,
+ HandleFromEntityComponentRef,
HandleMut as ComponentHandleMut,
};
-use crate::lock::{Error as LockError, Lock, ReadGuard};
+use crate::lock::ReadGuard;
use crate::uid::{Kind as UidKind, Uid};
-use crate::World;
+use crate::{EntityComponentRef, World};
/// A relationship to one or more targets.
#[derive(Debug, Component)]
@@ -70,22 +71,24 @@ where
relationship_comp: ComponentHandleMut<'rel_comp, Relationship<Kind, ComponentT>>,
}
-impl<'rel_comp, Kind, ComponentT> FromLockedOptionalComponent<'rel_comp>
+impl<'rel_comp, Kind, ComponentT> HandleFromEntityComponentRef<'rel_comp>
for RelationMut<'rel_comp, Kind, ComponentT>
where
ComponentT: Component,
{
- fn from_locked_optional_component(
- optional_component: Option<&'rel_comp crate::lock::Lock<Box<dyn Component>>>,
+ type Error = ComponentHandleError;
+
+ fn from_entity_component_ref(
+ entity_component_ref: Option<EntityComponentRef<'rel_comp>>,
world: &'rel_comp World,
- ) -> Result<Self, LockError>
+ ) -> Result<Self, Self::Error>
{
- let relationship_comp_handle_from_locked_opt_comp = ComponentHandleMut::<
+ let relationship_comp_handle_from_ent_comp_ref = ComponentHandleMut::<
Relationship<Kind, ComponentT>,
- >::from_locked_optional_component;
+ >::from_entity_component_ref;
let relationship_comp =
- relationship_comp_handle_from_locked_opt_comp(optional_component, world)?;
+ relationship_comp_handle_from_ent_comp_ref(entity_component_ref, world)?;
let component_storage_lock = world
.data
@@ -100,19 +103,21 @@ where
}
}
-impl<'rel_comp, Kind, ComponentT> FromLockedOptionalComponent<'rel_comp>
+impl<'rel_comp, Kind, ComponentT> HandleFromEntityComponentRef<'rel_comp>
for Option<RelationMut<'rel_comp, Kind, ComponentT>>
where
ComponentT: Component,
{
- fn from_locked_optional_component(
- optional_component: Option<&'rel_comp Lock<Box<dyn Component>>>,
+ type Error = ComponentHandleError;
+
+ fn from_entity_component_ref(
+ entity_component_ref: Option<EntityComponentRef<'rel_comp>>,
world: &'rel_comp World,
- ) -> Result<Self, crate::lock::Error>
+ ) -> Result<Self, Self::Error>
{
- optional_component
- .map(|component| {
- RelationMut::from_locked_optional_component(Some(component), world)
+ entity_component_ref
+ .map(|entity_comp| {
+ RelationMut::from_entity_component_ref(Some(entity_comp), world)
})
.transpose()
}
@@ -292,22 +297,23 @@ where
relationship_comp: ComponentHandle<'rel_comp, Relationship<Kind, ComponentT>>,
}
-impl<'rel_comp, Kind, ComponentT> FromLockedOptionalComponent<'rel_comp>
+impl<'rel_comp, Kind, ComponentT> HandleFromEntityComponentRef<'rel_comp>
for Relation<'rel_comp, Kind, ComponentT>
where
ComponentT: Component,
{
- fn from_locked_optional_component(
- optional_component: Option<&'rel_comp Lock<Box<dyn Component>>>,
+ type Error = ComponentHandleError;
+
+ fn from_entity_component_ref(
+ entity_component_ref: Option<EntityComponentRef<'rel_comp>>,
world: &'rel_comp World,
- ) -> Result<Self, LockError>
+ ) -> Result<Self, Self::Error>
{
- let relationship_comp_handle_from_locked_opt_comp = ComponentHandle::<
- Relationship<Kind, ComponentT>,
- >::from_locked_optional_component;
+ let relationship_comp_handle_from_ent_comp_ref =
+ ComponentHandle::<Relationship<Kind, ComponentT>>::from_entity_component_ref;
let relationship_comp =
- relationship_comp_handle_from_locked_opt_comp(optional_component, world)?;
+ relationship_comp_handle_from_ent_comp_ref(entity_component_ref, world)?;
let component_storage_lock = world
.data
@@ -322,19 +328,21 @@ where
}
}
-impl<'rel_comp, Kind, ComponentT> FromLockedOptionalComponent<'rel_comp>
+impl<'rel_comp, Kind, ComponentT> HandleFromEntityComponentRef<'rel_comp>
for Option<Relation<'rel_comp, Kind, ComponentT>>
where
ComponentT: Component,
{
- fn from_locked_optional_component(
- optional_component: Option<&'rel_comp Lock<Box<dyn Component>>>,
+ type Error = ComponentHandleError;
+
+ fn from_entity_component_ref(
+ entity_component_ref: Option<EntityComponentRef<'rel_comp>>,
world: &'rel_comp World,
- ) -> Result<Self, crate::lock::Error>
+ ) -> Result<Self, ComponentHandleError>
{
- optional_component
- .map(|component| {
- Relation::from_locked_optional_component(Some(component), world)
+ entity_component_ref
+ .map(|entity_comp| {
+ Relation::from_entity_component_ref(Some(entity_comp), world)
})
.transpose()
}
diff --git a/ecs/src/sole.rs b/ecs/src/sole.rs
index 5af5ce3..1cce419 100644
--- a/ecs/src/sole.rs
+++ b/ecs/src/sole.rs
@@ -6,11 +6,10 @@ use std::sync::{Arc, Weak};
use crate::lock::{Lock, WriteGuard};
use crate::system::{Param as SystemParam, System};
-use crate::type_name::TypeName;
use crate::World;
/// A type which has a single instance and is shared globally.
-pub trait Sole: Any + TypeName
+pub trait Sole: Any
{
fn drop_last(&self) -> bool;
@@ -40,14 +39,6 @@ impl Debug for dyn Sole
}
}
-impl TypeName for Box<dyn Sole>
-{
- fn type_name(&self) -> &'static str
- {
- self.as_ref().type_name()
- }
-}
-
/// Holds a reference to a globally shared singleton value.
#[derive(Debug)]
pub struct Single<'world, SoleT: Sole>
diff --git a/ecs/src/system/stateful.rs b/ecs/src/system/stateful.rs
index 9d911ee..5415cc7 100644
--- a/ecs/src/system/stateful.rs
+++ b/ecs/src/system/stateful.rs
@@ -1,4 +1,4 @@
-use std::any::{Any, TypeId};
+use std::any::{type_name, Any, TypeId};
use std::panic::{RefUnwindSafe, UnwindSafe};
use hashbrown::HashMap;
@@ -127,7 +127,10 @@ macro_rules! impl_system {
self.local_components
.insert(
LocalComponent::id(),
- Lock::new(Box::new(local_component))
+ Lock::new(
+ Box::new(local_component),
+ type_name::<LocalComponent>()
+ )
);
}
}
diff --git a/ecs/src/type_name.rs b/ecs/src/type_name.rs
deleted file mode 100644
index 54179be..0000000
--- a/ecs/src/type_name.rs
+++ /dev/null
@@ -1,15 +0,0 @@
-use std::any::type_name;
-
-pub trait TypeName
-{
- /// Returns the name of this type.
- fn type_name(&self) -> &'static str;
-}
-
-impl<Item> TypeName for Vec<Item>
-{
- fn type_name(&self) -> &'static str
- {
- type_name::<Self>()
- }
-}