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.rs143
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>
{
()
}