summaryrefslogtreecommitdiff
path: root/ecs/src/component.rs
diff options
context:
space:
mode:
authorHampusM <hampus@hampusmat.com>2024-11-03 21:12:57 +0100
committerHampusM <hampus@hampusmat.com>2024-11-03 21:12:57 +0100
commitcaef866b4e3f87fd6ae2dd5b979a1fe1a1f3e5f2 (patch)
treefa390998ff41b11bb0e60298a81f45619fbe4d69 /ecs/src/component.rs
parent373a0d53f31b838b3f650a37df39176a31a6c1c4 (diff)
feat(ecs): add read-only query iterating
Diffstat (limited to 'ecs/src/component.rs')
-rw-r--r--ecs/src/component.rs91
1 files changed, 69 insertions, 22 deletions
diff --git a/ecs/src/component.rs b/ecs/src/component.rs
index 5b1e7f5..0506346 100644
--- a/ecs/src/component.rs
+++ b/ecs/src/component.rs
@@ -3,8 +3,8 @@ use std::fmt::Debug;
use seq_macro::seq;
-use crate::lock::WriteGuard;
-use crate::system::{ComponentRefMut, Input as SystemInput};
+use crate::lock::{ReadGuard, WriteGuard};
+use crate::system::{ComponentRef, ComponentRefMut, Input as SystemInput};
use crate::type_name::TypeName;
use crate::{EntityComponent, World};
@@ -23,6 +23,10 @@ pub trait Component: SystemInput + Any + TypeName
where
Self: Sized;
+ type Ref<'component>
+ where
+ Self: Sized;
+
/// Returns the ID of this component's type.
fn id(&self) -> Id;
@@ -77,6 +81,7 @@ where
ComponentT: Component,
{
type Component = ComponentT;
+ type Ref<'component> = Option<ComponentRef<'component, ComponentT>>;
type RefMut<'component> = Option<ComponentRefMut<'component, ComponentT>>;
fn id(&self) -> Id
@@ -133,6 +138,10 @@ impl Id
/// A sequence of components.
pub trait Sequence
{
+ type MutRefs<'component>
+ where
+ Self: 'component;
+
type Refs<'component>
where
Self: 'component;
@@ -141,9 +150,20 @@ pub trait Sequence
fn metadata() -> Vec<Metadata>;
+ fn from_components_mut<'component>(
+ components: impl Iterator<Item = &'component EntityComponent>,
+ world: &'component World,
+ lock_component: fn(
+ entity_component: &EntityComponent,
+ ) -> WriteGuard<'_, Box<dyn Component>>,
+ ) -> Self::MutRefs<'component>;
+
fn from_components<'component>(
components: impl Iterator<Item = &'component EntityComponent>,
world: &'component World,
+ lock_component: fn(
+ entity_component: &EntityComponent,
+ ) -> ReadGuard<'_, Box<dyn Component>>,
) -> Self::Refs<'component>;
}
@@ -200,10 +220,18 @@ pub fn is_optional<ComponentT: Component>() -> bool
false
}
+pub trait FromOptionalMut<'comp>
+{
+ fn from_optional_mut_component(
+ optional_component: Option<WriteGuard<'comp, Box<dyn Component>>>,
+ world: &'comp World,
+ ) -> Self;
+}
+
pub trait FromOptional<'comp>
{
fn from_optional_component(
- optional_component: Option<WriteGuard<'comp, Box<dyn Component>>>,
+ optional_component: Option<ReadGuard<'comp, Box<dyn Component>>>,
world: &'comp World,
) -> Self;
}
@@ -213,9 +241,13 @@ macro_rules! inner {
seq!(I in 0..=$c {
impl<#(Comp~I: Component,)*> Sequence for (#(Comp~I,)*)
where
- #(for<'comp> Comp~I::RefMut<'comp>: FromOptional<'comp>,)*
+ #(for<'comp> Comp~I::RefMut<'comp>: FromOptionalMut<'comp>,)*
+ #(for<'comp> Comp~I::Ref<'comp>: FromOptional<'comp>,)*
{
- type Refs<'component> = (#(Comp~I::RefMut<'component>,)*)
+ type MutRefs<'component> = (#(Comp~I::RefMut<'component>,)*)
+ where Self: 'component;
+
+ type Refs<'component> = (#(Comp~I::Ref<'component>,)*)
where Self: 'component;
fn into_vec(self) -> Vec<Box<dyn Component>>
@@ -235,13 +267,43 @@ macro_rules! inner {
]
}
+ fn from_components_mut<'component>(
+ components: impl Iterator<Item = &'component EntityComponent>,
+ world: &'component World,
+ lock_component: fn(
+ entity_component: &EntityComponent,
+ ) -> WriteGuard<'_, Box<dyn Component>>,
+ ) -> Self::MutRefs<'component>
+ {
+ #(
+ let mut comp_~I: Option<WriteGuard<Box<dyn Component>>> = None;
+ )*
+
+ for comp in components {
+ #(
+ if comp.id == Id::of::<Comp~I::Component>() {
+ comp_~I = Some(lock_component(comp));
+ continue;
+ }
+ )*
+ }
+
+ (#(
+ Comp~I::RefMut::from_optional_mut_component(comp_~I, world),
+ )*)
+ }
+
fn from_components<'component>(
components: impl Iterator<Item = &'component EntityComponent>,
world: &'component World,
+ lock_component: fn(
+ entity_component: &EntityComponent,
+ ) -> ReadGuard<'_, Box<dyn Component>>,
) -> Self::Refs<'component>
{
+
#(
- let mut comp_~I: Option<WriteGuard<Box<dyn Component>>> = None;
+ let mut comp_~I: Option<ReadGuard<Box<dyn Component>>> = None;
)*
for comp in components {
@@ -254,7 +316,7 @@ macro_rules! inner {
}
(#(
- Comp~I::RefMut::from_optional_component(comp_~I, world),
+ Comp~I::Ref::from_optional_component(comp_~I, world),
)*)
}
}
@@ -265,18 +327,3 @@ macro_rules! inner {
seq!(C in 0..=64 {
inner!(C);
});
-
-fn lock_component(
- entity_component: &EntityComponent,
-) -> WriteGuard<'_, Box<dyn Component>>
-{
- entity_component
- .component
- .write_nonblock()
- .unwrap_or_else(|_| {
- panic!(
- "Failed to acquire read-write lock to component {}",
- entity_component.name
- );
- })
-}