Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mention in docs about the query iteration order and result uniqueness. #12400

Merged
merged 3 commits into from
Mar 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions crates/bevy_ecs/src/query/state.rs
Original file line number Diff line number Diff line change
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.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was curious about this: Is the iteration order random at some length? Or do it choose as first some archetypes rather than others?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right now it's in archetype ID order, but adding and removing components moves entities around both on tables and archetypes.

The exact iteration order should not be mentioned as it's not guaranteed in any form and subject to change at any time.

#[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
Original file line number Diff line number Diff line change
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