Skip to content

Commit

Permalink
Mention in docs about the query iteration order and result uniqueness. (
Browse files Browse the repository at this point in the history
#12400)

# Objective
Fix #10876. Improve `Query` and `QueryState`'s docs.

## Solution
Explicitly denote that Query is always guaranteed to return results from
all matching entities once and only once for each entity, and that
iteration order is not guaranteed in any way.
  • Loading branch information
james7132 committed Mar 11, 2024
1 parent c9e3285 commit 879b170
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 4 deletions.
24 changes: 24 additions & 0 deletions crates/bevy_ecs/src/query/state.rs
Expand Up @@ -730,6 +730,9 @@ impl<D: QueryData, F: QueryFilter> QueryState<D, F> {
}

/// Returns an [`Iterator`] over the query results for the given [`World`].
///
/// This iterator is always guaranteed to return results from each matching entity once and only once.
/// Iteration order is not guaranteed.
#[inline]
pub fn iter_mut<'w, 's>(&'s mut self, world: &'w mut World) -> QueryIter<'w, 's, D, F> {
self.update_archetypes(world);
Expand All @@ -744,6 +747,9 @@ impl<D: QueryData, F: QueryFilter> QueryState<D, F> {
/// Returns an [`Iterator`] over the query results for the given [`World`] without updating the query's archetypes.
/// Archetypes must be manually updated before by using [`Self::update_archetypes`].
///
/// This iterator is always guaranteed to return results from each matching entity once and only once.
/// Iteration order is not guaranteed.
///
/// This can only be called for read-only queries.
#[inline]
pub fn iter_manual<'w, 's>(&'s self, world: &'w World) -> QueryIter<'w, 's, D::ReadOnly, F> {
Expand Down Expand Up @@ -777,6 +783,9 @@ impl<D: QueryData, F: QueryFilter> QueryState<D, F> {
///
/// The `iter_combinations` method does not guarantee order of iteration.
///
/// This iterator is always guaranteed to return results from each unique pair of matching entities.
/// Iteration order is not guaranteed.
///
/// This can only be called for read-only queries, see [`Self::iter_combinations_mut`] for
/// write-queries.
#[inline]
Expand Down Expand Up @@ -923,6 +932,9 @@ impl<D: QueryData, F: QueryFilter> QueryState<D, F> {

/// Returns an [`Iterator`] over the query results for the given [`World`].
///
/// This iterator is always guaranteed to return results from each matching entity once and only once.
/// Iteration order is not guaranteed.
///
/// # Safety
///
/// This does not check for mutable query correctness. To be safe, make sure mutable queries
Expand All @@ -940,6 +952,9 @@ impl<D: QueryData, F: QueryFilter> QueryState<D, F> {
/// given [`World`] without repetition.
/// This can only be called for read-only queries.
///
/// This iterator is always guaranteed to return results from each unique pair of matching entities.
/// Iteration order is not guaranteed.
///
/// # Safety
///
/// This does not check for mutable query correctness. To be safe, make sure mutable queries
Expand All @@ -960,6 +975,9 @@ impl<D: QueryData, F: QueryFilter> QueryState<D, F> {
/// Returns an [`Iterator`] for the given [`World`], where the last change and
/// the current change tick are given.
///
/// This iterator is always guaranteed to return results from each matching entity once and only once.
/// Iteration order is not guaranteed.
///
/// # Safety
///
/// This does not check for mutable query correctness. To be safe, make sure mutable queries
Expand All @@ -979,6 +997,9 @@ impl<D: QueryData, F: QueryFilter> QueryState<D, F> {
/// Returns an [`Iterator`] for the given [`World`] and list of [`Entity`]'s, where the last change and
/// the current change tick are given.
///
/// This iterator is always guaranteed to return results from each unique pair of matching entities.
/// Iteration order is not guaranteed.
///
/// # Safety
///
/// This does not check for mutable query correctness. To be safe, make sure mutable queries
Expand All @@ -1004,6 +1025,9 @@ impl<D: QueryData, F: QueryFilter> QueryState<D, F> {
/// given [`World`] without repetition.
/// This can only be called for read-only queries.
///
/// This iterator is always guaranteed to return results from each unique pair of matching entities.
/// Iteration order is not guaranteed.
///
/// # Safety
///
/// This does not check for mutable query correctness. To be safe, make sure mutable queries
Expand Down
41 changes: 37 additions & 4 deletions crates/bevy_ecs/src/system/query.rs
Expand Up @@ -407,6 +407,9 @@ impl<'w, 's, D: QueryData, F: QueryFilter> Query<'w, 's, D, F> {

/// Returns an [`Iterator`] over the read-only query items.
///
/// This iterator is always guaranteed to return results from each matching entity once and only once.
/// Iteration order is not guaranteed.
///
/// # Example
///
/// Here, the `report_names_system` iterates over the `Player` component of every entity that contains it:
Expand Down Expand Up @@ -442,6 +445,9 @@ impl<'w, 's, D: QueryData, F: QueryFilter> Query<'w, 's, D, F> {

/// Returns an [`Iterator`] over the query items.
///
/// This iterator is always guaranteed to return results from each matching entity once and only once.
/// Iteration order is not guaranteed.
///
/// # Example
///
/// Here, the `gravity_system` updates the `Velocity` component of every entity that contains it:
Expand Down Expand Up @@ -474,6 +480,9 @@ impl<'w, 's, D: QueryData, F: QueryFilter> Query<'w, 's, D, F> {

/// Returns a [`QueryCombinationIter`] over all combinations of `K` read-only query items without repetition.
///
/// This iterator is always guaranteed to return results from each unique pair of matching entities.
/// Iteration order is not guaranteed.
///
/// # Example
///
/// ```
Expand Down Expand Up @@ -509,6 +518,9 @@ impl<'w, 's, D: QueryData, F: QueryFilter> Query<'w, 's, D, F> {

/// Returns a [`QueryCombinationIter`] over all combinations of `K` query items without repetition.
///
/// This iterator is always guaranteed to return results from each unique pair of matching entities.
/// Iteration order is not guaranteed.
///
/// # Example
///
/// ```
Expand Down Expand Up @@ -539,8 +551,8 @@ impl<'w, 's, D: QueryData, F: QueryFilter> Query<'w, 's, D, 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.
/// Items are returned in the order of the list of entities, and may not be unique if the input
/// doesnn't guarantee uniqueness. Entities that don't match the query are skipped.
///
/// # Example
///
Expand Down Expand Up @@ -596,8 +608,8 @@ impl<'w, 's, D: QueryData, F: QueryFilter> Query<'w, 's, D, F> {

/// Returns an iterator over the 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.
/// Items are returned in the order of the list of entities, and may not be unique if the input
/// doesnn't guarantee uniqueness. Entities that don't match the query are skipped.
///
/// # Examples
///
Expand Down Expand Up @@ -648,6 +660,9 @@ impl<'w, 's, D: QueryData, F: QueryFilter> Query<'w, 's, D, F> {

/// Returns an [`Iterator`] over the query items.
///
/// This iterator is always guaranteed to return results from each matching entity once and only once.
/// Iteration order is not guaranteed.
///
/// # Safety
///
/// This function makes it possible to violate Rust's aliasing guarantees.
Expand All @@ -669,6 +684,9 @@ impl<'w, 's, D: QueryData, F: QueryFilter> Query<'w, 's, D, F> {

/// Iterates over all possible combinations of `K` query items without repetition.
///
/// This iterator is always guaranteed to return results from each unique pair of matching entities.
/// Iteration order is not guaranteed.
///
/// # Safety
///
/// This allows aliased mutability.
Expand All @@ -692,6 +710,9 @@ impl<'w, 's, D: QueryData, F: QueryFilter> Query<'w, 's, D, F> {

/// Returns an [`Iterator`] over the query items generated from an [`Entity`] list.
///
/// Items are returned in the order of the list of entities, and may not be unique if the input
/// doesnn't guarantee uniqueness. Entities that don't match the query are skipped.
///
/// # Safety
///
/// This allows aliased mutability and does not check for entity uniqueness.
Expand Down Expand Up @@ -723,6 +744,12 @@ impl<'w, 's, D: QueryData, F: QueryFilter> Query<'w, 's, D, F> {

/// Returns a parallel iterator over the query results for the given [`World`].
///
/// This parallel iterator is always guaranteed to return results from each matching entity once and
/// only once. Iteration order and thread assignment is not guaranteed.
///
/// If the `multithreaded` feature is disabled, iterating with this operates identically to [`Iterator::for_each`]
/// on [`QueryIter`].
///
/// This can only be called for read-only queries, see [`par_iter_mut`] for write-queries.
///
/// Note that you must use the `for_each` method to iterate over the
Expand All @@ -743,6 +770,12 @@ impl<'w, 's, D: QueryData, F: QueryFilter> Query<'w, 's, D, F> {

/// Returns a parallel iterator over the query results for the given [`World`].
///
/// This parallel iterator is always guaranteed to return results from each matching entity once and
/// only once. Iteration order and thread assignment is not guaranteed.
///
/// If the `multithreaded` feature is disabled, iterating with this operates identically to [`Iterator::for_each`]
/// on [`QueryIter`].
///
/// This can only be called for mutable queries, see [`par_iter`] for read-only-queries.
///
/// # Example
Expand Down

0 comments on commit 879b170

Please sign in to comment.