Add iter_many_manual QueryState method (#8772)

# 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`
This commit is contained in:
Nicola Papale 2023-06-11 01:24:09 +02:00 committed by GitHub
parent 32faf4cb5c
commit 527d3a5885
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -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.