Skip to content

Commit

Permalink
Add iter_many_manual QueryState method (#8772)
Browse files Browse the repository at this point in the history
# Objective

`QueryState` exposes a `get_manual` and `iter_manual` method. However,
there is now `iter_many_manual`.

`iter_many_manual` is useful when you have a `&World` (eg: the `world`
in a `Scene`) and want to run a query several times on it (eg:
iteratively navigate a hierarchy by calling `iter_many` on `Children`
component).

`iter_many`'s need for a `&mut World` makes the API much less flexible.
The exclusive access pattern requires doing some very funky dance and
excludes a category of algorithms for hierarchy traversal.

## Solution

- Add a `iter_many_manual` method to `QueryState`

### Alternative

My current workaround is to use `get_manual`. However, this doesn't
benefit from the optimizations on `QueryManyIter`.

---

## Changelog

- Add a `iter_many_manual` method to `QueryState`
  • Loading branch information
nicopap authored Jun 10, 2023
1 parent 32faf4c commit 527d3a5
Showing 1 changed file with 35 additions and 0 deletions.
35 changes: 35 additions & 0 deletions crates/bevy_ecs/src/query/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -652,6 +652,41 @@ impl<Q: WorldQuery, F: ReadOnlyWorldQuery> QueryState<Q, F> {
}
}

/// Returns an [`Iterator`] over the read-only query items generated from an [`Entity`] list.
///
/// Items are returned in the order of the list of entities.
/// Entities that don't match the query are skipped.
///
/// If `world` archetypes changed since [`Self::update_archetypes`] was last called,
/// this will skip entities contained in new archetypes.
///
/// This can only be called for read-only queries.
///
/// # See also
///
/// - [`iter_many`](Self::iter_many) to update archetypes.
/// - [`iter_manual`](Self::iter_manual) to iterate over all query items.
#[inline]
pub fn iter_many_manual<'w, 's, EntityList: IntoIterator>(
&'s self,
world: &'w World,
entities: EntityList,
) -> QueryManyIter<'w, 's, Q::ReadOnly, F::ReadOnly, EntityList::IntoIter>
where
EntityList::Item: Borrow<Entity>,
{
self.validate_world(world);
// SAFETY: query is read only, world id is validated
unsafe {
self.as_readonly().iter_many_unchecked_manual(
entities,
world,
world.last_change_tick(),
world.read_change_tick(),
)
}
}

/// Returns an iterator over the query items generated from an [`Entity`] list.
///
/// Items are returned in the order of the list of entities.
Expand Down

0 comments on commit 527d3a5

Please sign in to comment.