bevy/crates/bevy_ecs/src
Vladyslav Batyrenko ba6b74ba20 Implement WorldQuery derive macro (#2713)
# Objective

- Closes #786
- Closes #2252
- Closes #2588

This PR implements a derive macro that allows users to define their queries as structs with named fields.

## Example

```rust
#[derive(WorldQuery)]
#[world_query(derive(Debug))]
struct NumQuery<'w, T: Component, P: Component> {
    entity: Entity,
    u: UNumQuery<'w>,
    generic: GenericQuery<'w, T, P>,
}

#[derive(WorldQuery)]
#[world_query(derive(Debug))]
struct UNumQuery<'w> {
    u_16: &'w u16,
    u_32_opt: Option<&'w u32>,
}

#[derive(WorldQuery)]
#[world_query(derive(Debug))]
struct GenericQuery<'w, T: Component, P: Component> {
    generic: (&'w T, &'w P),
}

#[derive(WorldQuery)]
#[world_query(filter)]
struct NumQueryFilter<T: Component, P: Component> {
    _u_16: With<u16>,
    _u_32: With<u32>,
    _or: Or<(With<i16>, Changed<u16>, Added<u32>)>,
    _generic_tuple: (With<T>, With<P>),
    _without: Without<Option<u16>>,
    _tp: PhantomData<(T, P)>,
}

fn print_nums_readonly(query: Query<NumQuery<u64, i64>, NumQueryFilter<u64, i64>>) {
    for num in query.iter() {
        println!("{:#?}", num);
    }
}

#[derive(WorldQuery)]
#[world_query(mutable, derive(Debug))]
struct MutNumQuery<'w, T: Component, P: Component> {
    i_16: &'w mut i16,
    i_32_opt: Option<&'w mut i32>,
}

fn print_nums(mut query: Query<MutNumQuery, NumQueryFilter<u64, i64>>) {
    for num in query.iter_mut() {
        println!("{:#?}", num);
    }
}
```

## TODOs:
- [x] Add support for `&T` and `&mut T`
  - [x] Test
- [x] Add support for optional types
  - [x] Test
- [x] Add support for `Entity`
  - [x] Test
- [x] Add support for nested `WorldQuery`
  - [x] Test
- [x] Add support for tuples
  - [x] Test
- [x] Add support for generics
  - [x] Test
- [x] Add support for query filters
  - [x] Test
- [x] Add support for `PhantomData`
  - [x] Test
- [x] Refactor `read_world_query_field_type_info`
- [x] Properly document `readonly` attribute for nested queries and the static assertions that guarantee safety
  - [x] Test that we never implement `ReadOnlyFetch` for types that need mutable access
  - [x] Test that we insert static assertions for nested `WorldQuery` that a user marked as readonly
2022-02-24 00:19:49 +00:00
..
entity Proper prehashing (#3963) 2022-02-18 03:26:01 +00:00
query Implement WorldQuery derive macro (#2713) 2022-02-24 00:19:49 +00:00
schedule small and mostly pointless refactoring (#2934) 2022-02-13 22:33:55 +00:00
storage Proper prehashing (#3963) 2022-02-18 03:26:01 +00:00
system Implement WorldQuery derive macro (#2713) 2022-02-24 00:19:49 +00:00
world SystemState usage docs (#3783) 2022-02-15 21:53:52 +00:00
archetype.rs small and mostly pointless refactoring (#2934) 2022-02-13 22:33:55 +00:00
bundle.rs small and mostly pointless refactoring (#2934) 2022-02-13 22:33:55 +00:00
change_detection.rs add missing into_inner to ReflectMut (#3841) 2022-02-04 03:37:45 +00:00
component.rs small and mostly pointless refactoring (#2934) 2022-02-13 22:33:55 +00:00
event.rs small and mostly pointless refactoring (#2934) 2022-02-13 22:33:55 +00:00
lib.rs small and mostly pointless refactoring (#2934) 2022-02-13 22:33:55 +00:00
reflect.rs Add FromReflect trait to convert dynamic types to concrete types (#1395) 2021-12-26 18:49:01 +00:00