Implement single queries for tuple entities

This commit is contained in:
hodasemi 2025-04-08 20:04:08 +02:00
parent 7a20347988
commit c728605684

View file

@ -451,6 +451,282 @@ macro_rules! impl_singleton_update {
} }
macro_rules! impl_pair_update { 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_id: expr,
( $([$lhs_little: ident: $lhs_big: ident]$(,)?)+ ), ( $([$lhs_little: ident: $lhs_big: ident]$(,)?)+ ),