Implement single query case

This commit is contained in:
hodasemi 2025-04-08 19:49:07 +02:00
parent 3aa5438fed
commit 7a20347988

View file

@ -18,30 +18,24 @@ use crate::*;
use update_macros::{implement_pair_update, implement_single_update};
macro_rules! impl_singleton_update {
// without resources
( $($var:ident $(,)?)+ ) => {
impl<Func, Filter, $( $var, )+> CreateArchetype<( $( $var, )+ ), (), Func, Filter> for Archetype
// single without resources
( $s:ident, ) => {
impl<Func, Filter, $s> CreateArchetype<$s, (), Func, Filter> for Archetype
where
Func: Fn(&mut Commands, Query<( $( &mut $var, )+ ), Filter>) -> Result<()> + Send + Sync + Clone + 'static,
Func: Fn(&mut Commands, Query<&mut $s, Filter>) -> Result<()> + Send + Sync + Clone + 'static,
Filter: CheckFilter + 'static,
$(
$var: EntityComponent + ComponentDebug,
)+
$s: EntityComponent + ComponentDebug,
{
paste::item! {
fn create(f: Func) -> Self {
$(
Filter::verify_dedup::<$var>();
)+
Filter::verify_dedup::<$s>();
Self {
check_entity: Box::new({
move |entity| {
$(
if !entity.components.contains::<$var>() {
if !entity.components.contains::<$s>() {
return false;
}
)+
if !Filter::check(entity) {
return false;
@ -52,11 +46,9 @@ macro_rules! impl_singleton_update {
}),
create_callback: Box::new(move |entity| {
$(
let [< $var:lower >] = UnsafeComponentStore::from(
entity.get_component::<$var>()?
let [< $s:lower >] = UnsafeComponentStore::from(
entity.get_component::<$s>()?
);
)+
let e = entity.as_entity();
let f = f.clone();
@ -64,7 +56,7 @@ macro_rules! impl_singleton_update {
Ok(Box::new(move |commands, _world| {
let query = Query {
entity: e,
c: unsafe { ($([< $var:lower >].as_mut(),)+) },
c: unsafe { [< $s:lower >].as_mut() },
filter: PhantomData,
};
@ -78,12 +70,10 @@ macro_rules! impl_singleton_update {
}
}
impl<Func, Filter, $( $var, )+> AddUpdates<( $( $var, )+ ), (), Func, Filter> for Updates
impl<Func, Filter, $s> AddUpdates<$s, (), Func, Filter> for Updates
where
$(
$var: EntityComponent + ComponentDebug,
)+
Func: Fn(& mut Commands, Query<( $( &mut $var, )+ ), Filter>) -> Result<()> + Send + Sync + Clone + 'static,
$s: EntityComponent + ComponentDebug,
Func: Fn(&mut Commands, Query<&mut $s, Filter>) -> Result<()> + Send + Sync + Clone + 'static,
Filter: CheckFilter + 'static
{
fn add_update(
@ -98,12 +88,10 @@ macro_rules! impl_singleton_update {
}
}
impl<Func, Filter, $( $var, )+> AddUpdates<( $( $var, )+ ), (), Func, Filter> for WorldBuilder
impl<Func, Filter, $s> AddUpdates<$s, (), Func, Filter> for WorldBuilder
where
$(
$var: EntityComponent + ComponentDebug,
)+
Func: Fn(& mut Commands, Query<( $( &mut $var, )+ ), Filter>) -> Result<()> + Send + Sync + Clone + 'static,
$s: EntityComponent + ComponentDebug,
Func: Fn(&mut Commands, Query<&mut $s, Filter>) -> Result<()> + Send + Sync + Clone + 'static,
Filter: CheckFilter + 'static
{
fn add_update(
@ -116,21 +104,125 @@ macro_rules! impl_singleton_update {
}
}
};
// with resources
( $($var:ident $(,)?)+ [$($res:ident $(,)?)+] ) => {
impl<Func, Filter, $( $var, )+ $( $res, )+> CreateArchetype<( $( $var, )+ ), ( $( $res, )+ ), Func, Filter> for Archetype
// 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 $var, )+ ), Filter>, $(&mut $res,)+) -> Result<()> + Send + Sync + Clone + 'static,
Func: Fn(&mut Commands, Query<&mut $s, Filter>, $(&mut $res,)+) -> Result<()> + Send + Sync + Clone + 'static,
Filter: CheckFilter + 'static,
$(
$var: EntityComponent + ComponentDebug,
)+
$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>();
)+
@ -138,6 +230,10 @@ macro_rules! impl_singleton_update {
Self {
check_entity: Box::new({
move |entity| {
if !entity.components.contains::<$s>() {
return false;
}
$(
if !entity.components.contains::<$var>() {
return false;
@ -153,6 +249,10 @@ macro_rules! impl_singleton_update {
}),
create_callback: Box::new(move |entity| {
let [< $s:lower >] = UnsafeComponentStore::from(
entity.get_component::<$s>()?
);
$(
let [< $var:lower >] = UnsafeComponentStore::from(
entity.get_component::<$var>()?
@ -162,25 +262,14 @@ macro_rules! impl_singleton_update {
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()?;
Ok(Box::new(move |commands, _world| {
let query = Query {
entity: e,
c: unsafe { ($([< $var:lower >].as_mut(),)+) },
c: unsafe { ( [< $s:lower >].as_mut(), $([< $var:lower >].as_mut(),)+) },
filter: PhantomData,
};
f(commands, query, $([< $res:lower _var >],)+)
f(commands, query)
}))
}),
@ -190,15 +279,13 @@ macro_rules! impl_singleton_update {
}
}
impl<Func, Filter, $( $var, )+ $( $res, )+> AddUpdates<( $( $var, )+ ), ( $( $res, )+ ), Func, Filter> for Updates
impl<Func, Filter, $s, $( $var, )+> AddUpdates<( $s, $( $var, )+ ), (), Func, Filter> for Updates
where
$s: EntityComponent + ComponentDebug,
$(
$var: EntityComponent + ComponentDebug,
)+
$(
$res: ResourceTrait,
)+
Func: Fn(& mut Commands, Query<( $( &mut $var, )+ ), Filter>, $(&mut $res,)+) -> Result<()> + Send + Sync + Clone + 'static,
Func: Fn(&mut Commands, Query<( &mut $s, $( &mut $var, )+ ), Filter>) -> Result<()> + Send + Sync + Clone + 'static,
Filter: CheckFilter + 'static
{
fn add_update(
@ -213,15 +300,142 @@ macro_rules! impl_singleton_update {
}
}
impl<Func, Filter, $( $var, )+ $( $res, )+> AddUpdates<( $( $var, )+ ), ( $( $res, )+ ), Func, Filter> for WorldBuilder
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,
)+
Func: Fn(& mut Commands, Query<( $( &mut $var, )+ ), Filter>, $(&mut $res,)+) -> Result<()> + Send + Sync + Clone + 'static,
{
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(