Improve Query's top-level documentation (#18622)

# Objective

- There's been several changes to `Query` for this release cycle, and
`Query`'s top-level documentation has gotten slightly out-of-date.
- Alternative to #18615.

## Solution

- Edit `Query`'s docs for consistency, clarity, and correctness.
- Make sure to group `get()` and `get_many()` together instead of
`single()` and `get_many()`, to enforce the distinction from
https://github.com/bevyengine/bevy/pull/18615#issuecomment-2764355672.
- Reformat doc tests so they would be readable if extracted into their
own file. (Which mainly involves adding more spacing.)
- Move link definitions to be nearer where they are used.
- Fix the tables so they are up-to-date and correctly escape square
brackets `\[ \]`.

## Testing

I ran `cargo doc -p bevy_ecs --no-deps` to view the docs and `cargo test
-p bevy_ecs --doc` to test the doc comments.

## Reviewing

The diff is difficult to read, so I don't recommend _just_ looking at
that. Instead, run `cargo doc -p bevy_ecs --no-deps` locally and read
through the new version. It should theoretically read smoother with less
super-technical jargon. :)

## Follow-up

I want to go through some of `Query`'s methods, such as `single()`,
`get()`, and `get_many()`, but I'll leave that for another PR.

---------

Co-authored-by: Chris Russell <8494645+chescock@users.noreply.github.com>
This commit is contained in:
BD103 2025-03-31 14:12:24 -04:00 committed by GitHub
parent 9de7bd4d87
commit bb87bd4d02
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -15,33 +15,40 @@ use core::{
ops::{Deref, DerefMut}, ops::{Deref, DerefMut},
}; };
/// [System parameter] that provides selective access to the [`Component`] data stored in a [`World`]. /// A [system parameter] that provides selective access to the [`Component`] data stored in a [`World`].
/// ///
/// Enables access to [entity identifiers] and [components] from a system, without the need to directly access the world. /// Queries enable systems to access [entity identifiers] and [components] without requiring direct access to the [`World`].
/// Its iterators and getter methods return *query items*. /// Its iterators and getter methods return *query items*, which are types containing data related to an entity.
/// Each query item is a type containing data relative to an entity.
/// ///
/// `Query` is a generic data structure that accepts two type parameters: /// `Query` is a generic data structure that accepts two type parameters:
/// ///
/// - **`D` (query data).** /// - **`D` (query data)**:
/// The type of data contained in the query item. /// The type of data fetched by the query, which will be returned as the query item.
/// Only entities that match the requested data will generate an item. /// Only entities that match the requested data will generate an item.
/// Must implement the [`QueryData`] trait. /// Must implement the [`QueryData`] trait.
/// - **`F` (query filter).** /// - **`F` (query filter)**:
/// A set of conditions that determines whether query items should be kept or discarded. /// An optional set of conditions that determine whether query items should be kept or discarded.
/// This defaults to [`unit`], which means no additional filters will be applied.
/// Must implement the [`QueryFilter`] trait. /// Must implement the [`QueryFilter`] trait.
/// This type parameter is optional.
/// ///
/// [system parameter]: crate::system::SystemParam
/// [`Component`]: crate::component::Component
/// [`World`]: crate::world::World /// [`World`]: crate::world::World
/// [entity identifiers]: Entity
/// [components]: crate::component::Component
/// ///
/// # Similar parameters /// # Similar parameters
/// ///
/// [`Query`] has few sibling [`SystemParam`](crate::system::system_param::SystemParam)s, which perform additional validation: /// `Query` has few sibling [`SystemParam`]s, which perform additional validation:
///
/// - [`Single`] - Exactly one matching query item. /// - [`Single`] - Exactly one matching query item.
/// - [`Option<Single>`] - Zero or one matching query item. /// - [`Option<Single>`] - Zero or one matching query item.
/// - [`Populated`] - At least one matching query item. /// - [`Populated`] - At least one matching query item.
/// ///
/// Those parameters will prevent systems from running if their requirements aren't met. /// These parameters will prevent systems from running if their requirements are not met.
///
/// [`SystemParam`]: crate::system::system_param::SystemParam
/// [`Option<Single>`]: Single
/// ///
/// # System parameter declaration /// # System parameter declaration
/// ///
@ -50,330 +57,428 @@ use core::{
/// ///
/// ## Component access /// ## Component access
/// ///
/// A query defined with a reference to a component as the query fetch type parameter can be used to generate items that refer to the data of said component. /// You can fetch an entity's component by specifying a reference to that component in the query's data parameter:
/// ///
/// ``` /// ```
/// # use bevy_ecs::prelude::*; /// # use bevy_ecs::prelude::*;
/// #
/// # #[derive(Component)] /// # #[derive(Component)]
/// # struct ComponentA; /// # struct ComponentA;
/// # fn immutable_ref( /// #
/// // A component can be accessed by shared reference... /// // A component can be accessed by a shared reference...
/// query: Query<&ComponentA> /// fn immutable_query(query: Query<&ComponentA>) {
/// # ) {} /// // ...
/// # bevy_ecs::system::assert_is_system(immutable_ref); /// }
/// ///
/// # fn mutable_ref( /// // ...or by a mutable reference.
/// // ... or by mutable reference. /// fn mutable_query(query: Query<&mut ComponentA>) {
/// query: Query<&mut ComponentA> /// // ...
/// # ) {} /// }
/// # bevy_ecs::system::assert_is_system(mutable_ref); /// #
/// # bevy_ecs::system::assert_is_system(immutable_query);
/// # bevy_ecs::system::assert_is_system(mutable_query);
/// ```
///
/// Note that components need to be behind a reference (`&` or `&mut`), or the query will not compile:
///
/// ```compile_fail,E0277
/// # use bevy_ecs::prelude::*;
/// #
/// # #[derive(Component)]
/// # struct ComponentA;
/// #
/// // This needs to be `&ComponentA` or `&mut ComponentA` in order to compile.
/// fn invalid_query(query: Query<ComponentA>) {
/// // ...
/// }
/// ``` /// ```
/// ///
/// ## Query filtering /// ## Query filtering
/// ///
/// Setting the query filter type parameter will ensure that each query item satisfies the given condition. /// Setting the query filter type parameter will ensure that each query item satisfies the given condition:
/// ///
/// ``` /// ```
/// # use bevy_ecs::prelude::*; /// # use bevy_ecs::prelude::*;
/// #
/// # #[derive(Component)] /// # #[derive(Component)]
/// # struct ComponentA; /// # struct ComponentA;
/// #
/// # #[derive(Component)] /// # #[derive(Component)]
/// # struct ComponentB; /// # struct ComponentB;
/// # fn system( /// #
/// // Just `ComponentA` data will be accessed, but only for entities that also contain /// // `ComponentA` data will be accessed, but only for entities that also contain `ComponentB`.
/// // `ComponentB`. /// fn filtered_query(query: Query<&ComponentA, With<ComponentB>>) {
/// query: Query<&ComponentA, With<ComponentB>> /// // ...
/// # ) {} /// }
/// # bevy_ecs::system::assert_is_system(system); /// #
/// # bevy_ecs::system::assert_is_system(filtered_query);
/// ``` /// ```
/// ///
/// Note that the filter is `With<ComponentB>`, not `With<&ComponentB>`. Unlike query data, `With`
/// does require components to be behind a reference.
///
/// ## `QueryData` or `QueryFilter` tuples /// ## `QueryData` or `QueryFilter` tuples
/// ///
/// Using tuples, each `Query` type parameter can contain multiple elements. /// Using [`tuple`]s, each `Query` type parameter can contain multiple elements.
/// ///
/// In the following example, two components are accessed simultaneously, and the query items are filtered on two conditions. /// In the following example two components are accessed simultaneously, and the query items are
/// filtered on two conditions:
/// ///
/// ``` /// ```
/// # use bevy_ecs::prelude::*; /// # use bevy_ecs::prelude::*;
/// #
/// # #[derive(Component)] /// # #[derive(Component)]
/// # struct ComponentA; /// # struct ComponentA;
/// #
/// # #[derive(Component)] /// # #[derive(Component)]
/// # struct ComponentB; /// # struct ComponentB;
/// #
/// # #[derive(Component)] /// # #[derive(Component)]
/// # struct ComponentC; /// # struct ComponentC;
/// #
/// # #[derive(Component)] /// # #[derive(Component)]
/// # struct ComponentD; /// # struct ComponentD;
/// # fn immutable_ref( /// #
/// query: Query<(&ComponentA, &ComponentB), (With<ComponentC>, Without<ComponentD>)> /// fn complex_query(
/// # ) {} /// query: Query<(&mut ComponentA, &ComponentB), (With<ComponentC>, Without<ComponentD>)>
/// # bevy_ecs::system::assert_is_system(immutable_ref); /// ) {
/// // ...
/// }
/// #
/// # bevy_ecs::system::assert_is_system(complex_query);
/// ```
///
/// Note that this currently only works on tuples with 15 or fewer items. You may nest tuples to
/// get around this limit:
///
/// ```
/// # use bevy_ecs::prelude::*;
/// #
/// # #[derive(Component)]
/// # struct ComponentA;
/// #
/// # #[derive(Component)]
/// # struct ComponentB;
/// #
/// # #[derive(Component)]
/// # struct ComponentC;
/// #
/// # #[derive(Component)]
/// # struct ComponentD;
/// #
/// fn nested_query(
/// query: Query<(&ComponentA, &ComponentB, (&mut ComponentC, &mut ComponentD))>
/// ) {
/// // ...
/// }
/// #
/// # bevy_ecs::system::assert_is_system(nested_query);
/// ``` /// ```
/// ///
/// ## Entity identifier access /// ## Entity identifier access
/// ///
/// The identifier of an entity can be made available inside the query item by including [`Entity`] in the query fetch type parameter. /// You can access [`Entity`], the entity identifier, by including it in the query data parameter:
/// ///
/// ``` /// ```
/// # use bevy_ecs::prelude::*; /// # use bevy_ecs::prelude::*;
/// #
/// # #[derive(Component)] /// # #[derive(Component)]
/// # struct ComponentA; /// # struct ComponentA;
/// # fn system( /// #
/// query: Query<(Entity, &ComponentA)> /// fn entity_id_query(query: Query<(Entity, &ComponentA)>) {
/// # ) {} /// // ...
/// # bevy_ecs::system::assert_is_system(system); /// }
/// #
/// # bevy_ecs::system::assert_is_system(entity_id_query);
/// ``` /// ```
/// ///
/// Be aware that [`Entity`] is not a component, so it does not need to be behind a reference.
///
/// ## Optional component access /// ## Optional component access
/// ///
/// A component can be made optional in a query by wrapping it into an [`Option`]. /// A component can be made optional by wrapping it into an [`Option`]. In the following example, a
/// In this way, a query item can still be generated even if the queried entity does not contain the wrapped component. /// query item will still be generated even if the queried entity does not contain `ComponentB`.
/// In this case, its corresponding value will be `None`. /// When this is the case, `Option<&ComponentB>`'s corresponding value will be `None`.
/// ///
/// ``` /// ```
/// # use bevy_ecs::prelude::*; /// # use bevy_ecs::prelude::*;
/// #
/// # #[derive(Component)] /// # #[derive(Component)]
/// # struct ComponentA; /// # struct ComponentA;
/// #
/// # #[derive(Component)] /// # #[derive(Component)]
/// # struct ComponentB; /// # struct ComponentB;
/// # fn system( /// #
/// // Generates items for entities that contain `ComponentA`, and optionally `ComponentB`. /// // A queried items must contain `ComponentA`. If they also contain `ComponentB`, its value will
/// query: Query<(&ComponentA, Option<&ComponentB>)> /// // be fetched as well.
/// # ) {} /// fn optional_component_query(query: Query<(&ComponentA, Option<&ComponentB>)>) {
/// # bevy_ecs::system::assert_is_system(system); /// // ...
/// }
/// #
/// # bevy_ecs::system::assert_is_system(optional_component_query);
/// ``` /// ```
/// ///
/// See the documentation for [`AnyOf`] to idiomatically declare many optional components. /// Optional components can hurt performance in some cases, so please read the [performance]
/// section to learn more about them. Additionally, if you need to declare several optional
/// components, you may be interested in using [`AnyOf`].
/// ///
/// See the [performance] section to learn more about the impact of optional components. /// [performance]: #performance
/// [`AnyOf`]: crate::query::AnyOf
/// ///
/// ## Disjoint queries /// ## Disjoint queries
/// ///
/// A system cannot contain two queries that break Rust's mutability rules. /// A system cannot contain two queries that break Rust's mutability rules, or else it will panic
/// In this case, the [`Without`] filter can be used to disjoint them. /// when initialized. This can often be fixed with the [`Without`] filter, which makes the queries
/// disjoint.
/// ///
/// In the following example, two queries mutably access the same component. /// In the following example, the two queries can mutably access the same `&mut Health` component
/// Executing this system will panic, since an entity could potentially match the two queries at the same time by having both `Player` and `Enemy` components. /// if an entity has both the `Player` and `Enemy` components. Bevy will catch this and panic,
/// This would violate mutability rules. /// however, instead of breaking Rust's mutability rules:
/// ///
/// ```should_panic /// ```should_panic
/// # use bevy_ecs::prelude::*; /// # use bevy_ecs::prelude::*;
/// #
/// # #[derive(Component)] /// # #[derive(Component)]
/// # struct Health; /// # struct Health;
/// #
/// # #[derive(Component)] /// # #[derive(Component)]
/// # struct Player; /// # struct Player;
/// #
/// # #[derive(Component)] /// # #[derive(Component)]
/// # struct Enemy; /// # struct Enemy;
/// # /// #
/// fn randomize_health( /// fn randomize_health(
/// player_query: Query<&mut Health, With<Player>>, /// player_query: Query<&mut Health, With<Player>>,
/// enemy_query: Query<&mut Health, With<Enemy>>, /// enemy_query: Query<&mut Health, With<Enemy>>,
/// ) /// ) {
/// # {} /// // ...
/// # let mut randomize_health_system = IntoSystem::into_system(randomize_health); /// }
/// # let mut world = World::new(); /// #
/// # randomize_health_system.initialize(&mut world); /// # bevy_ecs::system::assert_system_does_not_conflict(randomize_health);
/// # randomize_health_system.run((), &mut world);
/// ``` /// ```
/// ///
/// Adding a `Without` filter will disjoint the queries. /// Adding a [`Without`] filter will disjoint the queries. In the following example, any entity
/// In this way, any entity that has both `Player` and `Enemy` components is excluded from both queries. /// that has both the `Player` and `Enemy` components will be excluded from _both_ queries:
/// ///
/// ``` /// ```
/// # use bevy_ecs::prelude::*; /// # use bevy_ecs::prelude::*;
/// #
/// # #[derive(Component)] /// # #[derive(Component)]
/// # struct Health; /// # struct Health;
/// #
/// # #[derive(Component)] /// # #[derive(Component)]
/// # struct Player; /// # struct Player;
/// #
/// # #[derive(Component)] /// # #[derive(Component)]
/// # struct Enemy; /// # struct Enemy;
/// # /// #
/// fn randomize_health( /// fn randomize_health(
/// player_query: Query<&mut Health, (With<Player>, Without<Enemy>)>, /// player_query: Query<&mut Health, (With<Player>, Without<Enemy>)>,
/// enemy_query: Query<&mut Health, (With<Enemy>, Without<Player>)>, /// enemy_query: Query<&mut Health, (With<Enemy>, Without<Player>)>,
/// ) /// ) {
/// # {} /// // ...
/// # let mut randomize_health_system = IntoSystem::into_system(randomize_health); /// }
/// # let mut world = World::new(); /// #
/// # randomize_health_system.initialize(&mut world); /// # bevy_ecs::system::assert_system_does_not_conflict(randomize_health);
/// # randomize_health_system.run((), &mut world);
/// ``` /// ```
/// ///
/// An alternative to this idiom is to wrap the conflicting queries into a [`ParamSet`](super::ParamSet). /// An alternative solution to this problem would be to wrap the conflicting queries in
/// [`ParamSet`].
///
/// [`Without`]: crate::query::Without
/// [`ParamSet`]: crate::system::ParamSet
/// ///
/// ## Whole Entity Access /// ## Whole Entity Access
/// ///
/// [`EntityRef`]s can be fetched from a query. This will give read-only access to any component on the entity, /// [`EntityRef`] can be used in a query to gain read-only access to all components of an entity.
/// and can be used to dynamically fetch any component without baking it into the query type. Due to this global /// This is useful when dynamically fetching components instead of baking them into the query type.
/// access to the entity, this will block any other system from parallelizing with it. As such these queries
/// should be sparingly used.
/// ///
/// ``` /// ```
/// # use bevy_ecs::prelude::*; /// # use bevy_ecs::prelude::*;
/// #
/// # #[derive(Component)] /// # #[derive(Component)]
/// # struct ComponentA; /// # struct ComponentA;
/// # fn system( /// #
/// query: Query<(EntityRef, &ComponentA)> /// fn all_components_query(query: Query<(EntityRef, &ComponentA)>) {
/// # ) {} /// // ...
/// # bevy_ecs::system::assert_is_system(system); /// }
/// #
/// # bevy_ecs::system::assert_is_system(all_components_query);
/// ``` /// ```
/// ///
/// As `EntityRef` can read any component on an entity, a query using it will conflict with *any* mutable /// As [`EntityRef`] can read any component on an entity, a query using it will conflict with *any*
/// access. It is strongly advised to couple `EntityRef` queries with the use of either `With`/`Without` /// mutable component access.
/// filters or `ParamSets`. This also limits the scope of the query, which will improve iteration performance
/// and also allows it to parallelize with other non-conflicting systems.
/// ///
/// ```should_panic /// ```should_panic
/// # use bevy_ecs::prelude::*; /// # use bevy_ecs::prelude::*;
/// #
/// # #[derive(Component)] /// # #[derive(Component)]
/// # struct ComponentA; /// # struct ComponentA;
/// # fn system( /// #
/// // This will panic! /// // `EntityRef` provides read access to *all* components on an entity. When combined with
/// // EntityRef provides read access to ALL components on an entity. /// // `&mut ComponentA` in the same query, it creates a conflict because `EntityRef` could read
/// // When combined with &mut ComponentA in the same query, it creates /// // `&ComponentA` while `&mut ComponentA` attempts to modify it - violating Rust's borrowing
/// // a conflict because EntityRef could read ComponentA while the &mut /// // rules.
/// // attempts to modify it - violating Rust's borrowing rules of no /// fn invalid_query(query: Query<(EntityRef, &mut ComponentA)>) {
/// // simultaneous read+write access. /// // ...
/// query: Query<(EntityRef, &mut ComponentA)> /// }
/// # ) {} /// #
/// # bevy_ecs::system::assert_system_does_not_conflict(system); /// # bevy_ecs::system::assert_system_does_not_conflict(invalid_query);
/// ``` /// ```
///
/// It is strongly advised to couple [`EntityRef`] queries with the use of either [`With`] /
/// [`Without`] filters or [`ParamSet`]s. Not only does this improve the performance and
/// parallelization of the system, but it enables systems to gain mutable access to other
/// components:
///
/// ``` /// ```
/// # use bevy_ecs::prelude::*; /// # use bevy_ecs::prelude::*;
/// #
/// # #[derive(Component)] /// # #[derive(Component)]
/// # struct ComponentA; /// # struct ComponentA;
/// #
/// # #[derive(Component)] /// # #[derive(Component)]
/// # struct ComponentB; /// # struct ComponentB;
/// # fn system( /// #
/// // This will not panic. /// // The first query only reads entities that have `ComponentA`, while the second query only
/// // This creates a perfect separation where: /// // modifies entities that *don't* have `ComponentA`. Because neither query will access the same
/// // 1. First query reads entities that have ComponentA /// // entity, this system does not conflict.
/// // 2. Second query modifies ComponentB only on entities that DON'T have ComponentA /// fn disjoint_query(
/// // Result: No entity can ever be accessed by both queries simultaneously
/// query_a: Query<EntityRef, With<ComponentA>>, /// query_a: Query<EntityRef, With<ComponentA>>,
/// query_b: Query<&mut ComponentB, Without<ComponentA>>, /// query_b: Query<&mut ComponentB, Without<ComponentA>>,
/// # ) {} /// ) {
/// # bevy_ecs::system::assert_system_does_not_conflict(system); /// // ...
/// }
/// #
/// # bevy_ecs::system::assert_system_does_not_conflict(disjoint_query);
/// ``` /// ```
///
/// The fundamental rule: [`EntityRef`]'s ability to read all components means it can never /// The fundamental rule: [`EntityRef`]'s ability to read all components means it can never
/// coexist with mutable access. With/Without filters guarantee this by keeping the /// coexist with mutable access. [`With`] / [`Without`] filters can guarantee this by keeping the
/// queries on completely separate entities. /// queries on completely separate entities.
/// ///
/// [`EntityRef`]: crate::world::EntityRef
/// [`With`]: crate::query::With
///
/// # Accessing query items /// # Accessing query items
/// ///
/// The following table summarizes the behavior of the safe methods that can be used to get query items. /// The following table summarizes the behavior of safe methods that can be used to get query
/// items:
/// ///
/// |Query methods|Effect| /// |Query methods|Effect|
/// |:---:|---| /// |-|-|
/// |[`iter`]\[[`_mut`][`iter_mut`]]|Returns an iterator over all query items.| /// |[`iter`]\[[`_mut`][`iter_mut`]\]|Returns an iterator over all query items.|
/// |[[`iter().for_each()`][`for_each`]\[[`iter_mut().for_each()`][`for_each`]],<br>[`par_iter`]\[[`_mut`][`par_iter_mut`]]|Runs a specified function for each query item.| /// |[`iter[_mut]().for_each()`][`for_each`],<br />[`par_iter`]\[[`_mut`][`par_iter_mut`]\]|Runs a specified function for each query item.|
/// |[`iter_many`]\[[`_mut`][`iter_many_mut`]]|Iterates or runs a specified function over query items generated by a list of entities.| /// |[`iter_many`]\[[`_unique`][`iter_many_unique`]\]\[[`_mut`][`iter_many_mut`]\]|Iterates over query items that match a list of entities.|
/// |[`iter_combinations`]\[[`_mut`][`iter_combinations_mut`]]|Returns an iterator over all combinations of a specified number of query items.| /// |[`iter_combinations`]\[[`_mut`][`iter_combinations_mut`]\]|Iterates over all combinations of query items.|
/// |[`get`]\[[`_mut`][`get_mut`]]|Returns the query item for the specified entity.| /// |[`single`](Self::single)\[[`_mut`][`single_mut`]\]|Returns a single query item if only one exists.|
/// |[`many`]\[[`_mut`][`many_mut`]],<br>[`get_many`]\[[`_mut`][`get_many_mut`]]|Returns the query items for the specified entities.| /// |[`get`]\[[`_mut`][`get_mut`]\]|Returns the query item for a specified entity.|
/// |[`single`]\[[`_mut`][`single_mut`]],<br>[`single`]\[[`_mut`][`single_mut`]]|Returns the query item while verifying that there aren't others.| /// |[`get_many`]\[[`_unique`][`get_many_unique`]\]\[[`_mut`][`get_many_mut`]\]|Returns all query items that match a list of entities.|
/// ///
/// There are two methods for each type of query operation: immutable and mutable (ending with `_mut`). /// There are two methods for each type of query operation: immutable and mutable (ending with `_mut`).
/// When using immutable methods, the query items returned are of type [`ROQueryItem`], a read-only version of the query item. /// When using immutable methods, the query items returned are of type [`ROQueryItem`], a read-only version of the query item.
/// In this circumstance, every mutable reference in the query fetch type parameter is substituted by a shared reference. /// In this circumstance, every mutable reference in the query fetch type parameter is substituted by a shared reference.
/// ///
/// [`iter`]: Self::iter
/// [`iter_mut`]: Self::iter_mut
/// [`for_each`]: #iteratorfor_each
/// [`par_iter`]: Self::par_iter
/// [`par_iter_mut`]: Self::par_iter_mut
/// [`iter_many`]: Self::iter_many
/// [`iter_many_unique`]: Self::iter_many_unique
/// [`iter_many_mut`]: Self::iter_many_mut
/// [`iter_combinations`]: Self::iter_combinations
/// [`iter_combinations_mut`]: Self::iter_combinations_mut
/// [`single_mut`]: Self::single_mut
/// [`get`]: Self::get
/// [`get_mut`]: Self::get_mut
/// [`get_many`]: Self::get_many
/// [`get_many_unique`]: Self::get_many_unique
/// [`get_many_mut`]: Self::get_many_mut
///
/// # Performance /// # Performance
/// ///
/// Creating a `Query` is a low-cost constant operation. /// Creating a `Query` is a low-cost constant operation. Iterating it, on the other hand, fetches
/// Iterating it, on the other hand, fetches data from the world and generates items, which can have a significant computational cost. /// data from the world and generates items, which can have a significant computational cost.
/// ///
/// [`Table`] component storage type is much more optimized for query iteration than [`SparseSet`]. /// Two systems cannot be executed in parallel if both access the same component type where at
/// least one of the accesses is mutable. Because of this, it is recommended for queries to only
/// fetch mutable access to components when necessary, since immutable access can be parallelized.
/// ///
/// Two systems cannot be executed in parallel if both access the same component type where at least one of the accesses is mutable. /// Query filters ([`With`] / [`Without`]) can improve performance because they narrow the kinds of
/// This happens unless the executor can verify that no entity could be found in both queries. /// entities that can be fetched. Systems that access fewer kinds of entities are more likely to be
/// parallelized by the scheduler.
/// ///
/// Optional components increase the number of entities a query has to match against. /// On the other hand, be careful using optional components (`Option<&ComponentA>`) and
/// This can hurt iteration performance, especially if the query solely consists of only optional components, since the query would iterate over each entity in the world. /// [`EntityRef`] because they broaden the amount of entities kinds that can be accessed. This is
/// especially true of a query that _only_ fetches optional components or [`EntityRef`], as the
/// query would iterate over all entities in the world.
/// ///
/// The following table compares the computational complexity of the various methods and operations, where: /// There are two types of [component storage types]: [`Table`] and [`SparseSet`]. [`Table`] offers
/// fast iteration speeds, but slower insertion and removal speeds. [`SparseSet`] is the opposite:
/// it offers fast component insertion and removal speeds, but slower iteration speeds.
/// ///
/// - **n** is the number of entities that match the query, /// The following table compares the computational complexity of the various methods and
/// - **r** is the number of elements in a combination, /// operations, where:
/// - **k** is the number of involved entities in the operation, ///
/// - **a** is the number of archetypes in the world, /// - **n** is the number of entities that match the query.
/// - **C** is the [binomial coefficient], used to count combinations. /// - **r** is the number of elements in a combination.
/// <sub>n</sub>C<sub>r</sub> is read as "*n* choose *r*" and is equivalent to the number of distinct unordered subsets of *r* elements that can be taken from a set of *n* elements. /// - **k** is the number of involved entities in the operation.
/// - **a** is the number of archetypes in the world.
/// - **C** is the [binomial coefficient], used to count combinations. <sub>n</sub>C<sub>r</sub> is
/// read as "*n* choose *r*" and is equivalent to the number of distinct unordered subsets of *r*
/// elements that can be taken from a set of *n* elements.
/// ///
/// |Query operation|Computational complexity| /// |Query operation|Computational complexity|
/// |:---:|:---:| /// |-|-|
/// |[`iter`]\[[`_mut`][`iter_mut`]]|O(n)| /// |[`iter`]\[[`_mut`][`iter_mut`]\]|O(n)|
/// |[[`iter().for_each()`][`for_each`]\[[`iter_mut().for_each()`][`for_each`]],<br>[`par_iter`]\[[`_mut`][`par_iter_mut`]]|O(n)| /// |[`iter[_mut]().for_each()`][`for_each`],<br/>[`par_iter`]\[[`_mut`][`par_iter_mut`]\]|O(n)|
/// |[`iter_many`]\[[`_mut`][`iter_many_mut`]]|O(k)| /// |[`iter_many`]\[[`_mut`][`iter_many_mut`]\]|O(k)|
/// |[`iter_combinations`]\[[`_mut`][`iter_combinations_mut`]]|O(<sub>n</sub>C<sub>r</sub>)| /// |[`iter_combinations`]\[[`_mut`][`iter_combinations_mut`]\]|O(<sub>n</sub>C<sub>r</sub>)|
/// |[`get`]\[[`_mut`][`get_mut`]]|O(1)| /// |[`single`](Self::single)\[[`_mut`][`single_mut`]\]|O(a)|
/// |([`get_`][`get_many`])[`many`]|O(k)| /// |[`get`]\[[`_mut`][`get_mut`]\]|O(1)|
/// |([`get_`][`get_many_mut`])[`many_mut`]|O(k<sup>2</sup>)| /// |[`get_many`]|O(k)|
/// |[`single`]\[[`_mut`][`single_mut`]],<br>[`single`]\[[`_mut`][`single_mut`]]|O(a)| /// |[`get_many_mut`]|O(k<sup>2</sup>)|
/// |Archetype based filtering ([`With`], [`Without`], [`Or`])|O(a)| /// |Archetype-based filtering ([`With`], [`Without`], [`Or`])|O(a)|
/// |Change detection filtering ([`Added`], [`Changed`])|O(a + n)| /// |Change detection filtering ([`Added`], [`Changed`])|O(a + n)|
/// ///
/// [component storage types]: crate::component::StorageType
/// [`Table`]: crate::storage::Table
/// [`SparseSet`]: crate::storage::SparseSet
/// [binomial coefficient]: https://en.wikipedia.org/wiki/Binomial_coefficient
/// [`Or`]: crate::query::Or
/// [`Added`]: crate::query::Added
/// [`Changed`]: crate::query::Changed
///
/// # `Iterator::for_each` /// # `Iterator::for_each`
/// ///
/// `for_each` methods are seen to be generally faster than directly iterating through `iter` on worlds with high archetype /// The `for_each` methods appear to be generally faster than `for`-loops when run on worlds with
/// fragmentation, and may enable additional optimizations like [autovectorization]. It is strongly advised to only use /// high archetype fragmentation, and may enable additional optimizations like [autovectorization]. It
/// [`Iterator::for_each`] if it tangibly improves performance. *Always* be sure profile or benchmark both before and /// is strongly advised to only use [`Iterator::for_each`] if it tangibly improves performance.
/// after the change! /// *Always* profile or benchmark before and after the change!
/// ///
/// ```rust /// ```rust
/// # use bevy_ecs::prelude::*; /// # use bevy_ecs::prelude::*;
/// #
/// # #[derive(Component)] /// # #[derive(Component)]
/// # struct ComponentA; /// # struct ComponentA;
/// # fn system( /// #
/// # query: Query<&ComponentA>, /// fn system(query: Query<&ComponentA>) {
/// # ) { /// // This may result in better performance...
/// // This might be result in better performance...
/// query.iter().for_each(|component| { /// query.iter().for_each(|component| {
/// // do things with the component /// // ...
/// }); /// });
/// // ...than this. Always be sure to benchmark to validate the difference! ///
/// // ...than this. Always benchmark to validate the difference!
/// for component in query.iter() { /// for component in query.iter() {
/// // do things with the component /// // ...
/// } /// }
/// # } /// }
/// # bevy_ecs::system::assert_system_does_not_conflict(system); /// #
/// # bevy_ecs::system::assert_is_system(system);
/// ``` /// ```
/// ///
/// [`Component`]: crate::component::Component
/// [autovectorization]: https://en.wikipedia.org/wiki/Automatic_vectorization /// [autovectorization]: https://en.wikipedia.org/wiki/Automatic_vectorization
/// [`Added`]: crate::query::Added
/// [`AnyOf`]: crate::query::AnyOf
/// [binomial coefficient]: https://en.wikipedia.org/wiki/Binomial_coefficient
/// [`Changed`]: crate::query::Changed
/// [components]: crate::component::Component
/// [entity identifiers]: Entity
/// [`EntityRef`]: crate::world::EntityRef
/// [`for_each`]: #iterator-for-each
/// [`get`]: Self::get
/// [`get_many`]: Self::get_many
/// [`get_many_mut`]: Self::get_many_mut
/// [`get_mut`]: Self::get_mut
/// [`single`]: Self::single
/// [`single_mut`]: Self::single_mut
/// [`iter`]: Self::iter
/// [`iter_combinations`]: Self::iter_combinations
/// [`iter_combinations_mut`]: Self::iter_combinations_mut
/// [`iter_many`]: Self::iter_many
/// [`iter_many_mut`]: Self::iter_many_mut
/// [`iter_mut`]: Self::iter_mut
/// [`many`]: Self::many
/// [`many_mut`]: Self::many_mut
/// [`Or`]: crate::query::Or
/// [`par_iter`]: Self::par_iter
/// [`par_iter_mut`]: Self::par_iter_mut
/// [performance]: #performance
/// [`Single`]: Single
/// [`Option<Single>`]: Single
/// [`single`]: Self::single
/// [`single_mut`]: Self::single_mut
/// [`SparseSet`]: crate::storage::SparseSet
/// [System parameter]: crate::system::SystemParam
/// [`Table`]: crate::storage::Table
/// [`With`]: crate::query::With
/// [`Without`]: crate::query::Without
pub struct Query<'world, 'state, D: QueryData, F: QueryFilter = ()> { pub struct Query<'world, 'state, D: QueryData, F: QueryFilter = ()> {
// SAFETY: Must have access to the components registered in `state`. // SAFETY: Must have access to the components registered in `state`.
world: UnsafeWorldCell<'world>, world: UnsafeWorldCell<'world>,