mirror of
https://github.com/bevyengine/bevy
synced 2024-11-23 13:13:49 +00:00
92ddfe8ad4
# Objective Improve querying ergonomics around collections and iterators of entities. Example how queries over Children might be done currently. ```rust fn system(foo_query: Query<(&Foo, &Children)>, bar_query: Query<(&Bar, &Children)>) { for (foo, children) in &foo_query { for child in children.iter() { if let Ok((bar, children)) = bar_query.get(*child) { for child in children.iter() { if let Ok((foo, children)) = foo_query.get(*child) { // D: } } } } } } ``` Answers #4868 Partially addresses #4864 Fixes #1470 ## Solution Based on the great work by @deontologician in #2563 Added `iter_many` and `many_for_each_mut` to `Query`. These take a list of entities (Anything that implements `IntoIterator<Item: Borrow<Entity>>`). `iter_many` returns a `QueryManyIter` iterator over immutable results of a query (mutable data will be cast to an immutable form). `many_for_each_mut` calls a closure for every result of the query, ensuring not aliased mutability. This iterator goes over the list of entities in order and returns the result from the query for it. Skipping over any entities that don't match the query. Also added `unsafe fn iter_many_unsafe`. ### Examples ```rust #[derive(Component)] struct Counter { value: i32 } #[derive(Component)] struct Friends { list: Vec<Entity>, } fn system( friends_query: Query<&Friends>, mut counter_query: Query<&mut Counter>, ) { for friends in &friends_query { for counter in counter_query.iter_many(&friends.list) { println!("Friend's counter: {:?}", counter.value); } counter_query.many_for_each_mut(&friends.list, |mut counter| { counter.value += 1; println!("Friend's counter: {:?}", counter.value); }); } } ``` Here's how example in the Objective section can be written with this PR. ```rust fn system(foo_query: Query<(&Foo, &Children)>, bar_query: Query<(&Bar, &Children)>) { for (foo, children) in &foo_query { for (bar, children) in bar_query.iter_many(children) { for (foo, children) in foo_query.iter_many(children) { // :D } } } } ``` ## Additional changes Implemented `IntoIterator` for `&Children` because why not. ## Todo - Bikeshed! Co-authored-by: deontologician <deontologician@gmail.com> Co-authored-by: devil-ira <justthecooldude@gmail.com> |
||
---|---|---|
.. | ||
entity_ref_mut_lifetime_safety.rs | ||
entity_ref_mut_lifetime_safety.stderr | ||
query_lifetime_safety.rs | ||
query_lifetime_safety.stderr | ||
system_param_derive_readonly.rs | ||
system_param_derive_readonly.stderr | ||
system_query_get_lifetime_safety.rs | ||
system_query_get_lifetime_safety.stderr | ||
system_query_get_many_lifetime_safety.rs | ||
system_query_get_many_lifetime_safety.stderr | ||
system_query_get_many_mut_lifetime_safety.rs | ||
system_query_get_many_mut_lifetime_safety.stderr | ||
system_query_iter_lifetime_safety.rs | ||
system_query_iter_lifetime_safety.stderr | ||
system_query_many_for_each_mut_lifetime_safety.rs | ||
system_query_many_for_each_mut_lifetime_safety.stderr | ||
system_query_set_get_lifetime_safety.rs | ||
system_query_set_get_lifetime_safety.stderr | ||
system_query_set_iter_lifetime_safety.rs | ||
system_query_set_iter_lifetime_safety.stderr | ||
system_state_get_lifetime_safety.rs | ||
system_state_get_lifetime_safety.stderr | ||
system_state_iter_lifetime_safety.rs | ||
system_state_iter_lifetime_safety.stderr | ||
system_state_iter_mut_overlap_safety.rs | ||
system_state_iter_mut_overlap_safety.stderr | ||
world_query_derive.rs | ||
world_query_derive.stderr |