diff options
author | HampusM <hampus@hampusmat.com> | 2024-11-03 21:12:57 +0100 |
---|---|---|
committer | HampusM <hampus@hampusmat.com> | 2024-11-03 21:12:57 +0100 |
commit | caef866b4e3f87fd6ae2dd5b979a1fe1a1f3e5f2 (patch) | |
tree | fa390998ff41b11bb0e60298a81f45619fbe4d69 /ecs/src/component.rs | |
parent | 373a0d53f31b838b3f650a37df39176a31a6c1c4 (diff) |
feat(ecs): add read-only query iterating
Diffstat (limited to 'ecs/src/component.rs')
-rw-r--r-- | ecs/src/component.rs | 91 |
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 - ); - }) -} |