diff --git a/ecs/src/updates.rs b/ecs/src/updates.rs index cf827b6..985f76f 100644 --- a/ecs/src/updates.rs +++ b/ecs/src/updates.rs @@ -7,871 +7,10 @@ use std::collections::HashMap; use anyhow::Result; use indexmap::IndexMap; +use update_macros::implement_updates; use crate::resources::Resource as ResourceTrait; use crate::*; -use update_macros::{implement_pair_update, implement_single_update}; - -macro_rules! impl_singleton_update { - // single without resources - ( $s:ident, ) => { - impl CreateArchetype<$s, (), Func, Filter> for Archetype - where - Func: Fn(&mut Commands, Query<&mut $s, Filter>) -> Result<()> + Send + Sync + Clone + 'static, - Filter: CheckFilter + 'static, - $s: EntityComponent + ComponentDebug, - { - paste::item! { - fn create(f: Func) -> Self { - Filter::verify_dedup::<$s>(); - - Self { - check_entity: Box::new({ - move |entity| { - if !entity.components.contains::<$s>() { - return false; - } - - if !Filter::check(entity) { - return false; - } - - true - } - }), - - create_callback: Box::new(move |entity| { - let [< $s:lower >] = UnsafeComponentStore::from( - entity.get_component::<$s>()? - ); - - let e = entity.as_entity(); - let f = f.clone(); - - Ok(Box::new(move |commands, _world| { - let query = Query { - entity: e, - c: unsafe { [< $s:lower >].as_mut() }, - filter: PhantomData, - }; - - f(commands, query) - })) - }), - - entities: IndexMap::new(), - } - } - } - } - - impl AddUpdates<$s, (), Func, Filter> for Updates - where - $s: EntityComponent + ComponentDebug, - Func: Fn(&mut Commands, Query<&mut $s, Filter>) -> Result<()> + Send + Sync + Clone + 'static, - Filter: CheckFilter + 'static - { - fn add_update( - &mut self, - name: &str, - priority: u32, - func: Func, - ) -> Result<()> { - paste::item! { - self.add(name, priority, Update::Single(Archetype::create(func))) - } - } - } - - impl AddUpdates<$s, (), Func, Filter> for WorldBuilder - where - $s: EntityComponent + ComponentDebug, - Func: Fn(&mut Commands, Query<&mut $s, Filter>) -> Result<()> + Send + Sync + Clone + 'static, - Filter: CheckFilter + 'static - { - fn add_update( - &mut self, - name: &str, - priority: u32, - func: Func, - ) -> Result<()> { - self.updates.add_update(name, priority, func) - } - } - }; - // single with resources - ( $s:ident, [$($res:ident $(,)?)+] ) => { - impl CreateArchetype<$s, ( $( $res, )+ ), Func, Filter> for Archetype - where - Func: Fn(&mut Commands, Query<&mut $s, Filter>, $(&mut $res,)+) -> Result<()> + Send + Sync + Clone + 'static, - Filter: CheckFilter + 'static, - $s: EntityComponent + ComponentDebug, - $( - $res: ResourceTrait, - )+ - { - paste::item! { - fn create(f: Func) -> Self { - Filter::verify_dedup::<$s>(); - - Self { - check_entity: Box::new({ - move |entity| { - if !entity.components.contains::<$s>() { - return false; - } - - if !Filter::check(entity) { - return false; - } - - true - } - }), - - create_callback: Box::new(move |entity| { - let [< $s:lower >] = UnsafeComponentStore::from( - entity.get_component::<$s>()? - ); - - let e = entity.as_entity(); - let f = f.clone(); - - Ok(Box::new(move |commands, world| { - let ( - $( - [< $res:lower _var >], - )+ - ): ( - $( - &mut $res, - )+ - ) = world.resources.get_mut()?; - - let query = Query { - entity: e, - c: unsafe { [< $s:lower >].as_mut() }, - filter: PhantomData, - }; - - f(commands, query, $([< $res:lower _var >],)+) - })) - }), - - entities: IndexMap::new(), - } - } - } - } - - impl AddUpdates<$s, ( $( $res, )+ ), Func, Filter> for Updates - where - $s: EntityComponent + ComponentDebug, - $( - $res: ResourceTrait, - )+ - Func: Fn(& mut Commands, Query<&mut $s, Filter>, $(&mut $res,)+) -> Result<()> + Send + Sync + Clone + 'static, - Filter: CheckFilter + 'static - { - fn add_update( - &mut self, - name: &str, - priority: u32, - func: Func, - ) -> Result<()> { - paste::item! { - self.add(name, priority, Update::Single(Archetype::create(func))) - } - } - } - - impl AddUpdates<$s, ( $( $res, )+ ), Func, Filter> for WorldBuilder - where - $s: EntityComponent + ComponentDebug, - $( - $res: ResourceTrait, - )+ - Func: Fn(& mut Commands, Query<&mut $s, Filter>, $(&mut $res,)+) -> Result<()> + Send + Sync + Clone + 'static, - Filter: CheckFilter + 'static - { - fn add_update( - &mut self, - name: &str, - priority: u32, - func: Func, - ) -> Result<()> { - self.updates.add_update(name, priority, func) - } - } - }; - // without resources - ( $s:ident, $($var:ident $(,)?)+ ) => { - impl CreateArchetype<( $s, $( $var, )+ ), (), Func, Filter> for Archetype - where - Func: Fn(&mut Commands, Query<( &mut $s, $( &mut $var, )+ ), Filter>) -> Result<()> + Send + Sync + Clone + 'static, - Filter: CheckFilter + 'static, - $s: EntityComponent + ComponentDebug, - $( - $var: EntityComponent + ComponentDebug, - )+ - { - paste::item! { - fn create(f: Func) -> Self { - Filter::verify_dedup::<$s>(); - $( - Filter::verify_dedup::<$var>(); - )+ - - Self { - check_entity: Box::new({ - move |entity| { - if !entity.components.contains::<$s>() { - return false; - } - - $( - if !entity.components.contains::<$var>() { - return false; - } - )+ - - if !Filter::check(entity) { - return false; - } - - true - } - }), - - create_callback: Box::new(move |entity| { - let [< $s:lower >] = UnsafeComponentStore::from( - entity.get_component::<$s>()? - ); - - $( - let [< $var:lower >] = UnsafeComponentStore::from( - entity.get_component::<$var>()? - ); - )+ - - let e = entity.as_entity(); - let f = f.clone(); - - Ok(Box::new(move |commands, _world| { - let query = Query { - entity: e, - c: unsafe { ( [< $s:lower >].as_mut(), $([< $var:lower >].as_mut(),)+) }, - filter: PhantomData, - }; - - f(commands, query) - })) - }), - - entities: IndexMap::new(), - } - } - } - } - - impl AddUpdates<( $s, $( $var, )+ ), (), Func, Filter> for Updates - where - $s: EntityComponent + ComponentDebug, - $( - $var: EntityComponent + ComponentDebug, - )+ - Func: Fn(&mut Commands, Query<( &mut $s, $( &mut $var, )+ ), Filter>) -> Result<()> + Send + Sync + Clone + 'static, - Filter: CheckFilter + 'static - { - fn add_update( - &mut self, - name: &str, - priority: u32, - func: Func, - ) -> Result<()> { - paste::item! { - self.add(name, priority, Update::Single(Archetype::create(func))) - } - } - } - - impl AddUpdates<( $s, $( $var, )+ ), (), Func, Filter> for WorldBuilder - where - $s: EntityComponent + ComponentDebug, - $( - $var: EntityComponent + ComponentDebug, - )+ - Func: Fn(&mut Commands, Query<( &mut $s, $( &mut $var, )+ ), Filter>) -> Result<()> + Send + Sync + Clone + 'static, - Filter: CheckFilter + 'static - { - fn add_update( - &mut self, - name: &str, - priority: u32, - func: Func, - ) -> Result<()> { - self.updates.add_update(name, priority, func) - } - } - }; - // with resources - ( $s:ident, $($var:ident $(,)?)+ [$($res:ident $(,)?)+] ) => { - impl CreateArchetype<( $s, $( $var, )+ ), ( $( $res, )+ ), Func, Filter> for Archetype - where - Func: Fn(&mut Commands, Query<( &mut $s, $( &mut $var, )+ ), Filter>, $(&mut $res,)+) -> Result<()> + Send + Sync + Clone + 'static, - Filter: CheckFilter + 'static, - $s: EntityComponent + ComponentDebug, - $( - $var: EntityComponent + ComponentDebug, - )+ - $( - $res: ResourceTrait, - )+ - { - paste::item! { - fn create(f: Func) -> Self { - Filter::verify_dedup::<$s>(); - $( - Filter::verify_dedup::<$var>(); - )+ - - Self { - check_entity: Box::new({ - move |entity| { - if !entity.components.contains::<$s>() { - return false; - } - - $( - if !entity.components.contains::<$var>() { - return false; - } - )+ - - if !Filter::check(entity) { - return false; - } - - true - } - }), - - create_callback: Box::new(move |entity| { - let [< $s:lower >] = UnsafeComponentStore::from( - entity.get_component::<$s>()? - ); - - $( - let [< $var:lower >] = UnsafeComponentStore::from( - entity.get_component::<$var>()? - ); - )+ - - let e = entity.as_entity(); - let f = f.clone(); - - Ok(Box::new(move |commands, world| { - let ( - $( - [< $res:lower _var >], - )+ - ): ( - $( - &mut $res, - )+ - ) = world.resources.get_mut()?; - - let query = Query { - entity: e, - c: unsafe { ( [< $s:lower >].as_mut(), $([< $var:lower >].as_mut(),)+ ) }, - filter: PhantomData, - }; - - f(commands, query, $([< $res:lower _var >],)+) - })) - }), - - entities: IndexMap::new(), - } - } - } - } - - impl AddUpdates<( $s, $( $var, )+ ), ( $( $res, )+ ), Func, Filter> for Updates - where - $s: EntityComponent + ComponentDebug, - $( - $var: EntityComponent + ComponentDebug, - )+ - $( - $res: ResourceTrait, - )+ - Func: Fn(&mut Commands, Query<( &mut $s, $( &mut $var, )+ ), Filter>, $(&mut $res,)+) -> Result<()> + Send + Sync + Clone + 'static, - Filter: CheckFilter + 'static - { - fn add_update( - &mut self, - name: &str, - priority: u32, - func: Func, - ) -> Result<()> { - paste::item! { - self.add(name, priority, Update::Single(Archetype::create(func))) - } - } - } - - impl AddUpdates<( $s, $( $var, )+ ), ( $( $res, )+ ), Func, Filter> for WorldBuilder - where - $s: EntityComponent + ComponentDebug, - $( - $var: EntityComponent + ComponentDebug, - )+ - $( - $res: ResourceTrait, - )+ - Func: Fn(&mut Commands, Query<( &mut $s, $( &mut $var, )+ ), Filter>, $(&mut $res,)+) -> Result<()> + Send + Sync + Clone + 'static, - Filter: CheckFilter + 'static - { - fn add_update( - &mut self, - name: &str, - priority: u32, - func: Func, - ) -> Result<()> { - self.updates.add_update(name, priority, func) - } - } - }; -} - -macro_rules! impl_pair_update { - // lhs single - ( - $lhs_id: expr, - ( [$lhs_little: ident: $lhs_big: ident]$(,)? ), - $rhs_id: expr, - ( $([$rhs_little: ident: $rhs_big: ident]$(,)?)+ ) - ) => { - impl ArchetypePair { - paste::item! { - pub fn [] - (f: F) -> Self - where - F: Fn(&mut Commands, Query<&mut $lhs_big, LeftFilter>, Query<( $( &mut $rhs_big, )+ ), RightFilter>) -> Result<()> + Send + Sync + Clone + 'static, - LeftFilter: CheckFilter + 'static, - RightFilter: CheckFilter + 'static, - $( - $rhs_big: EntityComponent + ComponentDebug, - )+ - $lhs_big: EntityComponent + ComponentDebug, - { - LeftFilter::verify_dedup::<$lhs_big>(); - - $( - RightFilter::verify_dedup::<$rhs_big>(); - )+ - - Self { - check_left_entity: Box::new({ - move |entity| { - if !entity.components.contains::<$lhs_big>() { - return false; - } - - if !LeftFilter::check(entity) { - return false; - } - - true - } - }), - check_right_entity: Box::new({ - move |entity| { - $( - if !entity.components.contains::<$rhs_big>() { - return false; - } - )+ - - if !RightFilter::check(entity) { - return false; - } - - true - } - }), - - create_callback: Box::new(move |lhs_entity, rhs_entity| { - let $lhs_little = UnsafeComponentStore::from( - lhs_entity.get_component::<$lhs_big>()? - ); - - $( - let $rhs_little = UnsafeComponentStore::from( - rhs_entity.get_component::<$rhs_big>()? - ); - )+ - - let lhs_e = lhs_entity.as_entity(); - let rhs_e = rhs_entity.as_entity(); - let f = f.clone(); - - Ok(Box::new(move |commands| { - let lhs_query = Query { - entity: lhs_e, - c: unsafe { $lhs_little.as_mut() }, - filter: PhantomData, - }; - - let rhs_query = Query { - entity: rhs_e, - c: unsafe { ($($rhs_little.as_mut(),)+) }, - filter: PhantomData, - }; - - f(commands, lhs_query, rhs_query ) - })) - }), - - entities: IndexMap::new(), - } - } - } - } - - impl AddUpdates<( $lhs_big, ($($rhs_big,)+) ), (), Func, (LhsFilter, RhsFilter)> for Updates - where - $( - $rhs_big: EntityComponent + ComponentDebug, - )+ - $lhs_big: EntityComponent + ComponentDebug, - Func: Fn(&mut Commands, Query<&mut $lhs_big, LhsFilter>, Query<( $( &mut $rhs_big, )+ ), RhsFilter>) -> Result<()> + Send + Sync + Clone + 'static, - LhsFilter: CheckFilter + 'static, - RhsFilter: CheckFilter + 'static - { - fn add_update( - &mut self, - name: &str, - priority: u32, - func: Func, - ) -> Result<()> { - paste::item! { - self.add(name, priority, Update::Pair(ArchetypePair::[](func)))?; - } - - Ok(()) - } - } - - impl AddUpdates<( $lhs_big, ($($rhs_big,)+) ), (), Func, (LhsFilter, RhsFilter)> for WorldBuilder - where - $( - $rhs_big: EntityComponent + ComponentDebug, - )+ - $lhs_big: EntityComponent + ComponentDebug, - Func: Fn(&mut Commands, Query<&mut $lhs_big, LhsFilter>, Query<( $( &mut $rhs_big, )+ ), RhsFilter>) -> Result<()> + Send + Sync + Clone + 'static, - LhsFilter: CheckFilter + 'static, - RhsFilter: CheckFilter + 'static - { - fn add_update( - &mut self, - name: &str, - priority: u32, - func: Func, - ) -> Result<()> { - self.updates.add_update(name, priority, func) - } - } - }; - // rhs_single - ( - $lhs_id: expr, - ( $([$lhs_little: ident: $lhs_big: ident]$(,)?)+ ), - $rhs_id: expr, - ( [$rhs_little: ident: $rhs_big: ident]$(,)? ) - ) => { - impl ArchetypePair { - paste::item! { - pub fn [] - (f: F) -> Self - where - F: Fn(&mut Commands, Query<( $( &mut $lhs_big, )+ ), LeftFilter>, Query<&mut $rhs_big, RightFilter>) -> Result<()> + Send + Sync + Clone + 'static, - LeftFilter: CheckFilter + 'static, - RightFilter: CheckFilter + 'static, - $rhs_big: EntityComponent + ComponentDebug, - $( - $lhs_big: EntityComponent + ComponentDebug, - )+ - { - $( - LeftFilter::verify_dedup::<$lhs_big>(); - )+ - - RightFilter::verify_dedup::<$rhs_big>(); - - Self { - check_left_entity: Box::new({ - move |entity| { - $( - if !entity.components.contains::<$lhs_big>() { - return false; - } - )+ - - if !LeftFilter::check(entity) { - return false; - } - - true - } - }), - check_right_entity: Box::new({ - move |entity| { - if !entity.components.contains::<$rhs_big>() { - return false; - } - - if !RightFilter::check(entity) { - return false; - } - - true - } - }), - - create_callback: Box::new(move |lhs_entity, rhs_entity| { - $( - let $lhs_little = UnsafeComponentStore::from( - lhs_entity.get_component::<$lhs_big>()? - ); - )+ - - let $rhs_little = UnsafeComponentStore::from( - rhs_entity.get_component::<$rhs_big>()? - ); - - let lhs_e = lhs_entity.as_entity(); - let rhs_e = rhs_entity.as_entity(); - let f = f.clone(); - - Ok(Box::new(move |commands| { - let lhs_query = Query { - entity: lhs_e, - c: unsafe { ($($lhs_little.as_mut(),)+) }, - filter: PhantomData, - }; - - let rhs_query = Query { - entity: rhs_e, - c: unsafe { $rhs_little.as_mut() }, - filter: PhantomData, - }; - - f(commands, lhs_query, rhs_query ) - })) - }), - - entities: IndexMap::new(), - } - } - } - } - - impl AddUpdates<( ($( $lhs_big, )+), $rhs_big ), (), Func, (LhsFilter, RhsFilter)> for Updates - where - $rhs_big: EntityComponent + ComponentDebug, - $( - $lhs_big: EntityComponent + ComponentDebug, - )+ - Func: Fn(&mut Commands, Query<( $( &mut $lhs_big, )+ ), LhsFilter>, Query<&mut $rhs_big, RhsFilter>) -> Result<()> + Send + Sync + Clone + 'static, - LhsFilter: CheckFilter + 'static, - RhsFilter: CheckFilter + 'static - { - fn add_update( - &mut self, - name: &str, - priority: u32, - func: Func, - ) -> Result<()> { - paste::item! { - self.add(name, priority, Update::Pair(ArchetypePair::[](func)))?; - } - - Ok(()) - } - } - - impl AddUpdates<( ($( $lhs_big, )+), $rhs_big ), (), Func, (LhsFilter, RhsFilter)> for WorldBuilder - where - $rhs_big: EntityComponent + ComponentDebug, - $( - $lhs_big: EntityComponent + ComponentDebug, - )+ - Func: Fn(&mut Commands, Query<( $( &mut $lhs_big, )+ ), LhsFilter>, Query<&mut $rhs_big, RhsFilter>) -> Result<()> + Send + Sync + Clone + 'static, - LhsFilter: CheckFilter + 'static, - RhsFilter: CheckFilter + 'static - { - fn add_update( - &mut self, - name: &str, - priority: u32, - func: Func, - ) -> Result<()> { - self.updates.add_update(name, priority, func) - } - } - }; - ( - $lhs_id: expr, - ( $([$lhs_little: ident: $lhs_big: ident]$(,)?)+ ), - $rhs_id: expr, - ( $([$rhs_little: ident: $rhs_big: ident]$(,)?)+ ) - ) => { - impl ArchetypePair { - paste::item! { - pub fn [] - (f: F) -> Self - where - F: Fn(&mut Commands, Query<( $( &mut $lhs_big, )+ ), LeftFilter>, Query<( $( &mut $rhs_big, )+ ), RightFilter>) -> Result<()> + Send + Sync + Clone + 'static, - LeftFilter: CheckFilter + 'static, - RightFilter: CheckFilter + 'static, - $( - $rhs_big: EntityComponent + ComponentDebug, - )+ - $( - $lhs_big: EntityComponent + ComponentDebug, - )+ - { - $( - LeftFilter::verify_dedup::<$lhs_big>(); - )+ - - $( - RightFilter::verify_dedup::<$rhs_big>(); - )+ - - Self { - check_left_entity: Box::new({ - move |entity| { - $( - if !entity.components.contains::<$lhs_big>() { - return false; - } - )+ - - if !LeftFilter::check(entity) { - return false; - } - - true - } - }), - check_right_entity: Box::new({ - move |entity| { - $( - if !entity.components.contains::<$rhs_big>() { - return false; - } - )+ - - if !RightFilter::check(entity) { - return false; - } - - true - } - }), - - create_callback: Box::new(move |lhs_entity, rhs_entity| { - $( - let $lhs_little = UnsafeComponentStore::from( - lhs_entity.get_component::<$lhs_big>()? - ); - )+ - - $( - let $rhs_little = UnsafeComponentStore::from( - rhs_entity.get_component::<$rhs_big>()? - ); - )+ - - let lhs_e = lhs_entity.as_entity(); - let rhs_e = rhs_entity.as_entity(); - let f = f.clone(); - - Ok(Box::new(move |commands| { - let lhs_query = Query { - entity: lhs_e, - c: unsafe { ($($lhs_little.as_mut(),)+) }, - filter: PhantomData, - }; - - let rhs_query = Query { - entity: rhs_e, - c: unsafe { ($($rhs_little.as_mut(),)+) }, - filter: PhantomData, - }; - - f(commands, lhs_query, rhs_query ) - })) - }), - - entities: IndexMap::new(), - } - } - } - } - - impl AddUpdates<( ($( $lhs_big, )+), ($($rhs_big,)+) ), (), Func, (LhsFilter, RhsFilter)> for Updates - where - $( - $rhs_big: EntityComponent + ComponentDebug, - )+ - $( - $lhs_big: EntityComponent + ComponentDebug, - )+ - Func: Fn(&mut Commands, Query<( $( &mut $lhs_big, )+ ), LhsFilter>, Query<( $( &mut $rhs_big, )+ ), RhsFilter>) -> Result<()> + Send + Sync + Clone + 'static, - LhsFilter: CheckFilter + 'static, - RhsFilter: CheckFilter + 'static - { - fn add_update( - &mut self, - name: &str, - priority: u32, - func: Func, - ) -> Result<()> { - paste::item! { - self.add(name, priority, Update::Pair(ArchetypePair::[](func)))?; - } - - Ok(()) - } - } - - impl AddUpdates<( ($( $lhs_big, )+), ($($rhs_big,)+) ), (), Func, (LhsFilter, RhsFilter)> for WorldBuilder - where - $( - $rhs_big: EntityComponent + ComponentDebug, - )+ - $( - $lhs_big: EntityComponent + ComponentDebug, - )+ - Func: Fn(&mut Commands, Query<( $( &mut $lhs_big, )+ ), LhsFilter>, Query<( $( &mut $rhs_big, )+ ), RhsFilter>) -> Result<()> + Send + Sync + Clone + 'static, - LhsFilter: CheckFilter + 'static, - RhsFilter: CheckFilter + 'static - { - fn add_update( - &mut self, - name: &str, - priority: u32, - func: Func, - ) -> Result<()> { - self.updates.add_update(name, priority, func) - } - } - }; -} macro_rules! impl_update_filter { ( $name: ident, $([$big: ident, $little: ident]$(,)?)+ ) => { @@ -999,17 +138,18 @@ impl ArchetypeInfo { } pub struct Archetype { - check_entity: Box bool + Send + Sync>, + check_entity: Box bool + Send + Sync>, create_callback: Box< dyn Fn( - &EntityObject, + &[&EntityObject], ) -> Result Result<()> + Send + Sync>> + Send + Sync, >, - entities: IndexMap Result<()> + Send + Sync>>, + entities: + IndexMap, Box Result<()> + Send + Sync>>, } impl Archetype { @@ -1259,26 +399,25 @@ impl Archetypes { } } -implement_pair_update!(impl_pair_update, 1, 10); -implement_single_update!(impl_singleton_update, 1, 10); +implement_updates!(10, 4); -#[rustfmt::skip] -impl_update_filter!(Monuple, [R, r]); -#[rustfmt::skip] -impl_update_filter!(Couple, [R, r], [S, s]); -#[rustfmt::skip] -impl_update_filter!(Triple, [R, r], [S, s], [T, t]); -#[rustfmt::skip] -impl_update_filter!(Quadruple, [R, r], [S, s], [T, t], [U, u]); -#[rustfmt::skip] -impl_update_filter!(Quintuple, [R, r], [S, s], [T, t], [U, u], [V, v]); -#[rustfmt::skip] -impl_update_filter!(Sextuple, [R, r], [S, s], [T, t], [U, u], [V, v], [W, w]); -#[rustfmt::skip] -impl_update_filter!(Septuple, [R, r], [S, s], [T, t], [U, u], [V, v], [W, w], [X, x]); -#[rustfmt::skip] -impl_update_filter!(Octuple, [R, r], [S, s], [T, t], [U, u], [V, v], [W, w], [X, x], [Y, y]); -#[rustfmt::skip] -impl_update_filter!(Nonuple, [R, r], [S, s], [T, t], [U, u], [V, v], [W, w], [X, x], [Y, y], [Z, z]); -#[rustfmt::skip] -impl_update_filter!(Decuple, [R, r], [S, s], [T, t], [U, u], [V, v], [W, w], [X, x], [Y, y], [Z, z], [A, a]); +// #[rustfmt::skip] +// impl_update_filter!(Monuple, [R, r]); +// #[rustfmt::skip] +// impl_update_filter!(Couple, [R, r], [S, s]); +// #[rustfmt::skip] +// impl_update_filter!(Triple, [R, r], [S, s], [T, t]); +// #[rustfmt::skip] +// impl_update_filter!(Quadruple, [R, r], [S, s], [T, t], [U, u]); +// #[rustfmt::skip] +// impl_update_filter!(Quintuple, [R, r], [S, s], [T, t], [U, u], [V, v]); +// #[rustfmt::skip] +// impl_update_filter!(Sextuple, [R, r], [S, s], [T, t], [U, u], [V, v], [W, w]); +// #[rustfmt::skip] +// impl_update_filter!(Septuple, [R, r], [S, s], [T, t], [U, u], [V, v], [W, w], [X, x]); +// #[rustfmt::skip] +// impl_update_filter!(Octuple, [R, r], [S, s], [T, t], [U, u], [V, v], [W, w], [X, x], [Y, y]); +// #[rustfmt::skip] +// impl_update_filter!(Nonuple, [R, r], [S, s], [T, t], [U, u], [V, v], [W, w], [X, x], [Y, y], [Z, z]); +// #[rustfmt::skip] +// impl_update_filter!(Decuple, [R, r], [S, s], [T, t], [U, u], [V, v], [W, w], [X, x], [Y, y], [Z, z], [A, a]); diff --git a/update_macros/src/update.rs b/update_macros/src/update.rs index 950dce5..189c844 100644 --- a/update_macros/src/update.rs +++ b/update_macros/src/update.rs @@ -47,8 +47,8 @@ impl Query { let filter = &self.filter; quote! { - ( - let entity = &entites[#index]; + { + let entity = &entities[#index]; #( if !entity.components.contains::<#components>() { @@ -59,7 +59,7 @@ impl Query { if !#filter::check(entity) { return false; } - ) + } } } @@ -72,16 +72,16 @@ impl Query { .map(|component| format_ident!("q_{index}_{component}")) .collect::>(); let query_ident = format_ident!("query_{index}"); - let entity_ident = format_ident!("entity_{index}"); + let entity_ident = format_ident!("e_{index}"); ( quote! { let #entity_name = &entities[#index]; - let #entity_ident = entity_name.as_entity(); + let #entity_ident = #entity_name.as_entity(); #( let #component_name = UnsafeComponentStore::from( - entity.get_component::<#components>()? + #entity_name.get_component::<#components>()? ); )* }, @@ -136,6 +136,7 @@ struct Update { impl Update { const MIN_RESOURCE: usize = 0; + const MAX_RESOURCE: usize = 10; const MIN_COMPONENTS: usize = 1; const MIN_QUERIES: usize = 1; @@ -145,7 +146,7 @@ impl Update { .enumerate() .map(|(query, component_count)| { Query::new( - (1..component_count).map(|component| format_ident!("C{component}Q{query}")), + (0..component_count).map(|component| format_ident!("C{component}Q{query}")), query, ) }) @@ -176,6 +177,18 @@ impl Update { } } + pub fn filter_type_impls(&self) -> TokenStream2 { + let filter_types = self + .queries + .iter() + .map(|query| query.filter()) + .collect::>(); + + quote! { + #( #filter_types, )* + } + } + pub fn filter_requirements(&self) -> TokenStream2 { let filter_requirements = self .queries @@ -200,6 +213,19 @@ impl Update { } } + pub fn query_type_impls(&self) -> TokenStream2 { + let query_types = self + .queries + .iter() + .map(|query| query.components()) + .flatten() + .collect::>(); + + quote! { + #( #query_types, )* + } + } + pub fn component_requirements(&self) -> TokenStream2 { let component_requirements = self .queries @@ -215,10 +241,30 @@ impl Update { .collect::>(); quote! { - #( #component_requirements, )* + #( #component_requirements )* } } + pub fn resource_store(&self) -> (TokenStream2, Vec) { + let resource_types = &self.resources; + let resource_idents = self + .resources + .iter() + .map(|resource| format_ident!("res_{resource}")) + .collect::>(); + + ( + quote! { + let ( + #( #resource_idents, )* + ): ( + #( &mut #resource_types, )* + ) = world.resources.get_mut()?; + }, + resource_idents, + ) + } + pub fn resource_types(&self) -> TokenStream2 { let resource_types = &self.resources; @@ -227,6 +273,14 @@ impl Update { } } + pub fn resource_type_impls(&self) -> TokenStream2 { + let resource_types = &self.resources; + + quote! { + #( #resource_types, )* + } + } + pub fn reource_requirement(&self) -> TokenStream2 { let resource_types = &self.resources; @@ -240,8 +294,13 @@ impl ToTokens for Update { fn to_tokens(&self, tokens: &mut TokenStream2) { // generics to specify trait implementations let filter_types = self.filter_types(); + let filter_type_impls = self.filter_type_impls(); let query_types = self.query_types(); + let query_type_impls = self.query_type_impls(); let resource_types = self.resource_types(); + let resource_type_impls = self.resource_type_impls(); + + // panic!("{resource_type_impls}"); // function parameter let queries = &self.queries; @@ -273,15 +332,27 @@ impl ToTokens for Update { .map(|(index, query)| query.check_entity(index)) .collect::>(); - let component_stores = self + let component_stores_and_queries = self .queries .iter() .enumerate() .map(|(index, query)| query.component_store_and_query(index)) .collect::>(); + let mut component_stores = Vec::new(); + let mut query_structs = Vec::new(); + let mut query_idents = Vec::new(); + + for (component_store, query_struct, query_ident) in component_stores_and_queries { + component_stores.push(component_store); + query_structs.push(query_struct); + query_idents.push(query_ident); + } + + let (resource_store, resource_idents) = self.resource_store(); + TokenStream2::from(quote! { - impl CreateArchetype<#query_types, #resource_types, Func, #filter_types> for Archetype + impl CreateArchetype<#query_types, #resource_types, Func, #filter_types> for Archetype where Func: Fn(&mut Commands, #( #queries, )* #resources ) -> Result<()> + Send + Sync + Clone + 'static, #filter_requirements @@ -299,13 +370,15 @@ impl ToTokens for Update { }), create_callback: Box::new(move |entities| { - let e = entity.as_entity(); + #( #component_stores )* + let f = f.clone(); Ok(Box::new(move |commands, world| { + #( #query_structs )* + #resource_store - - f(commands ) + f(commands, #( #query_idents, )* #( #resource_idents, )*) })) }), @@ -314,7 +387,7 @@ impl ToTokens for Update { } } - impl AddUpdates<#query_types, #resource_types, Func, #filter_types> for Updates + impl AddUpdates<#query_types, #resource_types, Func, #filter_types> for Updates where Func: Fn(&mut Commands, #( #queries, )* #resources ) -> Result<()> + Send + Sync + Clone + 'static, #filter_requirements @@ -330,7 +403,7 @@ impl ToTokens for Update { } } - impl AddUpdates<#query_types, #resource_types, Func, #filter_types> for WorldBuilder + impl AddUpdates<#query_types, #resource_types, Func, #filter_types> for WorldBuilder where Func: Fn(&mut Commands, #( #queries, )* #resources ) -> Result<()> + Send + Sync + Clone + 'static, #filter_requirements @@ -351,13 +424,29 @@ impl ToTokens for Update { } pub fn update(max_components: usize, max_queries: usize) -> TokenStream { - let updates = (Update::MIN_QUERIES..max_queries) - .map(|query_count| { - // - }) - .collect::>(); + // let updates = (Update::MIN_QUERIES..max_queries) + // .map(|query_count| { + // let queries = (1..query_count).map(|q| { + + // }) + // }) + // .collect::>(); + + let mut query_counts = Vec::new(); + + for components in Update::MIN_COMPONENTS..=max_components { + query_counts.push(components); + } + + let mut resources = Vec::new(); + + for resource in Update::MIN_RESOURCE..Update::MAX_RESOURCE { + resources.push(resource); + } + + let updates = vec![Update::new(vec![2, 2].into_iter(), 1)]; TokenStream::from(quote! { - #( #updates ) + #( #updates )* }) }