use std::any::{type_name, Any}; use std::error::Error; 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, MappedReadGuard, MappedWriteGuard, ReadGuard, WriteGuard, }; use crate::system::Input as SystemInput; use crate::uid::Uid; use crate::util::Array; use crate::{EntityComponentRef, World}; pub mod local; pub(crate) mod storage; pub trait Component: SystemInput + Any { /// The component type in question. Will usually be `Self` type Component: Component where Self: Sized; 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 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; /// 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(&mut self) -> Option<&mut Real> { (self as &mut dyn Any).downcast_mut() } pub fn downcast_ref(&self) -> Option<&Real> { (self as &dyn Any).downcast_ref() } pub fn is(&self) -> bool { (self as &dyn Any).is::() } } impl Debug for dyn Component { fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { formatter.debug_struct("Component").finish_non_exhaustive() } } impl Component for Option where ComponentT: Component, for<'a> Option>: HandleFromEntityComponentRef<'a>, for<'a> Option>: HandleFromEntityComponentRef<'a>, { type Component = ComponentT; type Handle<'component> = Option>; type HandleMut<'component> = Option>; fn id() -> Uid { ComponentT::id() } fn name(&self) -> &'static str { type_name::() } fn get_event_uid(&self, event_kind: ComponentEventKind) -> Uid { match event_kind { ComponentEventKind::Removed => ComponentRemovedEvent::::id(), } } fn self_is_optional(&self) -> bool { true } fn is_optional() -> bool { true } } impl SystemInput for Option 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)>; fn into_array(self) -> Self::Array; fn metadata() -> impl Array; fn added_event_ids() -> Vec; fn removed_event_ids() -> Vec; } /// A mutable or immutable reference to a component. pub trait Ref { type Component: Component; type Handle<'component>: HandleFromEntityComponentRef<'component>; } impl Ref for &ComponentT where ComponentT: Component, { type Component = ComponentT; type Handle<'component> = ComponentT::Handle<'component>; } impl 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() -> Self { Self { id: ComponentT::id(), is_optional: ComponentT::is_optional(), } } } pub trait HandleFromEntityComponentRef<'comp>: Sized { type Error: Error; /// Creates a new handle instance from a [`EntityComponentRef`]. fn from_entity_component_ref( entity_component_ref: Option>, world: &'comp World, ) -> Result; } #[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>) -> Self { Self { inner: inner.map(|component| { component.downcast_ref::().unwrap_or_else(|| { panic!( "Failed to downcast component to type {}", type_name::() ); }) }), } } } impl<'comp, ComponentT: Component> HandleFromEntityComponentRef<'comp> for Handle<'comp, ComponentT> { type Error = HandleError; fn from_entity_component_ref( entity_component_ref: Option>, _world: &'comp World, ) -> Result { let entity_comp = entity_component_ref.ok_or(HandleError::ComponentDoesNotExist)?; Ok(Self::new( entity_comp .component() .read_nonblock() .map_err(AcquireComponentLockFailed)?, )) } } impl<'comp, ComponentT> HandleFromEntityComponentRef<'comp> for Option> where ComponentT: Component, { type Error = HandleError; fn from_entity_component_ref( entity_component_ref: Option>, _world: &'comp World, ) -> Result { entity_component_ref .map(|entity_comp| { Ok(Handle::new( entity_comp .component() .read_nonblock() .map_err(AcquireComponentLockFailed)?, )) }) .transpose() } } impl 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>) -> Self { Self { inner: inner.map(|component| { component.downcast_mut::().unwrap_or_else(|| { panic!( "Failed to downcast component to type {}", type_name::() ); }) }), } } } impl<'comp, ComponentT: Component> HandleFromEntityComponentRef<'comp> for HandleMut<'comp, ComponentT> { type Error = HandleError; fn from_entity_component_ref( entity_component_ref: Option>, _world: &'comp World, ) -> Result { let entity_comp = entity_component_ref.ok_or(HandleError::ComponentDoesNotExist)?; Ok(Self::new( entity_comp .component() .write_nonblock() .map_err(AcquireComponentLockFailed)?, )) } } impl<'comp, ComponentT> HandleFromEntityComponentRef<'comp> for Option> where ComponentT: Component, { type Error = HandleError; fn from_entity_component_ref( entity_component_ref: Option>, _world: &'comp World, ) -> Result { entity_component_ref .map(|entity_comp| { Ok(HandleMut::new( entity_comp .component() .write_nonblock() .map_err(AcquireComponentLockFailed)?, )) }) .transpose() } } impl Deref for HandleMut<'_, ComponentT> { type Target = ComponentT; fn deref(&self) -> &Self::Target { &self.inner } } impl DerefMut for HandleMut<'_, ComponentT> { fn deref_mut(&mut self) -> &mut Self::Target { &mut self.inner } } #[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 { impl<#(IntoComp~I,)*> Sequence for (#(IntoComp~I,)*) where #( for<'comp> IntoComp~I: Into, )* { const COUNT: usize = $c + 1; type Array = [(Uid, Box); $c + 1]; fn into_array(self) -> Self::Array { [#({ let (id, component) = self.I.into_component(); (id, Box::new(component)) },)*] } fn metadata() -> impl Array { [ #( Metadata { id: IntoComp~I::Component::id(), is_optional: IntoComp~I::Component::is_optional(), }, )* ] } fn added_event_ids() -> Vec { vec![ #(ComponentAddedEvent::::id(),)* ] } fn removed_event_ids() -> Vec { vec![ #(ComponentRemovedEvent::::id(),)* ] } } }); }; } seq!(C in 0..=16 { inner!(C); }); impl Sequence for () { type Array = [(Uid, Box); 0]; const COUNT: usize = 0; fn into_array(self) -> Self::Array { [] } fn metadata() -> impl Array { [] } fn added_event_ids() -> Vec { Vec::new() } fn removed_event_ids() -> Vec { Vec::new() } } pub trait Into { type Component; fn into_component(self) -> (Uid, Self::Component); } impl Into for ComponentT where ComponentT: Component, { type Component = Self; fn into_component(self) -> (Uid, Self::Component) { (Self::id(), self) } }