From caef866b4e3f87fd6ae2dd5b979a1fe1a1f3e5f2 Mon Sep 17 00:00:00 2001 From: HampusM Date: Sun, 3 Nov 2024 21:12:57 +0100 Subject: feat(ecs): add read-only query iterating --- ecs/src/component.rs | 91 +++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 69 insertions(+), 22 deletions(-) (limited to 'ecs/src/component.rs') 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>; type RefMut<'component> = Option>; 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; + fn from_components_mut<'component>( + components: impl Iterator, + world: &'component World, + lock_component: fn( + entity_component: &EntityComponent, + ) -> WriteGuard<'_, Box>, + ) -> Self::MutRefs<'component>; + fn from_components<'component>( components: impl Iterator, world: &'component World, + lock_component: fn( + entity_component: &EntityComponent, + ) -> ReadGuard<'_, Box>, ) -> Self::Refs<'component>; } @@ -200,10 +220,18 @@ pub fn is_optional() -> bool false } +pub trait FromOptionalMut<'comp> +{ + fn from_optional_mut_component( + optional_component: Option>>, + world: &'comp World, + ) -> Self; +} + pub trait FromOptional<'comp> { fn from_optional_component( - optional_component: Option>>, + optional_component: Option>>, 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> @@ -235,13 +267,43 @@ macro_rules! inner { ] } + fn from_components_mut<'component>( + components: impl Iterator, + world: &'component World, + lock_component: fn( + entity_component: &EntityComponent, + ) -> WriteGuard<'_, Box>, + ) -> Self::MutRefs<'component> + { + #( + let mut comp_~I: Option>> = None; + )* + + for comp in components { + #( + if comp.id == Id::of::() { + comp_~I = Some(lock_component(comp)); + continue; + } + )* + } + + (#( + Comp~I::RefMut::from_optional_mut_component(comp_~I, world), + )*) + } + fn from_components<'component>( components: impl Iterator, world: &'component World, + lock_component: fn( + entity_component: &EntityComponent, + ) -> ReadGuard<'_, Box>, ) -> Self::Refs<'component> { + #( - let mut comp_~I: Option>> = None; + let mut comp_~I: Option>> = 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> -{ - entity_component - .component - .write_nonblock() - .unwrap_or_else(|_| { - panic!( - "Failed to acquire read-write lock to component {}", - entity_component.name - ); - }) -} -- cgit v1.2.3-18-g5258