Skip to content

Commit

Permalink
Allow iter combinations on custom world queries (#5286)
Browse files Browse the repository at this point in the history
# Objective

- `.iter_combinations_*()` cannot be used on custom derived `WorldQuery`, so this fixes that
- Fixes #5284

## Solution

- `#[derive(Clone)]` on the `Fetch` of the proc macro derive.
- `#[derive(Clone)]` for `AnyOf` to satisfy tests.
  • Loading branch information
harudagondi committed Jul 13, 2022
1 parent 084a366 commit ada389f
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 0 deletions.
1 change: 1 addition & 0 deletions crates/bevy_ecs/macros/src/fetch.rs
Expand Up @@ -177,6 +177,7 @@ pub fn derive_world_query_impl(ast: DeriveInput) -> TokenStream {
#(#(#ignored_field_attrs)* #ignored_field_visibilities #ignored_field_idents: #ignored_field_types,)*
}

#[derive(Clone)]
#[doc(hidden)]
#visibility struct #fetch_struct_name #user_impl_generics_with_world #user_where_clauses_with_world {
#(#field_idents: #path::query::#fetch_type_alias::<'__w, #field_types>,)*
Expand Down
1 change: 1 addition & 0 deletions crates/bevy_ecs/src/query/fetch.rs
Expand Up @@ -1458,6 +1458,7 @@ macro_rules! impl_tuple_fetch {
/// `Query<AnyOf<(&A, &B, &mut C)>>` is equivalent to `Query<(Option<&A>, Option<&B>, Option<&mut C>), (Or(With<A>, With<B>, With<C>)>`.
/// Each of the components in `T` is returned as an `Option`, as with `Option<A>` queries.
/// Entities are guaranteed to have at least one of the components in `T`.
#[derive(Clone)]
pub struct AnyOf<T>(T);

macro_rules! impl_anytuple_fetch {
Expand Down
20 changes: 20 additions & 0 deletions crates/bevy_ecs/src/query/mod.rs
Expand Up @@ -592,6 +592,26 @@ count(): {count}"#
.collect::<Vec<_>>();
assert_eq!(custom_param_entities, normal_entities);
}

{
#[derive(WorldQuery)]
struct IterCombAB {
a: &'static A,
b: &'static B,
}

let custom_param_data = world
.query::<IterCombAB>()
.iter_combinations::<2>(&world)
.map(|[item0, item1]| [(*item0.a, *item0.b), (*item1.a, *item1.b)])
.collect::<Vec<_>>();
let normal_data = world
.query::<(&A, &B)>()
.iter_combinations(&world)
.map(|[(a0, b0), (a1, b1)]| [(*a0, *b0), (*a1, *b1)])
.collect::<Vec<_>>();
assert_eq!(custom_param_data, normal_data);
}
}

#[test]
Expand Down

0 comments on commit ada389f

Please sign in to comment.