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.rs472
1 files changed, 0 insertions, 472 deletions
diff --git a/ecs/src/component.rs b/ecs/src/component.rs
deleted file mode 100644
index 525bd98..0000000
--- a/ecs/src/component.rs
+++ /dev/null
@@ -1,472 +0,0 @@
-use std::any::{type_name, Any};
-use std::fmt::Debug;
-use std::ops::{Deref, DerefMut};
-
-use seq_macro::seq;
-
-use crate::event::component::{
- Added as ComponentAddedEvent,
- Kind as ComponentEventKind,
- Removed as ComponentRemovedEvent,
-};
-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;
-
-pub mod local;
-
-pub(crate) mod storage;
-
-pub trait Component: SystemInput + Any + TypeName
-{
- /// The component type in question. Will usually be `Self`
- type Component: Component
- where
- Self: Sized;
-
- type HandleMut<'component>: FromLockedOptional<'component>
- where
- Self: Sized;
-
- type Handle<'component>: FromLockedOptional<'component>
- where
- Self: Sized;
-
- /// Returns the ID of this component.
- fn id() -> Uid
- where
- Self: Sized;
-
- /// Returns the component UID of a component event for this component.
- fn get_event_uid(&self, event_kind: ComponentEventKind) -> Uid;
-
- /// Returns whether the component `self` is optional.
- fn self_is_optional(&self) -> bool
- {
- false
- }
-
- /// Returns whether this component is optional.
- #[must_use]
- fn is_optional() -> bool
- where
- Self: Sized,
- {
- false
- }
-}
-
-impl dyn Component
-{
- pub fn downcast_mut<Real: 'static>(&mut self) -> Option<&mut Real>
- {
- (self as &mut dyn Any).downcast_mut()
- }
-
- pub fn downcast_ref<Real: 'static>(&self) -> Option<&Real>
- {
- (self as &dyn Any).downcast_ref()
- }
-
- pub fn is<Other: 'static>(&self) -> bool
- {
- (self as &dyn Any).is::<Other>()
- }
-}
-
-impl Debug for dyn Component
-{
- fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result
- {
- formatter.debug_struct("Component").finish_non_exhaustive()
- }
-}
-
-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>,
-{
- type Component = ComponentT;
- type Handle<'component> = Option<ComponentT::Handle<'component>>;
- type HandleMut<'component> = Option<ComponentT::HandleMut<'component>>;
-
- fn id() -> Uid
- {
- ComponentT::id()
- }
-
- fn get_event_uid(&self, event_kind: ComponentEventKind) -> Uid
- {
- match event_kind {
- ComponentEventKind::Removed => ComponentRemovedEvent::<Self>::id(),
- }
- }
-
- fn self_is_optional(&self) -> bool
- {
- true
- }
-
- fn is_optional() -> bool
- {
- true
- }
-}
-
-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.
-pub trait Sequence
-{
- /// The number of components in this component sequence.
- const COUNT: usize;
-
- type Array: Array<(Uid, Box<dyn Component>)>;
-
- fn into_array(self) -> Self::Array;
-
- fn metadata() -> impl Array<Metadata>;
-
- fn added_event_ids() -> Vec<Uid>;
-
- fn removed_event_ids() -> Vec<Uid>;
-}
-
-/// A mutable or immutable reference to a component.
-pub trait Ref
-{
- type Component: Component;
- type Handle<'component>: FromLockedOptional<'component>;
-}
-
-impl<ComponentT> Ref for &ComponentT
-where
- ComponentT: Component,
-{
- type Component = ComponentT;
- type Handle<'component> = ComponentT::Handle<'component>;
-}
-
-impl<ComponentT> Ref for &mut ComponentT
-where
- ComponentT: Component,
-{
- type Component = ComponentT;
- type Handle<'component> = ComponentT::HandleMut<'component>;
-}
-
-/// [`Component`] metadata.
-#[derive(Debug, Clone)]
-#[non_exhaustive]
-pub struct Metadata
-{
- pub id: Uid,
- pub is_optional: bool,
-}
-
-impl Metadata
-{
- #[must_use]
- pub fn new_non_optional(id: Uid) -> Self
- {
- Self { id, is_optional: false }
- }
-
- #[must_use]
- pub fn of<ComponentT: Component>() -> Self
- {
- Self {
- id: ComponentT::id(),
- is_optional: ComponentT::is_optional(),
- }
- }
-}
-
-pub trait FromLockedOptional<'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>>>,
- world: &'comp World,
- ) -> Result<Self, LockError>;
-}
-
-#[derive(Debug)]
-pub struct Handle<'a, ComponentT: Component>
-{
- inner: MappedReadGuard<'a, ComponentT>,
-}
-
-impl<'a, ComponentT: Component> Handle<'a, ComponentT>
-{
- pub(crate) fn new(inner: ReadGuard<'a, Box<dyn Component>>) -> Self
- {
- Self {
- inner: inner.map(|component| {
- component.downcast_ref::<ComponentT>().unwrap_or_else(|| {
- panic!(
- "Cannot downcast component {} to type {}",
- component.type_name(),
- type_name::<ComponentT>()
- );
- })
- }),
- }
- }
-}
-
-impl<'component, ComponentT: Component> FromLockedOptional<'component>
- for Handle<'component, 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>()
- );
- });
-
- Ok(Self::new(component.read_nonblock()?))
- }
-}
-
-impl<'comp, ComponentT> FromLockedOptional<'comp> for Option<Handle<'comp, ComponentT>>
-where
- ComponentT: Component,
-{
- fn from_locked_optional_component(
- optional_component: Option<&'comp Lock<Box<dyn Component>>>,
- _world: &'comp World,
- ) -> Result<Self, LockError>
- {
- optional_component
- .map(|lock| Ok(Handle::new(lock.read_nonblock()?)))
- .transpose()
- }
-}
-
-impl<ComponentT: Component> Deref for Handle<'_, ComponentT>
-{
- type Target = ComponentT;
-
- fn deref(&self) -> &Self::Target
- {
- &self.inner
- }
-}
-
-#[derive(Debug)]
-pub struct HandleMut<'a, ComponentT: Component>
-{
- inner: MappedWriteGuard<'a, ComponentT>,
-}
-
-impl<'a, ComponentT: Component> HandleMut<'a, ComponentT>
-{
- pub(crate) fn new(inner: WriteGuard<'a, Box<dyn Component>>) -> Self
- {
- 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 {}",
- type_name::<ComponentT>()
- );
- })
- }),
- }
- }
-}
-
-impl<'component, ComponentT: Component> FromLockedOptional<'component>
- for HandleMut<'component, 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>()
- );
- });
-
- Ok(Self::new(component.write_nonblock()?))
- }
-}
-
-impl<'comp, ComponentT> FromLockedOptional<'comp> for Option<HandleMut<'comp, ComponentT>>
-where
- ComponentT: Component,
-{
- fn from_locked_optional_component(
- optional_component: Option<&'comp Lock<Box<dyn Component>>>,
- _world: &'comp World,
- ) -> Result<Self, LockError>
- {
- optional_component
- .map(|lock| Ok(HandleMut::new(lock.write_nonblock()?)))
- .transpose()
- }
-}
-
-impl<ComponentT: Component> Deref for HandleMut<'_, ComponentT>
-{
- type Target = ComponentT;
-
- fn deref(&self) -> &Self::Target
- {
- &self.inner
- }
-}
-
-impl<ComponentT: Component> DerefMut for HandleMut<'_, ComponentT>
-{
- fn deref_mut(&mut self) -> &mut Self::Target
- {
- &mut self.inner
- }
-}
-
-macro_rules! inner {
- ($c: tt) => {
- seq!(I in 0..=$c {
- impl<#(IntoComp~I,)*> Sequence for (#(IntoComp~I,)*)
- where
- #(
- for<'comp> IntoComp~I: Into<Component: Component>,
- )*
- {
- const COUNT: usize = $c + 1;
-
- type Array = [(Uid, Box<dyn Component>); $c + 1];
-
- fn into_array(self) -> Self::Array
- {
- [#({
- let (id, component) = self.I.into_component();
-
- (id, Box::new(component))
- },)*]
- }
-
- fn metadata() -> impl Array<Metadata>
- {
- [
- #(
- Metadata {
- id: IntoComp~I::Component::id(),
- is_optional: IntoComp~I::Component::is_optional(),
- },
- )*
- ]
- }
-
- fn added_event_ids() -> Vec<Uid>
- {
- vec![
- #(ComponentAddedEvent::<IntoComp~I::Component>::id(),)*
- ]
- }
-
- fn removed_event_ids() -> Vec<Uid>
- {
- vec![
- #(ComponentRemovedEvent::<IntoComp~I::Component>::id(),)*
- ]
- }
- }
- });
- };
-}
-
-seq!(C in 0..=16 {
- inner!(C);
-});
-
-impl Sequence for ()
-{
- type Array = [(Uid, Box<dyn Component>); 0];
-
- const COUNT: usize = 0;
-
- fn into_array(self) -> Self::Array
- {
- []
- }
-
- fn metadata() -> impl Array<Metadata>
- {
- []
- }
-
- fn added_event_ids() -> Vec<Uid>
- {
- Vec::new()
- }
-
- fn removed_event_ids() -> Vec<Uid>
- {
- Vec::new()
- }
-}
-
-pub trait Into
-{
- type Component;
-
- fn into_component(self) -> (Uid, Self::Component);
-}
-
-impl<ComponentT> Into for ComponentT
-where
- ComponentT: Component,
-{
- type Component = Self;
-
- fn into_component(self) -> (Uid, Self::Component)
- {
- (Self::id(), self)
- }
-}