Fix proc macro
This commit is contained in:
parent
7ee6ef0a08
commit
d730eb586b
2 changed files with 136 additions and 908 deletions
|
@ -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<Func, Filter, $s> 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<Func, Filter, $s> 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<Func, Filter, $s> 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<Func, Filter, $s, $( $res, )+> 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<Func, Filter, $s, $( $res, )+> 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<Func, Filter, $s, $( $res, )+> 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<Func, Filter, $s, $( $var, )+> 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<Func, Filter, $s, $( $var, )+> 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<Func, Filter, $s, $( $var, )+> 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<Func, Filter, $s, $( $var, )+ $( $res, )+> 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<Func, Filter, $s, $( $var, )+ $( $res, )+> 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<Func, Filter, $s, $( $var, )+ $( $res, )+> 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 [<create_lhs_ $lhs_id _rhs_ $rhs_id>] <F, LeftFilter, RightFilter, $lhs_big, $($rhs_big,)+>
|
||||
(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<Func, LhsFilter, RhsFilter, $lhs_big, $($rhs_big,)+> 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::[<create_lhs_ $lhs_id _rhs_ $rhs_id>](func)))?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl<Func, LhsFilter, RhsFilter, $lhs_big, $($rhs_big,)+> 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 [<create_lhs_ $lhs_id _rhs_ $rhs_id>] <F, LeftFilter, RightFilter, $($lhs_big,)+ $rhs_big>
|
||||
(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<Func, LhsFilter, RhsFilter, $( $lhs_big, )+ $rhs_big> 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::[<create_lhs_ $lhs_id _rhs_ $rhs_id>](func)))?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl<Func, LhsFilter, RhsFilter, $( $lhs_big, )+ $rhs_big> 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 [<create_lhs_ $lhs_id _rhs_ $rhs_id>] <F, LeftFilter, RightFilter, $($lhs_big,)+ $($rhs_big,)+>
|
||||
(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<Func, LhsFilter, RhsFilter, $( $lhs_big, )+ $($rhs_big,)+> 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::[<create_lhs_ $lhs_id _rhs_ $rhs_id>](func)))?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl<Func, LhsFilter, RhsFilter, $( $lhs_big, )+ $($rhs_big,)+> 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<dyn Fn(&EntityObject) -> bool + Send + Sync>,
|
||||
check_entity: Box<dyn Fn(&[&EntityObject]) -> bool + Send + Sync>,
|
||||
create_callback: Box<
|
||||
dyn Fn(
|
||||
&EntityObject,
|
||||
&[&EntityObject],
|
||||
)
|
||||
-> Result<Box<dyn Fn(&mut Commands, &mut World) -> Result<()> + Send + Sync>>
|
||||
+ Send
|
||||
+ Sync,
|
||||
>,
|
||||
|
||||
entities: IndexMap<Entity, Box<dyn Fn(&mut Commands, &mut World) -> Result<()> + Send + Sync>>,
|
||||
entities:
|
||||
IndexMap<Vec<Entity>, Box<dyn Fn(&mut Commands, &mut World) -> 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]);
|
||||
|
|
|
@ -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::<Vec<_>>();
|
||||
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::<Vec<_>>();
|
||||
|
||||
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::<Vec<_>>();
|
||||
|
||||
quote! {
|
||||
#( #query_types, )*
|
||||
}
|
||||
}
|
||||
|
||||
pub fn component_requirements(&self) -> TokenStream2 {
|
||||
let component_requirements = self
|
||||
.queries
|
||||
|
@ -215,10 +241,30 @@ impl Update {
|
|||
.collect::<Vec<_>>();
|
||||
|
||||
quote! {
|
||||
#( #component_requirements, )*
|
||||
#( #component_requirements )*
|
||||
}
|
||||
}
|
||||
|
||||
pub fn resource_store(&self) -> (TokenStream2, Vec<Ident>) {
|
||||
let resource_types = &self.resources;
|
||||
let resource_idents = self
|
||||
.resources
|
||||
.iter()
|
||||
.map(|resource| format_ident!("res_{resource}"))
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
(
|
||||
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::<Vec<_>>();
|
||||
|
||||
let component_stores = self
|
||||
let component_stores_and_queries = self
|
||||
.queries
|
||||
.iter()
|
||||
.enumerate()
|
||||
.map(|(index, query)| query.component_store_and_query(index))
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
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<Func, #filter_types, #query_types, #resource_types> CreateArchetype<#query_types, #resource_types, Func, #filter_types> for Archetype
|
||||
impl<Func, #filter_type_impls #query_type_impls #resource_type_impls> 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<Func, #filter_types, #query_types, #resource_types> AddUpdates<#query_types, #resource_types, Func, #filter_types> for Updates
|
||||
impl<Func, #filter_type_impls #query_type_impls #resource_type_impls> 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<Func, #filter_types, #query_types, #resource_types> AddUpdates<#query_types, #resource_types, Func, #filter_types> for WorldBuilder
|
||||
impl<Func, #filter_type_impls #query_type_impls #resource_type_impls> 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::<Vec<_>>();
|
||||
// let updates = (Update::MIN_QUERIES..max_queries)
|
||||
// .map(|query_count| {
|
||||
// let queries = (1..query_count).map(|q| {
|
||||
|
||||
// })
|
||||
// })
|
||||
// .collect::<Vec<_>>();
|
||||
|
||||
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 )*
|
||||
})
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue