diff options
Diffstat (limited to 'ecs/src/component.rs')
-rw-r--r-- | ecs/src/component.rs | 143 |
1 files changed, 74 insertions, 69 deletions
diff --git a/ecs/src/component.rs b/ecs/src/component.rs index 1abb23c..4d37cb8 100644 --- a/ecs/src/component.rs +++ b/ecs/src/component.rs @@ -8,7 +8,7 @@ use crate::event::component::{ Kind as ComponentEventKind, Removed as ComponentRemovedEvent, }; -use crate::lock::{ReadGuard, WriteGuard}; +use crate::lock::{Error as LockError, Lock, ReadGuard, WriteGuard}; use crate::system::{ComponentRef, ComponentRefMut, Input as SystemInput}; use crate::type_name::TypeName; use crate::uid::Uid; @@ -26,11 +26,11 @@ pub trait Component: SystemInput + Any + TypeName where Self: Sized; - type RefMut<'component>: FromOptionalMut<'component> + type RefMut<'component>: FromOptionalMut<'component> + FromLockedOptional<'component> where Self: Sized; - type Ref<'component>: FromOptional<'component> + type Ref<'component>: FromOptional<'component> + FromLockedOptional<'component> where Self: Sized; @@ -163,14 +163,6 @@ impl<ComponentT> SystemInput for Option<ComponentT> where ComponentT: Component /// A sequence of components. pub trait Sequence { - type MutRefs<'component> - where - Self: 'component; - - type Refs<'component> - where - Self: 'component; - /// The number of components in this component sequence. const COUNT: usize; @@ -181,20 +173,43 @@ pub trait Sequence fn added_event_ids() -> Vec<Uid>; fn removed_event_ids() -> Vec<Uid>; +} - fn from_components_mut<'component>( - components: &'component [EntityComponent], - component_index_lookup: impl Fn(Uid) -> Option<usize>, - world: &'component World, - lock_component: fn(&EntityComponent) -> WriteGuard<'_, Box<dyn Component>>, - ) -> Self::MutRefs<'component>; +/// A sequence of references (immutable or mutable) to components. +pub trait RefSequence +{ + type Handles<'component>; + + fn metadata() -> impl Array<Metadata>; fn from_components<'component>( components: &'component [EntityComponent], component_index_lookup: impl Fn(Uid) -> Option<usize>, world: &'component World, - lock_component: fn(&EntityComponent) -> ReadGuard<'_, Box<dyn Component>>, - ) -> Self::Refs<'component>; + ) -> Self::Handles<'component>; +} + +/// 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::Ref<'component>; +} + +impl<ComponentT> Ref for &mut ComponentT +where + ComponentT: Component, +{ + type Component = ComponentT; + type Handle<'component> = ComponentT::RefMut<'component>; } /// [`Component`] metadata. @@ -261,6 +276,14 @@ pub trait FromOptional<'comp> ) -> Self; } +pub trait FromLockedOptional<'comp>: Sized +{ + fn from_locked_optional_component( + optional_component: Option<&'comp Lock<Box<dyn Component>>>, + world: &'comp World, + ) -> Result<Self, LockError>; +} + macro_rules! inner { ($c: tt) => { seq!(I in 0..=$c { @@ -269,12 +292,6 @@ macro_rules! inner { #(for<'comp> Comp~I::RefMut<'comp>: FromOptionalMut<'comp>,)* #(for<'comp> Comp~I::Ref<'comp>: FromOptional<'comp>,)* { - type MutRefs<'component> = (#(Comp~I::RefMut<'component>,)*) - where Self: 'component; - - type Refs<'component> = (#(Comp~I::Ref<'component>,)*) - where Self: 'component; - const COUNT: usize = $c + 1; fn into_vec(self) -> Vec<Box<dyn Component>> @@ -307,46 +324,40 @@ macro_rules! inner { #(ComponentRemovedEvent::<Comp~I>::id(),)* ] } + } - #[inline] - fn from_components_mut<'component>( - components: &'component [EntityComponent], - component_index_lookup: impl Fn(Uid) -> Option<usize>, - world: &'component World, - lock_component: - fn(&EntityComponent) -> WriteGuard<'_, Box<dyn Component>>, - ) -> Self::MutRefs<'component> + impl<#(CompRef~I: Ref,)*> RefSequence for (#(CompRef~I,)*) + { + type Handles<'component> = (#(CompRef~I::Handle<'component>,)*); + + fn metadata() -> impl Array<Metadata> { - (#( - Comp~I::RefMut::from_optional_mut_component( - component_index_lookup(Comp~I::Component::id()) - .and_then(|component_index| { - components.get(component_index) - .map(lock_component) - }), - world - ), - )*) + [#( + Metadata { + id: CompRef~I::Component::id(), + is_optional: CompRef~I::Component::is_optional(), + }, + )*] } - #[inline] fn from_components<'component>( components: &'component [EntityComponent], component_index_lookup: impl Fn(Uid) -> Option<usize>, world: &'component World, - lock_component: - fn(&EntityComponent) -> ReadGuard<'_, Box<dyn Component>>, - ) -> Self::Refs<'component> + ) -> Self::Handles<'component> { (#( - Comp~I::Ref::from_optional_component( - component_index_lookup(Comp~I::Component::id()) - .and_then(|component_index| { - components.get(component_index) - .map(lock_component) - }), - world - ), + CompRef~I::Handle::from_locked_optional_component( + component_index_lookup(CompRef~I::Component::id()) + .and_then(|component_index| components.get(component_index)) + .map(|component| &component.component), + world, + ).unwrap_or_else(|err| { + panic!( + "Taking component {} lock failed: {err}", + type_name::<CompRef~I::Component>() + ); + }), )*) } } @@ -360,9 +371,6 @@ seq!(C in 0..=16 { impl Sequence for () { - type MutRefs<'component> = (); - type Refs<'component> = (); - const COUNT: usize = 0; fn into_vec(self) -> Vec<Box<dyn Component>> @@ -384,25 +392,22 @@ impl Sequence for () { Vec::new() } +} - #[inline] - fn from_components_mut<'component>( - _components: &'component [EntityComponent], - _component_index_lookup: impl Fn(Uid) -> Option<usize>, - _world: &'component World, - _lock_component: fn(&EntityComponent) -> WriteGuard<'_, Box<dyn Component>>, - ) -> Self::MutRefs<'component> +impl RefSequence for () +{ + type Handles<'component> = (); + + fn metadata() -> impl Array<Metadata> { - () + [] } - #[inline] fn from_components<'component>( _components: &'component [EntityComponent], _component_index_lookup: impl Fn(Uid) -> Option<usize>, _world: &'component World, - _lock_component: fn(&EntityComponent) -> ReadGuard<'_, Box<dyn Component>>, - ) -> Self::Refs<'component> + ) -> Self::Handles<'component> { () } |