summaryrefslogtreecommitdiff
path: root/ecs/src/component.rs
diff options
context:
space:
mode:
Diffstat (limited to 'ecs/src/component.rs')
-rw-r--r--ecs/src/component.rs170
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(),
+ }
+ }
+}