
# 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>
2795 lines
104 KiB
Rust
2795 lines
104 KiB
Rust
use crate::{
|
|
batching::BatchingStrategy,
|
|
component::Tick,
|
|
entity::{Entity, EntityDoesNotExistError, EntityEquivalent, EntitySet, UniqueEntityArray},
|
|
query::{
|
|
DebugCheckedUnwrap, NopWorldQuery, QueryCombinationIter, QueryData, QueryEntityError,
|
|
QueryFilter, QueryIter, QueryManyIter, QueryManyUniqueIter, QueryParIter, QueryParManyIter,
|
|
QueryParManyUniqueIter, QuerySingleError, QueryState, ROQueryItem, ReadOnlyQueryData,
|
|
},
|
|
world::unsafe_world_cell::UnsafeWorldCell,
|
|
};
|
|
use core::{
|
|
marker::PhantomData,
|
|
mem::MaybeUninit,
|
|
ops::{Deref, DerefMut},
|
|
};
|
|
|
|
/// A [system parameter] that provides selective access to the [`Component`] data stored in a [`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*, which are types containing data related to an entity.
|
|
///
|
|
/// `Query` is a generic data structure that accepts two type parameters:
|
|
///
|
|
/// - **`D` (query data)**:
|
|
/// 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.
|
|
/// Must implement the [`QueryData`] trait.
|
|
/// - **`F` (query filter)**:
|
|
/// 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.
|
|
///
|
|
/// [system parameter]: crate::system::SystemParam
|
|
/// [`Component`]: crate::component::Component
|
|
/// [`World`]: crate::world::World
|
|
/// [entity identifiers]: Entity
|
|
/// [components]: crate::component::Component
|
|
///
|
|
/// # Similar parameters
|
|
///
|
|
/// `Query` has few sibling [`SystemParam`]s, which perform additional validation:
|
|
///
|
|
/// - [`Single`] - Exactly one matching query item.
|
|
/// - [`Option<Single>`] - Zero or one matching query item.
|
|
/// - [`Populated`] - At least one matching query item.
|
|
///
|
|
/// 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
|
|
///
|
|
/// A query should always be declared as a system parameter.
|
|
/// This section shows the most common idioms involving the declaration of `Query`.
|
|
///
|
|
/// ## Component access
|
|
///
|
|
/// You can fetch an entity's component by specifying a reference to that component in the query's data parameter:
|
|
///
|
|
/// ```
|
|
/// # use bevy_ecs::prelude::*;
|
|
/// #
|
|
/// # #[derive(Component)]
|
|
/// # struct ComponentA;
|
|
/// #
|
|
/// // A component can be accessed by a shared reference...
|
|
/// fn immutable_query(query: Query<&ComponentA>) {
|
|
/// // ...
|
|
/// }
|
|
///
|
|
/// // ...or by a mutable reference.
|
|
/// fn mutable_query(query: Query<&mut ComponentA>) {
|
|
/// // ...
|
|
/// }
|
|
/// #
|
|
/// # 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
|
|
///
|
|
/// Setting the query filter type parameter will ensure that each query item satisfies the given condition:
|
|
///
|
|
/// ```
|
|
/// # use bevy_ecs::prelude::*;
|
|
/// #
|
|
/// # #[derive(Component)]
|
|
/// # struct ComponentA;
|
|
/// #
|
|
/// # #[derive(Component)]
|
|
/// # struct ComponentB;
|
|
/// #
|
|
/// // `ComponentA` data will be accessed, but only for entities that also contain `ComponentB`.
|
|
/// fn filtered_query(query: Query<&ComponentA, With<ComponentB>>) {
|
|
/// // ...
|
|
/// }
|
|
/// #
|
|
/// # 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
|
|
///
|
|
/// 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:
|
|
///
|
|
/// ```
|
|
/// # use bevy_ecs::prelude::*;
|
|
/// #
|
|
/// # #[derive(Component)]
|
|
/// # struct ComponentA;
|
|
/// #
|
|
/// # #[derive(Component)]
|
|
/// # struct ComponentB;
|
|
/// #
|
|
/// # #[derive(Component)]
|
|
/// # struct ComponentC;
|
|
/// #
|
|
/// # #[derive(Component)]
|
|
/// # struct ComponentD;
|
|
/// #
|
|
/// fn complex_query(
|
|
/// query: Query<(&mut ComponentA, &ComponentB), (With<ComponentC>, Without<ComponentD>)>
|
|
/// ) {
|
|
/// // ...
|
|
/// }
|
|
/// #
|
|
/// # 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
|
|
///
|
|
/// You can access [`Entity`], the entity identifier, by including it in the query data parameter:
|
|
///
|
|
/// ```
|
|
/// # use bevy_ecs::prelude::*;
|
|
/// #
|
|
/// # #[derive(Component)]
|
|
/// # struct ComponentA;
|
|
/// #
|
|
/// fn entity_id_query(query: Query<(Entity, &ComponentA)>) {
|
|
/// // ...
|
|
/// }
|
|
/// #
|
|
/// # 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
|
|
///
|
|
/// A component can be made optional by wrapping it into an [`Option`]. In the following example, a
|
|
/// query item will still be generated even if the queried entity does not contain `ComponentB`.
|
|
/// When this is the case, `Option<&ComponentB>`'s corresponding value will be `None`.
|
|
///
|
|
/// ```
|
|
/// # use bevy_ecs::prelude::*;
|
|
/// #
|
|
/// # #[derive(Component)]
|
|
/// # struct ComponentA;
|
|
/// #
|
|
/// # #[derive(Component)]
|
|
/// # struct ComponentB;
|
|
/// #
|
|
/// // A queried items must contain `ComponentA`. If they also contain `ComponentB`, its value will
|
|
/// // be fetched as well.
|
|
/// fn optional_component_query(query: Query<(&ComponentA, Option<&ComponentB>)>) {
|
|
/// // ...
|
|
/// }
|
|
/// #
|
|
/// # bevy_ecs::system::assert_is_system(optional_component_query);
|
|
/// ```
|
|
///
|
|
/// 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`].
|
|
///
|
|
/// [performance]: #performance
|
|
/// [`AnyOf`]: crate::query::AnyOf
|
|
///
|
|
/// ## Disjoint queries
|
|
///
|
|
/// A system cannot contain two queries that break Rust's mutability rules, or else it will panic
|
|
/// when initialized. This can often be fixed with the [`Without`] filter, which makes the queries
|
|
/// disjoint.
|
|
///
|
|
/// In the following example, the two queries can mutably access the same `&mut Health` component
|
|
/// if an entity has both the `Player` and `Enemy` components. Bevy will catch this and panic,
|
|
/// however, instead of breaking Rust's mutability rules:
|
|
///
|
|
/// ```should_panic
|
|
/// # use bevy_ecs::prelude::*;
|
|
/// #
|
|
/// # #[derive(Component)]
|
|
/// # struct Health;
|
|
/// #
|
|
/// # #[derive(Component)]
|
|
/// # struct Player;
|
|
/// #
|
|
/// # #[derive(Component)]
|
|
/// # struct Enemy;
|
|
/// #
|
|
/// fn randomize_health(
|
|
/// player_query: Query<&mut Health, With<Player>>,
|
|
/// enemy_query: Query<&mut Health, With<Enemy>>,
|
|
/// ) {
|
|
/// // ...
|
|
/// }
|
|
/// #
|
|
/// # bevy_ecs::system::assert_system_does_not_conflict(randomize_health);
|
|
/// ```
|
|
///
|
|
/// Adding a [`Without`] filter will disjoint the queries. In the following example, any entity
|
|
/// that has both the `Player` and `Enemy` components will be excluded from _both_ queries:
|
|
///
|
|
/// ```
|
|
/// # use bevy_ecs::prelude::*;
|
|
/// #
|
|
/// # #[derive(Component)]
|
|
/// # struct Health;
|
|
/// #
|
|
/// # #[derive(Component)]
|
|
/// # struct Player;
|
|
/// #
|
|
/// # #[derive(Component)]
|
|
/// # struct Enemy;
|
|
/// #
|
|
/// fn randomize_health(
|
|
/// player_query: Query<&mut Health, (With<Player>, Without<Enemy>)>,
|
|
/// enemy_query: Query<&mut Health, (With<Enemy>, Without<Player>)>,
|
|
/// ) {
|
|
/// // ...
|
|
/// }
|
|
/// #
|
|
/// # bevy_ecs::system::assert_system_does_not_conflict(randomize_health);
|
|
/// ```
|
|
///
|
|
/// 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
|
|
///
|
|
/// [`EntityRef`] can be used in a query to gain read-only access to all components of an entity.
|
|
/// This is useful when dynamically fetching components instead of baking them into the query type.
|
|
///
|
|
/// ```
|
|
/// # use bevy_ecs::prelude::*;
|
|
/// #
|
|
/// # #[derive(Component)]
|
|
/// # struct ComponentA;
|
|
/// #
|
|
/// fn all_components_query(query: Query<(EntityRef, &ComponentA)>) {
|
|
/// // ...
|
|
/// }
|
|
/// #
|
|
/// # 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 component access.
|
|
///
|
|
/// ```should_panic
|
|
/// # use bevy_ecs::prelude::*;
|
|
/// #
|
|
/// # #[derive(Component)]
|
|
/// # struct ComponentA;
|
|
/// #
|
|
/// // `EntityRef` provides read access to *all* components on an entity. When combined with
|
|
/// // `&mut ComponentA` in the same query, it creates a conflict because `EntityRef` could read
|
|
/// // `&ComponentA` while `&mut ComponentA` attempts to modify it - violating Rust's borrowing
|
|
/// // rules.
|
|
/// fn invalid_query(query: Query<(EntityRef, &mut ComponentA)>) {
|
|
/// // ...
|
|
/// }
|
|
/// #
|
|
/// # 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::*;
|
|
/// #
|
|
/// # #[derive(Component)]
|
|
/// # struct ComponentA;
|
|
/// #
|
|
/// # #[derive(Component)]
|
|
/// # struct ComponentB;
|
|
/// #
|
|
/// // The first query only reads entities that have `ComponentA`, while the second query only
|
|
/// // modifies entities that *don't* have `ComponentA`. Because neither query will access the same
|
|
/// // entity, this system does not conflict.
|
|
/// fn disjoint_query(
|
|
/// query_a: Query<EntityRef, With<ComponentA>>,
|
|
/// query_b: Query<&mut ComponentB, Without<ComponentA>>,
|
|
/// ) {
|
|
/// // ...
|
|
/// }
|
|
/// #
|
|
/// # bevy_ecs::system::assert_system_does_not_conflict(disjoint_query);
|
|
/// ```
|
|
///
|
|
/// The fundamental rule: [`EntityRef`]'s ability to read all components means it can never
|
|
/// coexist with mutable access. [`With`] / [`Without`] filters can guarantee this by keeping the
|
|
/// queries on completely separate entities.
|
|
///
|
|
/// [`EntityRef`]: crate::world::EntityRef
|
|
/// [`With`]: crate::query::With
|
|
///
|
|
/// # Accessing query items
|
|
///
|
|
/// The following table summarizes the behavior of safe methods that can be used to get query
|
|
/// items:
|
|
///
|
|
/// |Query methods|Effect|
|
|
/// |-|-|
|
|
/// |[`iter`]\[[`_mut`][`iter_mut`]\]|Returns an iterator over all query items.|
|
|
/// |[`iter[_mut]().for_each()`][`for_each`],<br />[`par_iter`]\[[`_mut`][`par_iter_mut`]\]|Runs a specified function for each query item.|
|
|
/// |[`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`]\]|Iterates over all combinations of query items.|
|
|
/// |[`single`](Self::single)\[[`_mut`][`single_mut`]\]|Returns a single query item if only one exists.|
|
|
/// |[`get`]\[[`_mut`][`get_mut`]\]|Returns the query item for a specified entity.|
|
|
/// |[`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`).
|
|
/// 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.
|
|
///
|
|
/// [`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
|
|
///
|
|
/// Creating a `Query` is a low-cost constant operation. Iterating it, on the other hand, fetches
|
|
/// data from the world and generates items, which can have a significant computational cost.
|
|
///
|
|
/// 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.
|
|
///
|
|
/// Query filters ([`With`] / [`Without`]) can improve performance because they narrow the kinds of
|
|
/// entities that can be fetched. Systems that access fewer kinds of entities are more likely to be
|
|
/// parallelized by the scheduler.
|
|
///
|
|
/// On the other hand, be careful using optional components (`Option<&ComponentA>`) and
|
|
/// [`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.
|
|
///
|
|
/// 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.
|
|
///
|
|
/// The following table compares the computational complexity of the various methods and
|
|
/// operations, where:
|
|
///
|
|
/// - **n** is the number of entities that match the query.
|
|
/// - **r** is the number of elements in a combination.
|
|
/// - **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|
|
|
/// |-|-|
|
|
/// |[`iter`]\[[`_mut`][`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_combinations`]\[[`_mut`][`iter_combinations_mut`]\]|O(<sub>n</sub>C<sub>r</sub>)|
|
|
/// |[`single`](Self::single)\[[`_mut`][`single_mut`]\]|O(a)|
|
|
/// |[`get`]\[[`_mut`][`get_mut`]\]|O(1)|
|
|
/// |[`get_many`]|O(k)|
|
|
/// |[`get_many_mut`]|O(k<sup>2</sup>)|
|
|
/// |Archetype-based filtering ([`With`], [`Without`], [`Or`])|O(a)|
|
|
/// |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`
|
|
///
|
|
/// The `for_each` methods appear to be generally faster than `for`-loops when run on worlds with
|
|
/// high archetype fragmentation, and may enable additional optimizations like [autovectorization]. It
|
|
/// is strongly advised to only use [`Iterator::for_each`] if it tangibly improves performance.
|
|
/// *Always* profile or benchmark before and after the change!
|
|
///
|
|
/// ```rust
|
|
/// # use bevy_ecs::prelude::*;
|
|
/// #
|
|
/// # #[derive(Component)]
|
|
/// # struct ComponentA;
|
|
/// #
|
|
/// fn system(query: Query<&ComponentA>) {
|
|
/// // This may result in better performance...
|
|
/// query.iter().for_each(|component| {
|
|
/// // ...
|
|
/// });
|
|
///
|
|
/// // ...than this. Always benchmark to validate the difference!
|
|
/// for component in query.iter() {
|
|
/// // ...
|
|
/// }
|
|
/// }
|
|
/// #
|
|
/// # bevy_ecs::system::assert_is_system(system);
|
|
/// ```
|
|
///
|
|
/// [autovectorization]: https://en.wikipedia.org/wiki/Automatic_vectorization
|
|
pub struct Query<'world, 'state, D: QueryData, F: QueryFilter = ()> {
|
|
// SAFETY: Must have access to the components registered in `state`.
|
|
world: UnsafeWorldCell<'world>,
|
|
state: &'state QueryState<D, F>,
|
|
last_run: Tick,
|
|
this_run: Tick,
|
|
}
|
|
|
|
impl<D: ReadOnlyQueryData, F: QueryFilter> Clone for Query<'_, '_, D, F> {
|
|
fn clone(&self) -> Self {
|
|
*self
|
|
}
|
|
}
|
|
|
|
impl<D: ReadOnlyQueryData, F: QueryFilter> Copy for Query<'_, '_, D, F> {}
|
|
|
|
impl<D: QueryData, F: QueryFilter> core::fmt::Debug for Query<'_, '_, D, F> {
|
|
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
|
|
f.debug_struct("Query")
|
|
.field("matched_entities", &self.iter().count())
|
|
.field("state", &self.state)
|
|
.field("last_run", &self.last_run)
|
|
.field("this_run", &self.this_run)
|
|
.field("world", &self.world)
|
|
.finish()
|
|
}
|
|
}
|
|
|
|
impl<'w, 's, D: QueryData, F: QueryFilter> Query<'w, 's, D, F> {
|
|
/// Creates a new query.
|
|
///
|
|
/// # Safety
|
|
///
|
|
/// * This will create a query that could violate memory safety rules. Make sure that this is only
|
|
/// called in ways that ensure the queries have unique mutable access.
|
|
/// * `world` must be the world used to create `state`.
|
|
#[inline]
|
|
pub(crate) unsafe fn new(
|
|
world: UnsafeWorldCell<'w>,
|
|
state: &'s QueryState<D, F>,
|
|
last_run: Tick,
|
|
this_run: Tick,
|
|
) -> Self {
|
|
Self {
|
|
world,
|
|
state,
|
|
last_run,
|
|
this_run,
|
|
}
|
|
}
|
|
|
|
/// Returns another `Query` from this that fetches the read-only version of the query items.
|
|
///
|
|
/// For example, `Query<(&mut D1, &D2, &mut D3), With<F>>` will become `Query<(&D1, &D2, &D3), With<F>>`.
|
|
/// This can be useful when working around the borrow checker,
|
|
/// or reusing functionality between systems via functions that accept query types.
|
|
///
|
|
/// # See also
|
|
///
|
|
/// [`into_readonly`](Self::into_readonly) for a version that consumes the `Query` to return one with the full `'world` lifetime.
|
|
pub fn as_readonly(&self) -> Query<'_, 's, D::ReadOnly, F> {
|
|
// SAFETY: The reborrowed query is converted to read-only, so it cannot perform mutable access,
|
|
// and the original query is held with a shared borrow, so it cannot perform mutable access either.
|
|
unsafe { self.reborrow_unsafe() }.into_readonly()
|
|
}
|
|
|
|
/// Returns another `Query` from this does not return any data, which can be faster.
|
|
fn as_nop(&self) -> Query<'_, 's, NopWorldQuery<D>, F> {
|
|
let new_state = self.state.as_nop();
|
|
// SAFETY:
|
|
// - The reborrowed query is converted to read-only, so it cannot perform mutable access,
|
|
// and the original query is held with a shared borrow, so it cannot perform mutable access either.
|
|
// Note that although `NopWorldQuery` itself performs *no* access and could soundly alias a mutable query,
|
|
// it has the original `QueryState::component_access` and could be `transmute`d to a read-only query.
|
|
// - The world matches because it was the same one used to construct self.
|
|
unsafe { Query::new(self.world, new_state, self.last_run, self.this_run) }
|
|
}
|
|
|
|
/// Returns another `Query` from this that fetches the read-only version of the query items.
|
|
///
|
|
/// For example, `Query<(&mut D1, &D2, &mut D3), With<F>>` will become `Query<(&D1, &D2, &D3), With<F>>`.
|
|
/// This can be useful when working around the borrow checker,
|
|
/// or reusing functionality between systems via functions that accept query types.
|
|
///
|
|
/// # See also
|
|
///
|
|
/// [`as_readonly`](Self::as_readonly) for a version that borrows the `Query` instead of consuming it.
|
|
pub fn into_readonly(self) -> Query<'w, 's, D::ReadOnly, F> {
|
|
let new_state = self.state.as_readonly();
|
|
// SAFETY:
|
|
// - This is memory safe because it turns the query immutable.
|
|
// - The world matches because it was the same one used to construct self.
|
|
unsafe { Query::new(self.world, new_state, self.last_run, self.this_run) }
|
|
}
|
|
|
|
/// Returns a new `Query` reborrowing the access from this one. The current query will be unusable
|
|
/// while the new one exists.
|
|
///
|
|
/// # Example
|
|
///
|
|
/// For example this allows to call other methods or other systems that require an owned `Query` without
|
|
/// completely giving up ownership of it.
|
|
///
|
|
/// ```
|
|
/// # use bevy_ecs::prelude::*;
|
|
/// #
|
|
/// # #[derive(Component)]
|
|
/// # struct ComponentA;
|
|
///
|
|
/// fn helper_system(query: Query<&ComponentA>) { /* ... */}
|
|
///
|
|
/// fn system(mut query: Query<&ComponentA>) {
|
|
/// helper_system(query.reborrow());
|
|
/// // Can still use query here:
|
|
/// for component in &query {
|
|
/// // ...
|
|
/// }
|
|
/// }
|
|
/// ```
|
|
pub fn reborrow(&mut self) -> Query<'_, 's, D, F> {
|
|
// SAFETY: this query is exclusively borrowed while the new one exists, so
|
|
// no overlapping access can occur.
|
|
unsafe { self.reborrow_unsafe() }
|
|
}
|
|
|
|
/// Returns a new `Query` reborrowing the access from this one.
|
|
/// The current query will still be usable while the new one exists, but must not be used in a way that violates aliasing.
|
|
///
|
|
/// # Safety
|
|
///
|
|
/// This function makes it possible to violate Rust's aliasing guarantees.
|
|
/// You must make sure this call does not result in a mutable or shared reference to a component with a mutable reference.
|
|
///
|
|
/// # See also
|
|
///
|
|
/// - [`reborrow`](Self::reborrow) for the safe versions.
|
|
pub unsafe fn reborrow_unsafe(&self) -> Query<'_, 's, D, F> {
|
|
// SAFETY:
|
|
// - This is memory safe because the caller ensures that there are no conflicting references.
|
|
// - The world matches because it was the same one used to construct self.
|
|
unsafe { self.copy_unsafe() }
|
|
}
|
|
|
|
/// Returns a new `Query` copying the access from this one.
|
|
/// The current query will still be usable while the new one exists, but must not be used in a way that violates aliasing.
|
|
///
|
|
/// # Safety
|
|
///
|
|
/// This function makes it possible to violate Rust's aliasing guarantees.
|
|
/// You must make sure this call does not result in a mutable or shared reference to a component with a mutable reference.
|
|
///
|
|
/// # See also
|
|
///
|
|
/// - [`reborrow_unsafe`](Self::reborrow_unsafe) for a safer version that constrains the returned `'w` lifetime to the length of the borrow.
|
|
unsafe fn copy_unsafe(&self) -> Query<'w, 's, D, F> {
|
|
// SAFETY:
|
|
// - This is memory safe because the caller ensures that there are no conflicting references.
|
|
// - The world matches because it was the same one used to construct self.
|
|
unsafe { Query::new(self.world, self.state, self.last_run, self.this_run) }
|
|
}
|
|
|
|
/// 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:
|
|
///
|
|
/// ```
|
|
/// # use bevy_ecs::prelude::*;
|
|
/// #
|
|
/// # #[derive(Component)]
|
|
/// # struct Player { name: String }
|
|
/// #
|
|
/// fn report_names_system(query: Query<&Player>) {
|
|
/// for player in &query {
|
|
/// println!("Say hello to {}!", player.name);
|
|
/// }
|
|
/// }
|
|
/// # bevy_ecs::system::assert_is_system(report_names_system);
|
|
/// ```
|
|
///
|
|
/// # See also
|
|
///
|
|
/// [`iter_mut`](Self::iter_mut) for mutable query items.
|
|
#[inline]
|
|
pub fn iter(&self) -> QueryIter<'_, 's, D::ReadOnly, F> {
|
|
self.as_readonly().into_iter()
|
|
}
|
|
|
|
/// 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:
|
|
///
|
|
/// ```
|
|
/// # use bevy_ecs::prelude::*;
|
|
/// #
|
|
/// # #[derive(Component)]
|
|
/// # struct Velocity { x: f32, y: f32, z: f32 }
|
|
/// fn gravity_system(mut query: Query<&mut Velocity>) {
|
|
/// const DELTA: f32 = 1.0 / 60.0;
|
|
/// for mut velocity in &mut query {
|
|
/// velocity.y -= 9.8 * DELTA;
|
|
/// }
|
|
/// }
|
|
/// # bevy_ecs::system::assert_is_system(gravity_system);
|
|
/// ```
|
|
///
|
|
/// # See also
|
|
///
|
|
/// [`iter`](Self::iter) for read-only query items.
|
|
#[inline]
|
|
pub fn iter_mut(&mut self) -> QueryIter<'_, 's, D, F> {
|
|
self.reborrow().into_iter()
|
|
}
|
|
|
|
/// 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
|
|
///
|
|
/// ```
|
|
/// # use bevy_ecs::prelude::*;
|
|
/// # #[derive(Component)]
|
|
/// # struct ComponentA;
|
|
/// #
|
|
/// fn some_system(query: Query<&ComponentA>) {
|
|
/// for [a1, a2] in query.iter_combinations() {
|
|
/// // ...
|
|
/// }
|
|
/// }
|
|
/// ```
|
|
///
|
|
/// # See also
|
|
///
|
|
/// - [`iter_combinations_mut`](Self::iter_combinations_mut) for mutable query item combinations.
|
|
/// - [`iter_combinations_inner`](Self::iter_combinations_inner) for mutable query item combinations with the full `'world` lifetime.
|
|
#[inline]
|
|
pub fn iter_combinations<const K: usize>(
|
|
&self,
|
|
) -> QueryCombinationIter<'_, 's, D::ReadOnly, F, K> {
|
|
self.as_readonly().iter_combinations_inner()
|
|
}
|
|
|
|
/// 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
|
|
///
|
|
/// ```
|
|
/// # use bevy_ecs::prelude::*;
|
|
/// # #[derive(Component)]
|
|
/// # struct ComponentA;
|
|
/// fn some_system(mut query: Query<&mut ComponentA>) {
|
|
/// let mut combinations = query.iter_combinations_mut();
|
|
/// while let Some([mut a1, mut a2]) = combinations.fetch_next() {
|
|
/// // mutably access components data
|
|
/// }
|
|
/// }
|
|
/// ```
|
|
///
|
|
/// # See also
|
|
///
|
|
/// - [`iter_combinations`](Self::iter_combinations) for read-only query item combinations.
|
|
/// - [`iter_combinations_inner`](Self::iter_combinations_inner) for mutable query item combinations with the full `'world` lifetime.
|
|
#[inline]
|
|
pub fn iter_combinations_mut<const K: usize>(
|
|
&mut self,
|
|
) -> QueryCombinationIter<'_, 's, D, F, K> {
|
|
self.reborrow().iter_combinations_inner()
|
|
}
|
|
|
|
/// Returns a [`QueryCombinationIter`] over all combinations of `K` query items without repetition.
|
|
/// This consumes the [`Query`] to return results with the actual "inner" world lifetime.
|
|
///
|
|
/// This iterator is always guaranteed to return results from each unique pair of matching entities.
|
|
/// Iteration order is not guaranteed.
|
|
///
|
|
/// # Example
|
|
///
|
|
/// ```
|
|
/// # use bevy_ecs::prelude::*;
|
|
/// # #[derive(Component)]
|
|
/// # struct ComponentA;
|
|
/// fn some_system(query: Query<&mut ComponentA>) {
|
|
/// let mut combinations = query.iter_combinations_inner();
|
|
/// while let Some([mut a1, mut a2]) = combinations.fetch_next() {
|
|
/// // mutably access components data
|
|
/// }
|
|
/// }
|
|
/// ```
|
|
///
|
|
/// # See also
|
|
///
|
|
/// - [`iter_combinations`](Self::iter_combinations) for read-only query item combinations.
|
|
/// - [`iter_combinations_mut`](Self::iter_combinations_mut) for mutable query item combinations.
|
|
#[inline]
|
|
pub fn iter_combinations_inner<const K: usize>(self) -> QueryCombinationIter<'w, 's, D, F, K> {
|
|
// SAFETY: `self.world` has permission to access the required components.
|
|
unsafe { QueryCombinationIter::new(self.world, self.state, self.last_run, self.this_run) }
|
|
}
|
|
|
|
/// 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, and may not be unique if the input
|
|
/// doesn't guarantee uniqueness. Entities that don't match the query are skipped.
|
|
///
|
|
/// # Example
|
|
///
|
|
/// ```
|
|
/// # use bevy_ecs::prelude::*;
|
|
/// # #[derive(Component)]
|
|
/// # struct Counter {
|
|
/// # value: i32
|
|
/// # }
|
|
/// #
|
|
/// // A component containing an entity list.
|
|
/// #[derive(Component)]
|
|
/// struct Friends {
|
|
/// list: Vec<Entity>,
|
|
/// }
|
|
///
|
|
/// fn system(
|
|
/// friends_query: Query<&Friends>,
|
|
/// counter_query: Query<&Counter>,
|
|
/// ) {
|
|
/// for friends in &friends_query {
|
|
/// for counter in counter_query.iter_many(&friends.list) {
|
|
/// println!("Friend's counter: {}", counter.value);
|
|
/// }
|
|
/// }
|
|
/// }
|
|
/// # bevy_ecs::system::assert_is_system(system);
|
|
/// ```
|
|
///
|
|
/// # See also
|
|
///
|
|
/// - [`iter_many_mut`](Self::iter_many_mut) to get mutable query items.
|
|
/// - [`iter_many_inner`](Self::iter_many_inner) to get mutable query items with the full `'world` lifetime.
|
|
#[inline]
|
|
pub fn iter_many<EntityList: IntoIterator<Item: EntityEquivalent>>(
|
|
&self,
|
|
entities: EntityList,
|
|
) -> QueryManyIter<'_, 's, D::ReadOnly, F, EntityList::IntoIter> {
|
|
self.as_readonly().iter_many_inner(entities)
|
|
}
|
|
|
|
/// 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
|
|
/// doesn't guarantee uniqueness. Entities that don't match the query are skipped.
|
|
///
|
|
/// # Examples
|
|
///
|
|
/// ```
|
|
/// # use bevy_ecs::prelude::*;
|
|
/// #[derive(Component)]
|
|
/// struct Counter {
|
|
/// value: i32
|
|
/// }
|
|
///
|
|
/// #[derive(Component)]
|
|
/// struct Friends {
|
|
/// list: Vec<Entity>,
|
|
/// }
|
|
///
|
|
/// fn system(
|
|
/// friends_query: Query<&Friends>,
|
|
/// mut counter_query: Query<&mut Counter>,
|
|
/// ) {
|
|
/// for friends in &friends_query {
|
|
/// let mut iter = counter_query.iter_many_mut(&friends.list);
|
|
/// while let Some(mut counter) = iter.fetch_next() {
|
|
/// println!("Friend's counter: {}", counter.value);
|
|
/// counter.value += 1;
|
|
/// }
|
|
/// }
|
|
/// }
|
|
/// # bevy_ecs::system::assert_is_system(system);
|
|
/// ```
|
|
/// # See also
|
|
///
|
|
/// - [`iter_many`](Self::iter_many) to get read-only query items.
|
|
/// - [`iter_many_inner`](Self::iter_many_inner) to get mutable query items with the full `'world` lifetime.
|
|
#[inline]
|
|
pub fn iter_many_mut<EntityList: IntoIterator<Item: EntityEquivalent>>(
|
|
&mut self,
|
|
entities: EntityList,
|
|
) -> QueryManyIter<'_, 's, D, F, EntityList::IntoIter> {
|
|
self.reborrow().iter_many_inner(entities)
|
|
}
|
|
|
|
/// Returns an iterator over the query items generated from an [`Entity`] list.
|
|
/// This consumes the [`Query`] to return results with the actual "inner" world lifetime.
|
|
///
|
|
/// Items are returned in the order of the list of entities, and may not be unique if the input
|
|
/// doesn't guarantee uniqueness. Entities that don't match the query are skipped.
|
|
///
|
|
/// # See also
|
|
///
|
|
/// - [`iter_many`](Self::iter_many) to get read-only query items.
|
|
/// - [`iter_many_mut`](Self::iter_many_mut) to get mutable query items.
|
|
#[inline]
|
|
pub fn iter_many_inner<EntityList: IntoIterator<Item: EntityEquivalent>>(
|
|
self,
|
|
entities: EntityList,
|
|
) -> QueryManyIter<'w, 's, D, F, EntityList::IntoIter> {
|
|
// SAFETY: `self.world` has permission to access the required components.
|
|
unsafe {
|
|
QueryManyIter::new(
|
|
self.world,
|
|
self.state,
|
|
entities,
|
|
self.last_run,
|
|
self.this_run,
|
|
)
|
|
}
|
|
}
|
|
|
|
/// Returns an [`Iterator`] over the unique read-only query items generated from an [`EntitySet`].
|
|
///
|
|
/// Items are returned in the order of the list of entities. Entities that don't match the query are skipped.
|
|
///
|
|
/// # Example
|
|
///
|
|
/// ```
|
|
/// # use bevy_ecs::{prelude::*, entity::{EntitySet, UniqueEntityIter}};
|
|
/// # use core::slice;
|
|
/// # #[derive(Component)]
|
|
/// # struct Counter {
|
|
/// # value: i32
|
|
/// # }
|
|
/// #
|
|
/// // `Friends` ensures that it only lists unique entities.
|
|
/// #[derive(Component)]
|
|
/// struct Friends {
|
|
/// unique_list: Vec<Entity>,
|
|
/// }
|
|
///
|
|
/// impl<'a> IntoIterator for &'a Friends {
|
|
///
|
|
/// type Item = &'a Entity;
|
|
/// type IntoIter = UniqueEntityIter<slice::Iter<'a, Entity>>;
|
|
///
|
|
/// fn into_iter(self) -> Self::IntoIter {
|
|
/// // SAFETY: `Friends` ensures that it unique_list contains only unique entities.
|
|
/// unsafe { UniqueEntityIter::from_iterator_unchecked(self.unique_list.iter()) }
|
|
/// }
|
|
/// }
|
|
///
|
|
/// fn system(
|
|
/// friends_query: Query<&Friends>,
|
|
/// counter_query: Query<&Counter>,
|
|
/// ) {
|
|
/// for friends in &friends_query {
|
|
/// for counter in counter_query.iter_many_unique(friends) {
|
|
/// println!("Friend's counter: {:?}", counter.value);
|
|
/// }
|
|
/// }
|
|
/// }
|
|
/// # bevy_ecs::system::assert_is_system(system);
|
|
/// ```
|
|
///
|
|
/// # See also
|
|
///
|
|
/// - [`iter_many_unique_mut`](Self::iter_many_unique_mut) to get mutable query items.
|
|
/// - [`iter_many_unique_inner`](Self::iter_many_unique_inner) to get with the actual "inner" world lifetime.
|
|
#[inline]
|
|
pub fn iter_many_unique<EntityList: EntitySet>(
|
|
&self,
|
|
entities: EntityList,
|
|
) -> QueryManyUniqueIter<'_, 's, D::ReadOnly, F, EntityList::IntoIter> {
|
|
self.as_readonly().iter_many_unique_inner(entities)
|
|
}
|
|
|
|
/// Returns an iterator over the unique query items generated from an [`EntitySet`].
|
|
///
|
|
/// Items are returned in the order of the list of entities. Entities that don't match the query are skipped.
|
|
///
|
|
/// # Examples
|
|
///
|
|
/// ```
|
|
/// # use bevy_ecs::{prelude::*, entity::{EntitySet, UniqueEntityIter}};
|
|
/// # use core::slice;
|
|
/// #[derive(Component)]
|
|
/// struct Counter {
|
|
/// value: i32
|
|
/// }
|
|
///
|
|
/// // `Friends` ensures that it only lists unique entities.
|
|
/// #[derive(Component)]
|
|
/// struct Friends {
|
|
/// unique_list: Vec<Entity>,
|
|
/// }
|
|
///
|
|
/// impl<'a> IntoIterator for &'a Friends {
|
|
/// type Item = &'a Entity;
|
|
/// type IntoIter = UniqueEntityIter<slice::Iter<'a, Entity>>;
|
|
///
|
|
/// fn into_iter(self) -> Self::IntoIter {
|
|
/// // SAFETY: `Friends` ensures that it unique_list contains only unique entities.
|
|
/// unsafe { UniqueEntityIter::from_iterator_unchecked(self.unique_list.iter()) }
|
|
/// }
|
|
/// }
|
|
///
|
|
/// fn system(
|
|
/// friends_query: Query<&Friends>,
|
|
/// mut counter_query: Query<&mut Counter>,
|
|
/// ) {
|
|
/// for friends in &friends_query {
|
|
/// for mut counter in counter_query.iter_many_unique_mut(friends) {
|
|
/// println!("Friend's counter: {:?}", counter.value);
|
|
/// counter.value += 1;
|
|
/// }
|
|
/// }
|
|
/// }
|
|
/// # bevy_ecs::system::assert_is_system(system);
|
|
/// ```
|
|
/// # See also
|
|
///
|
|
/// - [`iter_many_unique`](Self::iter_many_unique) to get read-only query items.
|
|
/// - [`iter_many_unique_inner`](Self::iter_many_unique_inner) to get with the actual "inner" world lifetime.
|
|
#[inline]
|
|
pub fn iter_many_unique_mut<EntityList: EntitySet>(
|
|
&mut self,
|
|
entities: EntityList,
|
|
) -> QueryManyUniqueIter<'_, 's, D, F, EntityList::IntoIter> {
|
|
self.reborrow().iter_many_unique_inner(entities)
|
|
}
|
|
|
|
/// Returns an iterator over the unique query items generated from an [`EntitySet`].
|
|
/// This consumes the [`Query`] to return results with the actual "inner" world lifetime.
|
|
///
|
|
/// Items are returned in the order of the list of entities. Entities that don't match the query are skipped.
|
|
///
|
|
/// # Examples
|
|
///
|
|
/// ```
|
|
/// # use bevy_ecs::{prelude::*, entity::{EntitySet, UniqueEntityIter}};
|
|
/// # use core::slice;
|
|
/// #[derive(Component)]
|
|
/// struct Counter {
|
|
/// value: i32
|
|
/// }
|
|
///
|
|
/// // `Friends` ensures that it only lists unique entities.
|
|
/// #[derive(Component)]
|
|
/// struct Friends {
|
|
/// unique_list: Vec<Entity>,
|
|
/// }
|
|
///
|
|
/// impl<'a> IntoIterator for &'a Friends {
|
|
/// type Item = &'a Entity;
|
|
/// type IntoIter = UniqueEntityIter<slice::Iter<'a, Entity>>;
|
|
///
|
|
/// fn into_iter(self) -> Self::IntoIter {
|
|
/// // SAFETY: `Friends` ensures that it unique_list contains only unique entities.
|
|
/// unsafe { UniqueEntityIter::from_iterator_unchecked(self.unique_list.iter()) }
|
|
/// }
|
|
/// }
|
|
///
|
|
/// fn system(
|
|
/// friends_query: Query<&Friends>,
|
|
/// mut counter_query: Query<&mut Counter>,
|
|
/// ) {
|
|
/// let friends = friends_query.single().unwrap();
|
|
/// for mut counter in counter_query.iter_many_unique_inner(friends) {
|
|
/// println!("Friend's counter: {:?}", counter.value);
|
|
/// counter.value += 1;
|
|
/// }
|
|
/// }
|
|
/// # bevy_ecs::system::assert_is_system(system);
|
|
/// ```
|
|
/// # See also
|
|
///
|
|
/// - [`iter_many_unique`](Self::iter_many_unique) to get read-only query items.
|
|
/// - [`iter_many_unique_mut`](Self::iter_many_unique_mut) to get mutable query items.
|
|
#[inline]
|
|
pub fn iter_many_unique_inner<EntityList: EntitySet>(
|
|
self,
|
|
entities: EntityList,
|
|
) -> QueryManyUniqueIter<'w, 's, D, F, EntityList::IntoIter> {
|
|
// SAFETY: `self.world` has permission to access the required components.
|
|
unsafe {
|
|
QueryManyUniqueIter::new(
|
|
self.world,
|
|
self.state,
|
|
entities,
|
|
self.last_run,
|
|
self.this_run,
|
|
)
|
|
}
|
|
}
|
|
|
|
/// 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.
|
|
/// You must make sure this call does not result in multiple mutable references to the same component.
|
|
///
|
|
/// # See also
|
|
///
|
|
/// - [`iter`](Self::iter) and [`iter_mut`](Self::iter_mut) for the safe versions.
|
|
#[inline]
|
|
pub unsafe fn iter_unsafe(&self) -> QueryIter<'_, 's, D, F> {
|
|
// SAFETY: The caller promises that this will not result in multiple mutable references.
|
|
unsafe { self.reborrow_unsafe() }.into_iter()
|
|
}
|
|
|
|
/// 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.
|
|
/// You must make sure this call does not result in multiple mutable references to the same component.
|
|
///
|
|
/// # See also
|
|
///
|
|
/// - [`iter_combinations`](Self::iter_combinations) and [`iter_combinations_mut`](Self::iter_combinations_mut) for the safe versions.
|
|
#[inline]
|
|
pub unsafe fn iter_combinations_unsafe<const K: usize>(
|
|
&self,
|
|
) -> QueryCombinationIter<'_, 's, D, F, K> {
|
|
// SAFETY: The caller promises that this will not result in multiple mutable references.
|
|
unsafe { self.reborrow_unsafe() }.iter_combinations_inner()
|
|
}
|
|
|
|
/// 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.
|
|
/// You must make sure this call does not result in multiple mutable references to the same component.
|
|
/// Particular care must be taken when collecting the data (rather than iterating over it one item at a time) such as via [`Iterator::collect`].
|
|
///
|
|
/// # See also
|
|
///
|
|
/// - [`iter_many_mut`](Self::iter_many_mut) to safely access the query items.
|
|
pub unsafe fn iter_many_unsafe<EntityList: IntoIterator<Item: EntityEquivalent>>(
|
|
&self,
|
|
entities: EntityList,
|
|
) -> QueryManyIter<'_, 's, D, F, EntityList::IntoIter> {
|
|
// SAFETY: The caller promises that this will not result in multiple mutable references.
|
|
unsafe { self.reborrow_unsafe() }.iter_many_inner(entities)
|
|
}
|
|
|
|
/// Returns an [`Iterator`] over the unique 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.
|
|
///
|
|
/// # Safety
|
|
///
|
|
/// This allows aliased mutability.
|
|
/// You must make sure this call does not result in multiple mutable references to the same component.
|
|
///
|
|
/// # See also
|
|
///
|
|
/// - [`iter_many_unique`](Self::iter_many_unique) to get read-only query items.
|
|
/// - [`iter_many_unique_mut`](Self::iter_many_unique_mut) to get mutable query items.
|
|
/// - [`iter_many_unique_inner`](Self::iter_many_unique_inner) to get with the actual "inner" world lifetime.
|
|
pub unsafe fn iter_many_unique_unsafe<EntityList: EntitySet>(
|
|
&self,
|
|
entities: EntityList,
|
|
) -> QueryManyUniqueIter<'_, 's, D, F, EntityList::IntoIter> {
|
|
// SAFETY: The caller promises that this will not result in multiple mutable references.
|
|
unsafe { self.reborrow_unsafe() }.iter_many_unique_inner(entities)
|
|
}
|
|
|
|
/// 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
|
|
/// results, see [`par_iter_mut`] for an example.
|
|
///
|
|
/// [`par_iter_mut`]: Self::par_iter_mut
|
|
/// [`World`]: crate::world::World
|
|
#[inline]
|
|
pub fn par_iter(&self) -> QueryParIter<'_, '_, D::ReadOnly, F> {
|
|
self.as_readonly().par_iter_inner()
|
|
}
|
|
|
|
/// 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
|
|
///
|
|
/// Here, the `gravity_system` updates the `Velocity` component of every entity that contains it:
|
|
///
|
|
/// ```
|
|
/// # use bevy_ecs::prelude::*;
|
|
/// #
|
|
/// # #[derive(Component)]
|
|
/// # struct Velocity { x: f32, y: f32, z: f32 }
|
|
/// fn gravity_system(mut query: Query<&mut Velocity>) {
|
|
/// const DELTA: f32 = 1.0 / 60.0;
|
|
/// query.par_iter_mut().for_each(|mut velocity| {
|
|
/// velocity.y -= 9.8 * DELTA;
|
|
/// });
|
|
/// }
|
|
/// # bevy_ecs::system::assert_is_system(gravity_system);
|
|
/// ```
|
|
///
|
|
/// [`par_iter`]: Self::par_iter
|
|
/// [`World`]: crate::world::World
|
|
#[inline]
|
|
pub fn par_iter_mut(&mut self) -> QueryParIter<'_, '_, D, F> {
|
|
self.reborrow().par_iter_inner()
|
|
}
|
|
|
|
/// Returns a parallel iterator over the query results for the given [`World`](crate::world::World).
|
|
/// This consumes the [`Query`] to return results with the actual "inner" world lifetime.
|
|
///
|
|
/// 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`].
|
|
///
|
|
/// # Example
|
|
///
|
|
/// Here, the `gravity_system` updates the `Velocity` component of every entity that contains it:
|
|
///
|
|
/// ```
|
|
/// # use bevy_ecs::prelude::*;
|
|
/// #
|
|
/// # #[derive(Component)]
|
|
/// # struct Velocity { x: f32, y: f32, z: f32 }
|
|
/// fn gravity_system(query: Query<&mut Velocity>) {
|
|
/// const DELTA: f32 = 1.0 / 60.0;
|
|
/// query.par_iter_inner().for_each(|mut velocity| {
|
|
/// velocity.y -= 9.8 * DELTA;
|
|
/// });
|
|
/// }
|
|
/// # bevy_ecs::system::assert_is_system(gravity_system);
|
|
/// ```
|
|
#[inline]
|
|
pub fn par_iter_inner(self) -> QueryParIter<'w, 's, D, F> {
|
|
QueryParIter {
|
|
world: self.world,
|
|
state: self.state,
|
|
last_run: self.last_run,
|
|
this_run: self.this_run,
|
|
batching_strategy: BatchingStrategy::new(),
|
|
}
|
|
}
|
|
|
|
/// Returns a parallel iterator over the read-only query items generated from an [`Entity`] list.
|
|
///
|
|
/// Entities that don't match the query are skipped. Iteration order and thread assignment is not guaranteed.
|
|
///
|
|
/// If the `multithreaded` feature is disabled, iterating with this operates identically to [`Iterator::for_each`]
|
|
/// on [`QueryManyIter`].
|
|
///
|
|
/// This can only be called for read-only queries. To avoid potential aliasing, there is no `par_iter_many_mut` equivalent.
|
|
/// See [`par_iter_many_unique_mut`] for an alternative using [`EntitySet`].
|
|
///
|
|
/// Note that you must use the `for_each` method to iterate over the
|
|
/// results, see [`par_iter_mut`] for an example.
|
|
///
|
|
/// [`par_iter_many_unique_mut`]: Self::par_iter_many_unique_mut
|
|
/// [`par_iter_mut`]: Self::par_iter_mut
|
|
#[inline]
|
|
pub fn par_iter_many<EntityList: IntoIterator<Item: EntityEquivalent>>(
|
|
&self,
|
|
entities: EntityList,
|
|
) -> QueryParManyIter<'_, '_, D::ReadOnly, F, EntityList::Item> {
|
|
QueryParManyIter {
|
|
world: self.world,
|
|
state: self.state.as_readonly(),
|
|
entity_list: entities.into_iter().collect(),
|
|
last_run: self.last_run,
|
|
this_run: self.this_run,
|
|
batching_strategy: BatchingStrategy::new(),
|
|
}
|
|
}
|
|
|
|
/// Returns a parallel iterator over the unique read-only query items generated from an [`EntitySet`].
|
|
///
|
|
/// Entities that don't match the query are skipped. Iteration order and thread assignment is not guaranteed.
|
|
///
|
|
/// If the `multithreaded` feature is disabled, iterating with this operates identically to [`Iterator::for_each`]
|
|
/// on [`QueryManyUniqueIter`].
|
|
///
|
|
/// This can only be called for read-only queries, see [`par_iter_many_unique_mut`] for write-queries.
|
|
///
|
|
/// Note that you must use the `for_each` method to iterate over the
|
|
/// results, see [`par_iter_mut`] for an example.
|
|
///
|
|
/// [`par_iter_many_unique_mut`]: Self::par_iter_many_unique_mut
|
|
/// [`par_iter_mut`]: Self::par_iter_mut
|
|
#[inline]
|
|
pub fn par_iter_many_unique<EntityList: EntitySet<Item: Sync>>(
|
|
&self,
|
|
entities: EntityList,
|
|
) -> QueryParManyUniqueIter<'_, '_, D::ReadOnly, F, EntityList::Item> {
|
|
QueryParManyUniqueIter {
|
|
world: self.world,
|
|
state: self.state.as_readonly(),
|
|
entity_list: entities.into_iter().collect(),
|
|
last_run: self.last_run,
|
|
this_run: self.this_run,
|
|
batching_strategy: BatchingStrategy::new(),
|
|
}
|
|
}
|
|
|
|
/// Returns a parallel iterator over the unique query items generated from an [`EntitySet`].
|
|
///
|
|
/// Entities that don't match the query are skipped. Iteration order and thread assignment is not guaranteed.
|
|
///
|
|
/// If the `multithreaded` feature is disabled, iterating with this operates identically to [`Iterator::for_each`]
|
|
/// on [`QueryManyUniqueIter`].
|
|
///
|
|
/// This can only be called for mutable queries, see [`par_iter_many_unique`] for read-only-queries.
|
|
///
|
|
/// Note that you must use the `for_each` method to iterate over the
|
|
/// results, see [`par_iter_mut`] for an example.
|
|
///
|
|
/// [`par_iter_many_unique`]: Self::par_iter_many_unique
|
|
/// [`par_iter_mut`]: Self::par_iter_mut
|
|
#[inline]
|
|
pub fn par_iter_many_unique_mut<EntityList: EntitySet<Item: Sync>>(
|
|
&mut self,
|
|
entities: EntityList,
|
|
) -> QueryParManyUniqueIter<'_, '_, D, F, EntityList::Item> {
|
|
QueryParManyUniqueIter {
|
|
world: self.world,
|
|
state: self.state,
|
|
entity_list: entities.into_iter().collect(),
|
|
last_run: self.last_run,
|
|
this_run: self.this_run,
|
|
batching_strategy: BatchingStrategy::new(),
|
|
}
|
|
}
|
|
|
|
/// Returns the read-only query item for the given [`Entity`].
|
|
///
|
|
/// In case of a nonexisting entity or mismatched component, a [`QueryEntityError`] is returned instead.
|
|
///
|
|
/// This is always guaranteed to run in `O(1)` time.
|
|
///
|
|
/// # Example
|
|
///
|
|
/// Here, `get` is used to retrieve the exact query item of the entity specified by the `SelectedCharacter` resource.
|
|
///
|
|
/// ```
|
|
/// # use bevy_ecs::prelude::*;
|
|
/// #
|
|
/// # #[derive(Resource)]
|
|
/// # struct SelectedCharacter { entity: Entity }
|
|
/// # #[derive(Component)]
|
|
/// # struct Character { name: String }
|
|
/// #
|
|
/// fn print_selected_character_name_system(
|
|
/// query: Query<&Character>,
|
|
/// selection: Res<SelectedCharacter>
|
|
/// )
|
|
/// {
|
|
/// if let Ok(selected_character) = query.get(selection.entity) {
|
|
/// println!("{}", selected_character.name);
|
|
/// }
|
|
/// }
|
|
/// # bevy_ecs::system::assert_is_system(print_selected_character_name_system);
|
|
/// ```
|
|
///
|
|
/// # See also
|
|
///
|
|
/// - [`get_mut`](Self::get_mut) to get a mutable query item.
|
|
#[inline]
|
|
pub fn get(&self, entity: Entity) -> Result<ROQueryItem<'_, D>, QueryEntityError> {
|
|
self.as_readonly().get_inner(entity)
|
|
}
|
|
|
|
/// Returns the read-only query items for the given array of [`Entity`].
|
|
///
|
|
/// The returned query items are in the same order as the input.
|
|
/// In case of a nonexisting entity or mismatched component, a [`QueryEntityError`] is returned instead.
|
|
/// The elements of the array do not need to be unique, unlike `get_many_mut`.
|
|
///
|
|
/// # Examples
|
|
///
|
|
/// ```
|
|
/// use bevy_ecs::prelude::*;
|
|
/// use bevy_ecs::query::QueryEntityError;
|
|
///
|
|
/// #[derive(Component, PartialEq, Debug)]
|
|
/// struct A(usize);
|
|
///
|
|
/// let mut world = World::new();
|
|
/// let entity_vec: Vec<Entity> = (0..3).map(|i| world.spawn(A(i)).id()).collect();
|
|
/// let entities: [Entity; 3] = entity_vec.try_into().unwrap();
|
|
///
|
|
/// world.spawn(A(73));
|
|
///
|
|
/// let mut query_state = world.query::<&A>();
|
|
/// let query = query_state.query(&world);
|
|
///
|
|
/// let component_values = query.get_many(entities).unwrap();
|
|
///
|
|
/// assert_eq!(component_values, [&A(0), &A(1), &A(2)]);
|
|
///
|
|
/// let wrong_entity = Entity::from_raw(365);
|
|
///
|
|
/// assert_eq!(
|
|
/// match query.get_many([wrong_entity]).unwrap_err() {
|
|
/// QueryEntityError::EntityDoesNotExist(error) => error.entity,
|
|
/// _ => panic!(),
|
|
/// },
|
|
/// wrong_entity
|
|
/// );
|
|
/// ```
|
|
///
|
|
/// # See also
|
|
///
|
|
/// - [`get_many_mut`](Self::get_many_mut) to get mutable query items.
|
|
/// - [`get_many_unique`](Self::get_many_unique) to only handle unique inputs.
|
|
/// - [`many`](Self::many) for the panicking version.
|
|
#[inline]
|
|
pub fn get_many<const N: usize>(
|
|
&self,
|
|
entities: [Entity; N],
|
|
) -> Result<[ROQueryItem<'_, D>; N], QueryEntityError> {
|
|
// Note that we call a separate `*_inner` method from `get_many_mut`
|
|
// because we don't need to check for duplicates.
|
|
self.as_readonly().get_many_inner(entities)
|
|
}
|
|
|
|
/// Returns the read-only query items for the given [`UniqueEntityArray`].
|
|
///
|
|
/// The returned query items are in the same order as the input.
|
|
/// In case of a nonexisting entity or mismatched component, a [`QueryEntityError`] is returned instead.
|
|
///
|
|
/// # Examples
|
|
///
|
|
/// ```
|
|
/// use bevy_ecs::{prelude::*, query::QueryEntityError, entity::{EntitySetIterator, UniqueEntityArray, UniqueEntityVec}};
|
|
///
|
|
/// #[derive(Component, PartialEq, Debug)]
|
|
/// struct A(usize);
|
|
///
|
|
/// let mut world = World::new();
|
|
/// let entity_set: UniqueEntityVec = world.spawn_batch((0..3).map(A)).collect_set();
|
|
/// let entity_set: UniqueEntityArray<3> = entity_set.try_into().unwrap();
|
|
///
|
|
/// world.spawn(A(73));
|
|
///
|
|
/// let mut query_state = world.query::<&A>();
|
|
/// let query = query_state.query(&world);
|
|
///
|
|
/// let component_values = query.get_many_unique(entity_set).unwrap();
|
|
///
|
|
/// assert_eq!(component_values, [&A(0), &A(1), &A(2)]);
|
|
///
|
|
/// let wrong_entity = Entity::from_raw(365);
|
|
///
|
|
/// assert_eq!(
|
|
/// match query.get_many_unique(UniqueEntityArray::from([wrong_entity])).unwrap_err() {
|
|
/// QueryEntityError::EntityDoesNotExist(error) => error.entity,
|
|
/// _ => panic!(),
|
|
/// },
|
|
/// wrong_entity
|
|
/// );
|
|
/// ```
|
|
///
|
|
/// # See also
|
|
///
|
|
/// - [`get_many_unique_mut`](Self::get_many_mut) to get mutable query items.
|
|
/// - [`get_many`](Self::get_many) to handle inputs with duplicates.
|
|
#[inline]
|
|
pub fn get_many_unique<const N: usize>(
|
|
&self,
|
|
entities: UniqueEntityArray<N>,
|
|
) -> Result<[ROQueryItem<'_, D>; N], QueryEntityError> {
|
|
self.as_readonly().get_many_unique_inner(entities)
|
|
}
|
|
|
|
/// Returns the read-only query items for the given array of [`Entity`].
|
|
///
|
|
/// # Panics
|
|
///
|
|
/// This method panics if there is a query mismatch or a non-existing entity.
|
|
///
|
|
/// # Examples
|
|
/// ``` no_run
|
|
/// use bevy_ecs::prelude::*;
|
|
///
|
|
/// #[derive(Component)]
|
|
/// struct Targets([Entity; 3]);
|
|
///
|
|
/// #[derive(Component)]
|
|
/// struct Position{
|
|
/// x: i8,
|
|
/// y: i8
|
|
/// };
|
|
///
|
|
/// impl Position {
|
|
/// fn distance(&self, other: &Position) -> i8 {
|
|
/// // Manhattan distance is way easier to compute!
|
|
/// (self.x - other.x).abs() + (self.y - other.y).abs()
|
|
/// }
|
|
/// }
|
|
///
|
|
/// fn check_all_targets_in_range(targeting_query: Query<(Entity, &Targets, &Position)>, targets_query: Query<&Position>){
|
|
/// for (targeting_entity, targets, origin) in &targeting_query {
|
|
/// // We can use "destructuring" to unpack the results nicely
|
|
/// let [target_1, target_2, target_3] = targets_query.many(targets.0);
|
|
///
|
|
/// assert!(target_1.distance(origin) <= 5);
|
|
/// assert!(target_2.distance(origin) <= 5);
|
|
/// assert!(target_3.distance(origin) <= 5);
|
|
/// }
|
|
/// }
|
|
/// ```
|
|
///
|
|
/// # See also
|
|
///
|
|
/// - [`get_many`](Self::get_many) for the non-panicking version.
|
|
#[inline]
|
|
#[track_caller]
|
|
#[deprecated(note = "Use `get_many` instead and handle the Result.")]
|
|
pub fn many<const N: usize>(&self, entities: [Entity; N]) -> [ROQueryItem<'_, D>; N] {
|
|
match self.get_many(entities) {
|
|
Ok(items) => items,
|
|
Err(error) => panic!("Cannot get query results: {error}"),
|
|
}
|
|
}
|
|
|
|
/// Returns the query item for the given [`Entity`].
|
|
///
|
|
/// In case of a nonexisting entity or mismatched component, a [`QueryEntityError`] is returned instead.
|
|
///
|
|
/// This is always guaranteed to run in `O(1)` time.
|
|
///
|
|
/// # Example
|
|
///
|
|
/// Here, `get_mut` is used to retrieve the exact query item of the entity specified by the `PoisonedCharacter` resource.
|
|
///
|
|
/// ```
|
|
/// # use bevy_ecs::prelude::*;
|
|
/// #
|
|
/// # #[derive(Resource)]
|
|
/// # struct PoisonedCharacter { character_id: Entity }
|
|
/// # #[derive(Component)]
|
|
/// # struct Health(u32);
|
|
/// #
|
|
/// fn poison_system(mut query: Query<&mut Health>, poisoned: Res<PoisonedCharacter>) {
|
|
/// if let Ok(mut health) = query.get_mut(poisoned.character_id) {
|
|
/// health.0 -= 1;
|
|
/// }
|
|
/// }
|
|
/// # bevy_ecs::system::assert_is_system(poison_system);
|
|
/// ```
|
|
///
|
|
/// # See also
|
|
///
|
|
/// - [`get`](Self::get) to get a read-only query item.
|
|
#[inline]
|
|
pub fn get_mut(&mut self, entity: Entity) -> Result<D::Item<'_>, QueryEntityError> {
|
|
self.reborrow().get_inner(entity)
|
|
}
|
|
|
|
/// Returns the query item for the given [`Entity`].
|
|
/// This consumes the [`Query`] to return results with the actual "inner" world lifetime.
|
|
///
|
|
/// In case of a nonexisting entity or mismatched component, a [`QueryEntityError`] is returned instead.
|
|
///
|
|
/// This is always guaranteed to run in `O(1)` time.
|
|
///
|
|
/// # See also
|
|
///
|
|
/// - [`get_mut`](Self::get_mut) to get the item using a mutable borrow of the [`Query`].
|
|
#[inline]
|
|
pub fn get_inner(self, entity: Entity) -> Result<D::Item<'w>, QueryEntityError> {
|
|
// SAFETY: system runs without conflicts with other systems.
|
|
// same-system queries have runtime borrow checks when they conflict
|
|
unsafe {
|
|
let location = self
|
|
.world
|
|
.entities()
|
|
.get(entity)
|
|
.ok_or(EntityDoesNotExistError::new(entity, self.world.entities()))?;
|
|
if !self
|
|
.state
|
|
.matched_archetypes
|
|
.contains(location.archetype_id.index())
|
|
{
|
|
return Err(QueryEntityError::QueryDoesNotMatch(
|
|
entity,
|
|
location.archetype_id,
|
|
));
|
|
}
|
|
let archetype = self
|
|
.world
|
|
.archetypes()
|
|
.get(location.archetype_id)
|
|
.debug_checked_unwrap();
|
|
let mut fetch = D::init_fetch(
|
|
self.world,
|
|
&self.state.fetch_state,
|
|
self.last_run,
|
|
self.this_run,
|
|
);
|
|
let mut filter = F::init_fetch(
|
|
self.world,
|
|
&self.state.filter_state,
|
|
self.last_run,
|
|
self.this_run,
|
|
);
|
|
|
|
let table = self
|
|
.world
|
|
.storages()
|
|
.tables
|
|
.get(location.table_id)
|
|
.debug_checked_unwrap();
|
|
D::set_archetype(&mut fetch, &self.state.fetch_state, archetype, table);
|
|
F::set_archetype(&mut filter, &self.state.filter_state, archetype, table);
|
|
|
|
if F::filter_fetch(&mut filter, entity, location.table_row) {
|
|
Ok(D::fetch(&mut fetch, entity, location.table_row))
|
|
} else {
|
|
Err(QueryEntityError::QueryDoesNotMatch(
|
|
entity,
|
|
location.archetype_id,
|
|
))
|
|
}
|
|
}
|
|
}
|
|
|
|
/// Returns the query items for the given array of [`Entity`].
|
|
///
|
|
/// The returned query items are in the same order as the input.
|
|
/// In case of a nonexisting entity, duplicate entities or mismatched component, a [`QueryEntityError`] is returned instead.
|
|
///
|
|
/// # Examples
|
|
///
|
|
/// ```
|
|
/// use bevy_ecs::prelude::*;
|
|
/// use bevy_ecs::query::QueryEntityError;
|
|
///
|
|
/// #[derive(Component, PartialEq, Debug)]
|
|
/// struct A(usize);
|
|
///
|
|
/// let mut world = World::new();
|
|
///
|
|
/// let entities: Vec<Entity> = (0..3).map(|i| world.spawn(A(i)).id()).collect();
|
|
/// let entities: [Entity; 3] = entities.try_into().unwrap();
|
|
///
|
|
/// world.spawn(A(73));
|
|
/// let wrong_entity = Entity::from_raw(57);
|
|
/// let invalid_entity = world.spawn_empty().id();
|
|
///
|
|
///
|
|
/// let mut query_state = world.query::<&mut A>();
|
|
/// let mut query = query_state.query_mut(&mut world);
|
|
///
|
|
/// let mut mutable_component_values = query.get_many_mut(entities).unwrap();
|
|
///
|
|
/// for mut a in &mut mutable_component_values {
|
|
/// a.0 += 5;
|
|
/// }
|
|
///
|
|
/// let component_values = query.get_many(entities).unwrap();
|
|
///
|
|
/// assert_eq!(component_values, [&A(5), &A(6), &A(7)]);
|
|
///
|
|
/// assert_eq!(
|
|
/// match query
|
|
/// .get_many_mut([wrong_entity])
|
|
/// .unwrap_err()
|
|
/// {
|
|
/// QueryEntityError::EntityDoesNotExist(error) => error.entity,
|
|
/// _ => panic!(),
|
|
/// },
|
|
/// wrong_entity
|
|
/// );
|
|
/// assert_eq!(
|
|
/// match query
|
|
/// .get_many_mut([invalid_entity])
|
|
/// .unwrap_err()
|
|
/// {
|
|
/// QueryEntityError::QueryDoesNotMatch(entity, _) => entity,
|
|
/// _ => panic!(),
|
|
/// },
|
|
/// invalid_entity
|
|
/// );
|
|
/// assert_eq!(
|
|
/// query
|
|
/// .get_many_mut([entities[0], entities[0]])
|
|
/// .unwrap_err(),
|
|
/// QueryEntityError::AliasedMutability(entities[0])
|
|
/// );
|
|
/// ```
|
|
/// # See also
|
|
///
|
|
/// - [`get_many`](Self::get_many) to get read-only query items without checking for duplicate entities.
|
|
/// - [`many_mut`](Self::many_mut) for the panicking version.
|
|
#[inline]
|
|
pub fn get_many_mut<const N: usize>(
|
|
&mut self,
|
|
entities: [Entity; N],
|
|
) -> Result<[D::Item<'_>; N], QueryEntityError> {
|
|
self.reborrow().get_many_mut_inner(entities)
|
|
}
|
|
|
|
/// Returns the query items for the given [`UniqueEntityArray`].
|
|
///
|
|
/// The returned query items are in the same order as the input.
|
|
/// In case of a nonexisting entity or mismatched component, a [`QueryEntityError`] is returned instead.
|
|
///
|
|
/// # Examples
|
|
///
|
|
/// ```
|
|
/// use bevy_ecs::{prelude::*, query::QueryEntityError, entity::{EntitySetIterator, UniqueEntityArray, UniqueEntityVec}};
|
|
///
|
|
/// #[derive(Component, PartialEq, Debug)]
|
|
/// struct A(usize);
|
|
///
|
|
/// let mut world = World::new();
|
|
///
|
|
/// let entity_set: UniqueEntityVec<_> = world.spawn_batch((0..3).map(A)).collect_set();
|
|
/// let entity_set: UniqueEntityArray<3> = entity_set.try_into().unwrap();
|
|
///
|
|
/// world.spawn(A(73));
|
|
/// let wrong_entity = Entity::from_raw(57);
|
|
/// let invalid_entity = world.spawn_empty().id();
|
|
///
|
|
///
|
|
/// let mut query_state = world.query::<&mut A>();
|
|
/// let mut query = query_state.query_mut(&mut world);
|
|
///
|
|
/// let mut mutable_component_values = query.get_many_unique_mut(entity_set).unwrap();
|
|
///
|
|
/// for mut a in &mut mutable_component_values {
|
|
/// a.0 += 5;
|
|
/// }
|
|
///
|
|
/// let component_values = query.get_many_unique(entity_set).unwrap();
|
|
///
|
|
/// assert_eq!(component_values, [&A(5), &A(6), &A(7)]);
|
|
///
|
|
/// assert_eq!(
|
|
/// match query
|
|
/// .get_many_unique_mut(UniqueEntityArray::from([wrong_entity]))
|
|
/// .unwrap_err()
|
|
/// {
|
|
/// QueryEntityError::EntityDoesNotExist(error) => error.entity,
|
|
/// _ => panic!(),
|
|
/// },
|
|
/// wrong_entity
|
|
/// );
|
|
/// assert_eq!(
|
|
/// match query
|
|
/// .get_many_unique_mut(UniqueEntityArray::from([invalid_entity]))
|
|
/// .unwrap_err()
|
|
/// {
|
|
/// QueryEntityError::QueryDoesNotMatch(entity, _) => entity,
|
|
/// _ => panic!(),
|
|
/// },
|
|
/// invalid_entity
|
|
/// );
|
|
/// ```
|
|
/// # See also
|
|
///
|
|
/// - [`get_many_unique`](Self::get_many) to get read-only query items.
|
|
#[inline]
|
|
pub fn get_many_unique_mut<const N: usize>(
|
|
&mut self,
|
|
entities: UniqueEntityArray<N>,
|
|
) -> Result<[D::Item<'_>; N], QueryEntityError> {
|
|
self.reborrow().get_many_unique_inner(entities)
|
|
}
|
|
|
|
/// Returns the query items for the given array of [`Entity`].
|
|
/// This consumes the [`Query`] to return results with the actual "inner" world lifetime.
|
|
///
|
|
/// The returned query items are in the same order as the input.
|
|
/// In case of a nonexisting entity, duplicate entities or mismatched component, a [`QueryEntityError`] is returned instead.
|
|
///
|
|
/// # See also
|
|
///
|
|
/// - [`get_many`](Self::get_many) to get read-only query items without checking for duplicate entities.
|
|
/// - [`get_many_mut`](Self::get_many_mut) to get items using a mutable reference.
|
|
/// - [`get_many_inner`](Self::get_many_mut_inner) to get read-only query items with the actual "inner" world lifetime.
|
|
#[inline]
|
|
pub fn get_many_mut_inner<const N: usize>(
|
|
self,
|
|
entities: [Entity; N],
|
|
) -> Result<[D::Item<'w>; N], QueryEntityError> {
|
|
// Verify that all entities are unique
|
|
for i in 0..N {
|
|
for j in 0..i {
|
|
if entities[i] == entities[j] {
|
|
return Err(QueryEntityError::AliasedMutability(entities[i]));
|
|
}
|
|
}
|
|
}
|
|
// SAFETY: All entities are unique, so the results don't alias.
|
|
unsafe { self.get_many_impl(entities) }
|
|
}
|
|
|
|
/// Returns the query items for the given array of [`Entity`].
|
|
/// This consumes the [`Query`] to return results with the actual "inner" world lifetime.
|
|
///
|
|
/// The returned query items are in the same order as the input.
|
|
/// In case of a nonexisting entity or mismatched component, a [`QueryEntityError`] is returned instead.
|
|
///
|
|
/// # See also
|
|
///
|
|
/// - [`get_many`](Self::get_many) to get read-only query items without checking for duplicate entities.
|
|
/// - [`get_many_mut`](Self::get_many_mut) to get items using a mutable reference.
|
|
/// - [`get_many_mut_inner`](Self::get_many_mut_inner) to get mutable query items with the actual "inner" world lifetime.
|
|
#[inline]
|
|
pub fn get_many_inner<const N: usize>(
|
|
self,
|
|
entities: [Entity; N],
|
|
) -> Result<[D::Item<'w>; N], QueryEntityError>
|
|
where
|
|
D: ReadOnlyQueryData,
|
|
{
|
|
// SAFETY: The query results are read-only, so they don't conflict if there are duplicate entities.
|
|
unsafe { self.get_many_impl(entities) }
|
|
}
|
|
|
|
/// Returns the query items for the given [`UniqueEntityArray`].
|
|
/// This consumes the [`Query`] to return results with the actual "inner" world lifetime.
|
|
///
|
|
/// The returned query items are in the same order as the input.
|
|
/// In case of a nonexisting entity, duplicate entities or mismatched component, a [`QueryEntityError`] is returned instead.
|
|
///
|
|
/// # See also
|
|
///
|
|
/// - [`get_many_unique`](Self::get_many_unique) to get read-only query items without checking for duplicate entities.
|
|
/// - [`get_many_unique_mut`](Self::get_many_unique_mut) to get items using a mutable reference.
|
|
#[inline]
|
|
pub fn get_many_unique_inner<const N: usize>(
|
|
self,
|
|
entities: UniqueEntityArray<N>,
|
|
) -> Result<[D::Item<'w>; N], QueryEntityError> {
|
|
// SAFETY: All entities are unique, so the results don't alias.
|
|
unsafe { self.get_many_impl(entities.into_inner()) }
|
|
}
|
|
|
|
/// Returns the query items for the given array of [`Entity`].
|
|
/// This consumes the [`Query`] to return results with the actual "inner" world lifetime.
|
|
///
|
|
/// # Safety
|
|
///
|
|
/// The caller must ensure that the query data returned for the entities does not conflict,
|
|
/// either because they are all unique or because the data is read-only.
|
|
unsafe fn get_many_impl<const N: usize>(
|
|
self,
|
|
entities: [Entity; N],
|
|
) -> Result<[D::Item<'w>; N], QueryEntityError> {
|
|
let mut values = [(); N].map(|_| MaybeUninit::uninit());
|
|
|
|
for (value, entity) in core::iter::zip(&mut values, entities) {
|
|
// SAFETY: The caller asserts that the results don't alias
|
|
let item = unsafe { self.copy_unsafe() }.get_inner(entity)?;
|
|
*value = MaybeUninit::new(item);
|
|
}
|
|
|
|
// SAFETY: Each value has been fully initialized.
|
|
Ok(values.map(|x| unsafe { x.assume_init() }))
|
|
}
|
|
|
|
/// Returns the query items for the given array of [`Entity`].
|
|
///
|
|
/// # Panics
|
|
///
|
|
/// This method panics if there is a query mismatch, a non-existing entity, or the same `Entity` is included more than once in the array.
|
|
///
|
|
/// # Examples
|
|
///
|
|
/// ``` no_run
|
|
/// use bevy_ecs::prelude::*;
|
|
///
|
|
/// #[derive(Component)]
|
|
/// struct Spring{
|
|
/// connected_entities: [Entity; 2],
|
|
/// strength: f32,
|
|
/// }
|
|
///
|
|
/// #[derive(Component)]
|
|
/// struct Position {
|
|
/// x: f32,
|
|
/// y: f32,
|
|
/// }
|
|
///
|
|
/// #[derive(Component)]
|
|
/// struct Force {
|
|
/// x: f32,
|
|
/// y: f32,
|
|
/// }
|
|
///
|
|
/// fn spring_forces(spring_query: Query<&Spring>, mut mass_query: Query<(&Position, &mut Force)>){
|
|
/// for spring in &spring_query {
|
|
/// // We can use "destructuring" to unpack our query items nicely
|
|
/// let [(position_1, mut force_1), (position_2, mut force_2)] = mass_query.many_mut(spring.connected_entities);
|
|
///
|
|
/// force_1.x += spring.strength * (position_1.x - position_2.x);
|
|
/// force_1.y += spring.strength * (position_1.y - position_2.y);
|
|
///
|
|
/// // Silence borrow-checker: I have split your mutable borrow!
|
|
/// force_2.x += spring.strength * (position_2.x - position_1.x);
|
|
/// force_2.y += spring.strength * (position_2.y - position_1.y);
|
|
/// }
|
|
/// }
|
|
/// ```
|
|
///
|
|
/// # See also
|
|
///
|
|
/// - [`get_many_mut`](Self::get_many_mut) for the non panicking version.
|
|
/// - [`many`](Self::many) to get read-only query items.
|
|
#[inline]
|
|
#[track_caller]
|
|
#[deprecated(note = "Use `get_many_mut` instead and handle the Result.")]
|
|
pub fn many_mut<const N: usize>(&mut self, entities: [Entity; N]) -> [D::Item<'_>; N] {
|
|
match self.get_many_mut(entities) {
|
|
Ok(items) => items,
|
|
Err(error) => panic!("Cannot get query result: {error}"),
|
|
}
|
|
}
|
|
|
|
/// Returns the query item for the given [`Entity`].
|
|
///
|
|
/// In case of a nonexisting entity or mismatched component, a [`QueryEntityError`] is returned instead.
|
|
///
|
|
/// This is always guaranteed to run in `O(1)` time.
|
|
///
|
|
/// # Safety
|
|
///
|
|
/// This function makes it possible to violate Rust's aliasing guarantees.
|
|
/// You must make sure this call does not result in multiple mutable references to the same component.
|
|
///
|
|
/// # See also
|
|
///
|
|
/// - [`get_mut`](Self::get_mut) for the safe version.
|
|
#[inline]
|
|
pub unsafe fn get_unchecked(&self, entity: Entity) -> Result<D::Item<'_>, QueryEntityError> {
|
|
// SAFETY: The caller promises that this will not result in multiple mutable references.
|
|
unsafe { self.reborrow_unsafe() }.get_inner(entity)
|
|
}
|
|
|
|
/// Returns a single read-only query item when there is exactly one entity matching the query.
|
|
///
|
|
/// If the number of query items is not exactly one, a [`QuerySingleError`] is returned instead.
|
|
///
|
|
/// # Example
|
|
///
|
|
/// ```
|
|
/// # use bevy_ecs::prelude::*;
|
|
/// # use bevy_ecs::query::QuerySingleError;
|
|
/// # #[derive(Component)]
|
|
/// # struct PlayerScore(i32);
|
|
/// fn player_scoring_system(query: Query<&PlayerScore>) {
|
|
/// match query.single() {
|
|
/// Ok(PlayerScore(score)) => {
|
|
/// println!("Score: {}", score);
|
|
/// }
|
|
/// Err(QuerySingleError::NoEntities(_)) => {
|
|
/// println!("Error: There is no player!");
|
|
/// }
|
|
/// Err(QuerySingleError::MultipleEntities(_)) => {
|
|
/// println!("Error: There is more than one player!");
|
|
/// }
|
|
/// }
|
|
/// }
|
|
/// # bevy_ecs::system::assert_is_system(player_scoring_system);
|
|
/// ```
|
|
///
|
|
/// # See also
|
|
///
|
|
/// - [`single_mut`](Self::single_mut) to get the mutable query item.
|
|
#[inline]
|
|
pub fn single(&self) -> Result<ROQueryItem<'_, D>, QuerySingleError> {
|
|
self.as_readonly().single_inner()
|
|
}
|
|
|
|
/// A deprecated alias for [`single`](Self::single).
|
|
#[deprecated(note = "Please use `single` instead")]
|
|
pub fn get_single(&self) -> Result<ROQueryItem<'_, D>, QuerySingleError> {
|
|
self.single()
|
|
}
|
|
|
|
/// Returns a single query item when there is exactly one entity matching the query.
|
|
///
|
|
/// If the number of query items is not exactly one, a [`QuerySingleError`] is returned instead.
|
|
///
|
|
/// # Example
|
|
///
|
|
/// ```
|
|
/// # use bevy_ecs::prelude::*;
|
|
/// #
|
|
/// # #[derive(Component)]
|
|
/// # struct Player;
|
|
/// # #[derive(Component)]
|
|
/// # struct Health(u32);
|
|
/// #
|
|
/// fn regenerate_player_health_system(mut query: Query<&mut Health, With<Player>>) {
|
|
/// let mut health = query.single_mut().expect("Error: Could not find a single player.");
|
|
/// health.0 += 1;
|
|
/// }
|
|
/// # bevy_ecs::system::assert_is_system(regenerate_player_health_system);
|
|
/// ```
|
|
///
|
|
/// # See also
|
|
///
|
|
/// - [`single`](Self::single) to get the read-only query item.
|
|
#[inline]
|
|
pub fn single_mut(&mut self) -> Result<D::Item<'_>, QuerySingleError> {
|
|
self.reborrow().single_inner()
|
|
}
|
|
|
|
/// A deprecated alias for [`single_mut`](Self::single_mut).
|
|
#[deprecated(note = "Please use `single_mut` instead")]
|
|
pub fn get_single_mut(&mut self) -> Result<D::Item<'_>, QuerySingleError> {
|
|
self.single_mut()
|
|
}
|
|
|
|
/// Returns a single query item when there is exactly one entity matching the query.
|
|
/// This consumes the [`Query`] to return results with the actual "inner" world lifetime.
|
|
///
|
|
/// If the number of query items is not exactly one, a [`QuerySingleError`] is returned instead.
|
|
///
|
|
/// # Example
|
|
///
|
|
/// ```
|
|
/// # use bevy_ecs::prelude::*;
|
|
/// #
|
|
/// # #[derive(Component)]
|
|
/// # struct Player;
|
|
/// # #[derive(Component)]
|
|
/// # struct Health(u32);
|
|
/// #
|
|
/// fn regenerate_player_health_system(query: Query<&mut Health, With<Player>>) {
|
|
/// let mut health = query.single_inner().expect("Error: Could not find a single player.");
|
|
/// health.0 += 1;
|
|
/// }
|
|
/// # bevy_ecs::system::assert_is_system(regenerate_player_health_system);
|
|
/// ```
|
|
///
|
|
/// # See also
|
|
///
|
|
/// - [`single`](Self::single) to get the read-only query item.
|
|
/// - [`single_mut`](Self::single_mut) to get the mutable query item.
|
|
/// - [`single_inner`](Self::single_inner) for the panicking version.
|
|
#[inline]
|
|
pub fn single_inner(self) -> Result<D::Item<'w>, QuerySingleError> {
|
|
let mut query = self.into_iter();
|
|
let first = query.next();
|
|
let extra = query.next().is_some();
|
|
|
|
match (first, extra) {
|
|
(Some(r), false) => Ok(r),
|
|
(None, _) => Err(QuerySingleError::NoEntities(core::any::type_name::<Self>())),
|
|
(Some(_), _) => Err(QuerySingleError::MultipleEntities(core::any::type_name::<
|
|
Self,
|
|
>())),
|
|
}
|
|
}
|
|
|
|
/// Returns `true` if there are no query items.
|
|
///
|
|
/// This is equivalent to `self.iter().next().is_none()`, and thus the worst case runtime will be `O(n)`
|
|
/// where `n` is the number of *potential* matches. This can be notably expensive for queries that rely
|
|
/// on non-archetypal filters such as [`Added`] or [`Changed`] which must individually check each query
|
|
/// result for a match.
|
|
///
|
|
/// # Example
|
|
///
|
|
/// Here, the score is increased only if an entity with a `Player` component is present in the world:
|
|
///
|
|
/// ```
|
|
/// # use bevy_ecs::prelude::*;
|
|
/// #
|
|
/// # #[derive(Component)]
|
|
/// # struct Player;
|
|
/// # #[derive(Resource)]
|
|
/// # struct Score(u32);
|
|
/// fn update_score_system(query: Query<(), With<Player>>, mut score: ResMut<Score>) {
|
|
/// if !query.is_empty() {
|
|
/// score.0 += 1;
|
|
/// }
|
|
/// }
|
|
/// # bevy_ecs::system::assert_is_system(update_score_system);
|
|
/// ```
|
|
///
|
|
/// [`Added`]: crate::query::Added
|
|
/// [`Changed`]: crate::query::Changed
|
|
#[inline]
|
|
pub fn is_empty(&self) -> bool {
|
|
self.as_nop().iter().next().is_none()
|
|
}
|
|
|
|
/// Returns `true` if the given [`Entity`] matches the query.
|
|
///
|
|
/// This is always guaranteed to run in `O(1)` time.
|
|
///
|
|
/// # Example
|
|
///
|
|
/// ```
|
|
/// # use bevy_ecs::prelude::*;
|
|
/// #
|
|
/// # #[derive(Component)]
|
|
/// # struct InRange;
|
|
/// #
|
|
/// # #[derive(Resource)]
|
|
/// # struct Target {
|
|
/// # entity: Entity,
|
|
/// # }
|
|
/// #
|
|
/// fn targeting_system(in_range_query: Query<&InRange>, target: Res<Target>) {
|
|
/// if in_range_query.contains(target.entity) {
|
|
/// println!("Bam!")
|
|
/// }
|
|
/// }
|
|
/// # bevy_ecs::system::assert_is_system(targeting_system);
|
|
/// ```
|
|
#[inline]
|
|
pub fn contains(&self, entity: Entity) -> bool {
|
|
self.as_nop().get(entity).is_ok()
|
|
}
|
|
|
|
/// Returns a [`QueryLens`] that can be used to get a query with a more general fetch.
|
|
///
|
|
/// For example, this can transform a `Query<(&A, &mut B)>` to a `Query<&B>`.
|
|
/// This can be useful for passing the query to another function. Note that since
|
|
/// filter terms are dropped, non-archetypal filters like [`Added`](crate::query::Added) and
|
|
/// [`Changed`](crate::query::Changed) will not be respected. To maintain or change filter
|
|
/// terms see [`Self::transmute_lens_filtered`]
|
|
///
|
|
/// ## Panics
|
|
///
|
|
/// This will panic if `NewD` is not a subset of the original fetch `D`
|
|
///
|
|
/// ## Example
|
|
///
|
|
/// ```rust
|
|
/// # use bevy_ecs::prelude::*;
|
|
/// # use bevy_ecs::system::QueryLens;
|
|
/// #
|
|
/// # #[derive(Component)]
|
|
/// # struct A(usize);
|
|
/// #
|
|
/// # #[derive(Component)]
|
|
/// # struct B(usize);
|
|
/// #
|
|
/// # let mut world = World::new();
|
|
/// #
|
|
/// # world.spawn((A(10), B(5)));
|
|
/// #
|
|
/// fn reusable_function(lens: &mut QueryLens<&A>) {
|
|
/// assert_eq!(lens.query().single().unwrap().0, 10);
|
|
/// }
|
|
///
|
|
/// // We can use the function in a system that takes the exact query.
|
|
/// fn system_1(mut query: Query<&A>) {
|
|
/// reusable_function(&mut query.as_query_lens());
|
|
/// }
|
|
///
|
|
/// // We can also use it with a query that does not match exactly
|
|
/// // by transmuting it.
|
|
/// fn system_2(mut query: Query<(&mut A, &B)>) {
|
|
/// let mut lens = query.transmute_lens::<&A>();
|
|
/// reusable_function(&mut lens);
|
|
/// }
|
|
///
|
|
/// # let mut schedule = Schedule::default();
|
|
/// # schedule.add_systems((system_1, system_2));
|
|
/// # schedule.run(&mut world);
|
|
/// ```
|
|
///
|
|
/// ## Allowed Transmutes
|
|
///
|
|
/// Besides removing parameters from the query,
|
|
/// you can also make limited changes to the types of parameters.
|
|
/// The new query must have a subset of the *read*, *write*, and *required* access of the original query.
|
|
///
|
|
/// * `&mut T` and [`Mut<T>`](crate::change_detection::Mut) have read, write, and required access to `T`
|
|
/// * `&T` and [`Ref<T>`](crate::change_detection::Ref) have read and required access to `T`
|
|
/// * [`Option<D>`] and [`AnyOf<(D, ...)>`](crate::query::AnyOf) have the read and write access of the subqueries, but no required access
|
|
/// * Tuples of query data and `#[derive(QueryData)]` structs have the union of the access of their subqueries
|
|
/// * [`EntityMut`](crate::world::EntityMut) has read and write access to all components, but no required access
|
|
/// * [`EntityRef`](crate::world::EntityRef) has read access to all components, but no required access
|
|
/// * [`Entity`], [`EntityLocation`], [`&Archetype`], [`Has<T>`], and [`PhantomData<T>`] have no access at all,
|
|
/// so can be added to any query
|
|
/// * [`FilteredEntityRef`](crate::world::FilteredEntityRef) and [`FilteredEntityMut`](crate::world::FilteredEntityMut)
|
|
/// have access determined by the [`QueryBuilder`](crate::query::QueryBuilder) used to construct them.
|
|
/// Any query can be transmuted to them, and they will receive the access of the source query,
|
|
/// but only if they are the top-level query and not nested
|
|
/// * [`Added<T>`](crate::query::Added) and [`Changed<T>`](crate::query::Changed) filters have read and required access to `T`
|
|
/// * [`With<T>`](crate::query::With) and [`Without<T>`](crate::query::Without) filters have no access at all,
|
|
/// so can be added to any query
|
|
/// * Tuples of query filters and `#[derive(QueryFilter)]` structs have the union of the access of their subqueries
|
|
/// * [`Or<(F, ...)>`](crate::query::Or) filters have the read access of the subqueries, but no required access
|
|
///
|
|
/// ### Examples of valid transmutes
|
|
///
|
|
/// ```rust
|
|
/// # use bevy_ecs::{
|
|
/// # prelude::*,
|
|
/// # archetype::Archetype,
|
|
/// # entity::EntityLocation,
|
|
/// # query::{QueryData, QueryFilter},
|
|
/// # world::{FilteredEntityMut, FilteredEntityRef},
|
|
/// # };
|
|
/// # use std::marker::PhantomData;
|
|
/// #
|
|
/// # fn assert_valid_transmute<OldD: QueryData, NewD: QueryData>() {
|
|
/// # assert_valid_transmute_filtered::<OldD, (), NewD, ()>();
|
|
/// # }
|
|
/// #
|
|
/// # fn assert_valid_transmute_filtered<OldD: QueryData, OldF: QueryFilter, NewD: QueryData, NewF: QueryFilter>() {
|
|
/// # let mut world = World::new();
|
|
/// # // Make sure all components in the new query are initialized
|
|
/// # let state = world.query_filtered::<NewD, NewF>();
|
|
/// # let state = world.query_filtered::<OldD, OldF>();
|
|
/// # state.transmute_filtered::<NewD, NewF>(&world);
|
|
/// # }
|
|
/// #
|
|
/// # #[derive(Component)]
|
|
/// # struct T;
|
|
/// #
|
|
/// # #[derive(Component)]
|
|
/// # struct U;
|
|
/// #
|
|
/// # #[derive(Component)]
|
|
/// # struct V;
|
|
/// #
|
|
/// // `&mut T` and `Mut<T>` access the same data and can be transmuted to each other,
|
|
/// // `&T` and `Ref<T>` access the same data and can be transmuted to each other,
|
|
/// // and mutable versions can be transmuted to read-only versions
|
|
/// assert_valid_transmute::<&mut T, &T>();
|
|
/// assert_valid_transmute::<&mut T, Mut<T>>();
|
|
/// assert_valid_transmute::<Mut<T>, &mut T>();
|
|
/// assert_valid_transmute::<&T, Ref<T>>();
|
|
/// assert_valid_transmute::<Ref<T>, &T>();
|
|
///
|
|
/// // The structure can be rearranged, or subqueries dropped
|
|
/// assert_valid_transmute::<(&T, &U), &T>();
|
|
/// assert_valid_transmute::<((&T, &U), &V), (&T, (&U, &V))>();
|
|
/// assert_valid_transmute::<Option<(&T, &U)>, (Option<&T>, Option<&U>)>();
|
|
///
|
|
/// // Queries with no access can be freely added
|
|
/// assert_valid_transmute::<
|
|
/// &T,
|
|
/// (&T, Entity, EntityLocation, &Archetype, Has<U>, PhantomData<T>),
|
|
/// >();
|
|
///
|
|
/// // Required access can be transmuted to optional,
|
|
/// // and optional access can be transmuted to other optional access
|
|
/// assert_valid_transmute::<&T, Option<&T>>();
|
|
/// assert_valid_transmute::<AnyOf<(&mut T, &mut U)>, Option<&T>>();
|
|
/// // Note that removing subqueries from `AnyOf` will result
|
|
/// // in an `AnyOf` where all subqueries can yield `None`!
|
|
/// assert_valid_transmute::<AnyOf<(&T, &U, &V)>, AnyOf<(&T, &U)>>();
|
|
/// assert_valid_transmute::<EntityMut, Option<&mut T>>();
|
|
///
|
|
/// // Anything can be transmuted to `FilteredEntityRef` or `FilteredEntityMut`
|
|
/// // This will create a `FilteredEntityMut` that only has read access to `T`
|
|
/// assert_valid_transmute::<&T, FilteredEntityMut>();
|
|
/// // This transmute will succeed, but the `FilteredEntityMut` will have no access!
|
|
/// // It must be the top-level query to be given access, but here it is nested in a tuple.
|
|
/// assert_valid_transmute::<&T, (Entity, FilteredEntityMut)>();
|
|
///
|
|
/// // `Added<T>` and `Changed<T>` filters have the same access as `&T` data
|
|
/// // Remember that they are only evaluated on the transmuted query, not the original query!
|
|
/// assert_valid_transmute_filtered::<Entity, Changed<T>, &T, ()>();
|
|
/// assert_valid_transmute_filtered::<&mut T, (), &T, Added<T>>();
|
|
/// // Nested inside of an `Or` filter, they have the same access as `Option<&T>`.
|
|
/// assert_valid_transmute_filtered::<Option<&T>, (), Entity, Or<(Changed<T>, With<U>)>>();
|
|
/// ```
|
|
///
|
|
/// [`EntityLocation`]: crate::entity::EntityLocation
|
|
/// [`&Archetype`]: crate::archetype::Archetype
|
|
/// [`Has<T>`]: crate::query::Has
|
|
#[track_caller]
|
|
pub fn transmute_lens<NewD: QueryData>(&mut self) -> QueryLens<'_, NewD> {
|
|
self.transmute_lens_filtered::<NewD, ()>()
|
|
}
|
|
|
|
/// Returns a [`QueryLens`] that can be used to get a query with a more general fetch.
|
|
/// This consumes the [`Query`] to return results with the actual "inner" world lifetime.
|
|
///
|
|
/// For example, this can transform a `Query<(&A, &mut B)>` to a `Query<&B>`.
|
|
/// This can be useful for passing the query to another function. Note that since
|
|
/// filter terms are dropped, non-archetypal filters like [`Added`](crate::query::Added) and
|
|
/// [`Changed`](crate::query::Changed) will not be respected. To maintain or change filter
|
|
/// terms see [`Self::transmute_lens_filtered`]
|
|
///
|
|
/// ## Panics
|
|
///
|
|
/// This will panic if `NewD` is not a subset of the original fetch `Q`
|
|
///
|
|
/// ## Example
|
|
///
|
|
/// ```rust
|
|
/// # use bevy_ecs::prelude::*;
|
|
/// # use bevy_ecs::system::QueryLens;
|
|
/// #
|
|
/// # #[derive(Component)]
|
|
/// # struct A(usize);
|
|
/// #
|
|
/// # #[derive(Component)]
|
|
/// # struct B(usize);
|
|
/// #
|
|
/// # let mut world = World::new();
|
|
/// #
|
|
/// # world.spawn((A(10), B(5)));
|
|
/// #
|
|
/// fn reusable_function(mut lens: QueryLens<&A>) {
|
|
/// assert_eq!(lens.query().single().unwrap().0, 10);
|
|
/// }
|
|
///
|
|
/// // We can use the function in a system that takes the exact query.
|
|
/// fn system_1(query: Query<&A>) {
|
|
/// reusable_function(query.into_query_lens());
|
|
/// }
|
|
///
|
|
/// // We can also use it with a query that does not match exactly
|
|
/// // by transmuting it.
|
|
/// fn system_2(query: Query<(&mut A, &B)>) {
|
|
/// let mut lens = query.transmute_lens_inner::<&A>();
|
|
/// reusable_function(lens);
|
|
/// }
|
|
///
|
|
/// # let mut schedule = Schedule::default();
|
|
/// # schedule.add_systems((system_1, system_2));
|
|
/// # schedule.run(&mut world);
|
|
/// ```
|
|
///
|
|
/// ## Allowed Transmutes
|
|
///
|
|
/// Besides removing parameters from the query, you can also
|
|
/// make limited changes to the types of parameters.
|
|
///
|
|
/// * Can always add/remove [`Entity`]
|
|
/// * Can always add/remove [`EntityLocation`]
|
|
/// * Can always add/remove [`&Archetype`]
|
|
/// * `Ref<T>` <-> `&T`
|
|
/// * `&mut T` -> `&T`
|
|
/// * `&mut T` -> `Ref<T>`
|
|
/// * [`EntityMut`](crate::world::EntityMut) -> [`EntityRef`](crate::world::EntityRef)
|
|
///
|
|
/// [`EntityLocation`]: crate::entity::EntityLocation
|
|
/// [`&Archetype`]: crate::archetype::Archetype
|
|
///
|
|
/// # See also
|
|
///
|
|
/// - [`transmute_lens`](Self::transmute_lens) to convert to a lens using a mutable borrow of the [`Query`].
|
|
#[track_caller]
|
|
pub fn transmute_lens_inner<NewD: QueryData>(self) -> QueryLens<'w, NewD> {
|
|
self.transmute_lens_filtered_inner::<NewD, ()>()
|
|
}
|
|
|
|
/// Equivalent to [`Self::transmute_lens`] but also includes a [`QueryFilter`] type.
|
|
///
|
|
/// Note that the lens will iterate the same tables and archetypes as the original query. This means that
|
|
/// additional archetypal query terms like [`With`](crate::query::With) and [`Without`](crate::query::Without)
|
|
/// will not necessarily be respected and non-archetypal terms like [`Added`](crate::query::Added) and
|
|
/// [`Changed`](crate::query::Changed) will only be respected if they are in the type signature.
|
|
#[track_caller]
|
|
pub fn transmute_lens_filtered<NewD: QueryData, NewF: QueryFilter>(
|
|
&mut self,
|
|
) -> QueryLens<'_, NewD, NewF> {
|
|
self.reborrow().transmute_lens_filtered_inner()
|
|
}
|
|
|
|
/// Equivalent to [`Self::transmute_lens_inner`] but also includes a [`QueryFilter`] type.
|
|
/// This consumes the [`Query`] to return results with the actual "inner" world lifetime.
|
|
///
|
|
/// Note that the lens will iterate the same tables and archetypes as the original query. This means that
|
|
/// additional archetypal query terms like [`With`](crate::query::With) and [`Without`](crate::query::Without)
|
|
/// will not necessarily be respected and non-archetypal terms like [`Added`](crate::query::Added) and
|
|
/// [`Changed`](crate::query::Changed) will only be respected if they are in the type signature.
|
|
///
|
|
/// # See also
|
|
///
|
|
/// - [`transmute_lens_filtered`](Self::transmute_lens_filtered) to convert to a lens using a mutable borrow of the [`Query`].
|
|
#[track_caller]
|
|
pub fn transmute_lens_filtered_inner<NewD: QueryData, NewF: QueryFilter>(
|
|
self,
|
|
) -> QueryLens<'w, NewD, NewF> {
|
|
let state = self.state.transmute_filtered::<NewD, NewF>(self.world);
|
|
QueryLens {
|
|
world: self.world,
|
|
state,
|
|
last_run: self.last_run,
|
|
this_run: self.this_run,
|
|
}
|
|
}
|
|
|
|
/// Gets a [`QueryLens`] with the same accesses as the existing query
|
|
pub fn as_query_lens(&mut self) -> QueryLens<'_, D> {
|
|
self.transmute_lens()
|
|
}
|
|
|
|
/// Gets a [`QueryLens`] with the same accesses as the existing query
|
|
///
|
|
/// # See also
|
|
///
|
|
/// - [`as_query_lens`](Self::as_query_lens) to convert to a lens using a mutable borrow of the [`Query`].
|
|
pub fn into_query_lens(self) -> QueryLens<'w, D> {
|
|
self.transmute_lens_inner()
|
|
}
|
|
|
|
/// Returns a [`QueryLens`] that can be used to get a query with the combined fetch.
|
|
///
|
|
/// For example, this can take a `Query<&A>` and a `Query<&B>` and return a `Query<(&A, &B)>`.
|
|
/// The returned query will only return items with both `A` and `B`. Note that since filters
|
|
/// are dropped, non-archetypal filters like `Added` and `Changed` will not be respected.
|
|
/// To maintain or change filter terms see `Self::join_filtered`.
|
|
///
|
|
/// ## Example
|
|
///
|
|
/// ```rust
|
|
/// # use bevy_ecs::prelude::*;
|
|
/// # use bevy_ecs::system::QueryLens;
|
|
/// #
|
|
/// # #[derive(Component)]
|
|
/// # struct Transform;
|
|
/// #
|
|
/// # #[derive(Component)]
|
|
/// # struct Player;
|
|
/// #
|
|
/// # #[derive(Component)]
|
|
/// # struct Enemy;
|
|
/// #
|
|
/// # let mut world = World::default();
|
|
/// # world.spawn((Transform, Player));
|
|
/// # world.spawn((Transform, Enemy));
|
|
///
|
|
/// fn system(
|
|
/// mut transforms: Query<&Transform>,
|
|
/// mut players: Query<&Player>,
|
|
/// mut enemies: Query<&Enemy>
|
|
/// ) {
|
|
/// let mut players_transforms: QueryLens<(&Transform, &Player)> = transforms.join(&mut players);
|
|
/// for (transform, player) in &players_transforms.query() {
|
|
/// // do something with a and b
|
|
/// }
|
|
///
|
|
/// let mut enemies_transforms: QueryLens<(&Transform, &Enemy)> = transforms.join(&mut enemies);
|
|
/// for (transform, enemy) in &enemies_transforms.query() {
|
|
/// // do something with a and b
|
|
/// }
|
|
/// }
|
|
///
|
|
/// # let mut schedule = Schedule::default();
|
|
/// # schedule.add_systems(system);
|
|
/// # schedule.run(&mut world);
|
|
/// ```
|
|
/// ## Panics
|
|
///
|
|
/// This will panic if `NewD` is not a subset of the union of the original fetch `Q` and `OtherD`.
|
|
///
|
|
/// ## Allowed Transmutes
|
|
///
|
|
/// Like `transmute_lens` the query terms can be changed with some restrictions.
|
|
/// See [`Self::transmute_lens`] for more details.
|
|
pub fn join<'a, OtherD: QueryData, NewD: QueryData>(
|
|
&'a mut self,
|
|
other: &'a mut Query<OtherD>,
|
|
) -> QueryLens<'a, NewD> {
|
|
self.join_filtered(other)
|
|
}
|
|
|
|
/// Returns a [`QueryLens`] that can be used to get a query with the combined fetch.
|
|
/// This consumes the [`Query`] to return results with the actual "inner" world lifetime.
|
|
///
|
|
/// For example, this can take a `Query<&A>` and a `Query<&B>` and return a `Query<(&A, &B)>`.
|
|
/// The returned query will only return items with both `A` and `B`. Note that since filters
|
|
/// are dropped, non-archetypal filters like `Added` and `Changed` will not be respected.
|
|
/// To maintain or change filter terms see `Self::join_filtered`.
|
|
///
|
|
/// ## Panics
|
|
///
|
|
/// This will panic if `NewD` is not a subset of the union of the original fetch `Q` and `OtherD`.
|
|
///
|
|
/// ## Allowed Transmutes
|
|
///
|
|
/// Like `transmute_lens` the query terms can be changed with some restrictions.
|
|
/// See [`Self::transmute_lens`] for more details.
|
|
///
|
|
/// # See also
|
|
///
|
|
/// - [`join`](Self::join) to join using a mutable borrow of the [`Query`].
|
|
pub fn join_inner<OtherD: QueryData, NewD: QueryData>(
|
|
self,
|
|
other: Query<'w, '_, OtherD>,
|
|
) -> QueryLens<'w, NewD> {
|
|
self.join_filtered_inner(other)
|
|
}
|
|
|
|
/// Equivalent to [`Self::join`] but also includes a [`QueryFilter`] type.
|
|
///
|
|
/// Note that the lens with iterate a subset of the original queries' tables
|
|
/// and archetypes. This means that additional archetypal query terms like
|
|
/// `With` and `Without` will not necessarily be respected and non-archetypal
|
|
/// terms like `Added` and `Changed` will only be respected if they are in
|
|
/// the type signature.
|
|
pub fn join_filtered<
|
|
'a,
|
|
OtherD: QueryData,
|
|
OtherF: QueryFilter,
|
|
NewD: QueryData,
|
|
NewF: QueryFilter,
|
|
>(
|
|
&'a mut self,
|
|
other: &'a mut Query<OtherD, OtherF>,
|
|
) -> QueryLens<'a, NewD, NewF> {
|
|
self.reborrow().join_filtered_inner(other.reborrow())
|
|
}
|
|
|
|
/// Equivalent to [`Self::join_inner`] but also includes a [`QueryFilter`] type.
|
|
/// This consumes the [`Query`] to return results with the actual "inner" world lifetime.
|
|
///
|
|
/// Note that the lens with iterate a subset of the original queries' tables
|
|
/// and archetypes. This means that additional archetypal query terms like
|
|
/// `With` and `Without` will not necessarily be respected and non-archetypal
|
|
/// terms like `Added` and `Changed` will only be respected if they are in
|
|
/// the type signature.
|
|
///
|
|
/// # See also
|
|
///
|
|
/// - [`join_filtered`](Self::join_filtered) to join using a mutable borrow of the [`Query`].
|
|
pub fn join_filtered_inner<
|
|
OtherD: QueryData,
|
|
OtherF: QueryFilter,
|
|
NewD: QueryData,
|
|
NewF: QueryFilter,
|
|
>(
|
|
self,
|
|
other: Query<'w, '_, OtherD, OtherF>,
|
|
) -> QueryLens<'w, NewD, NewF> {
|
|
let state = self
|
|
.state
|
|
.join_filtered::<OtherD, OtherF, NewD, NewF>(self.world, other.state);
|
|
QueryLens {
|
|
world: self.world,
|
|
state,
|
|
last_run: self.last_run,
|
|
this_run: self.this_run,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl<'w, 's, D: QueryData, F: QueryFilter> IntoIterator for Query<'w, 's, D, F> {
|
|
type Item = D::Item<'w>;
|
|
type IntoIter = QueryIter<'w, 's, D, F>;
|
|
|
|
fn into_iter(self) -> Self::IntoIter {
|
|
// SAFETY:
|
|
// - `self.world` has permission to access the required components.
|
|
// - We consume the query, so mutable queries cannot alias.
|
|
// Read-only queries are `Copy`, but may alias themselves.
|
|
unsafe { QueryIter::new(self.world, self.state, self.last_run, self.this_run) }
|
|
}
|
|
}
|
|
|
|
impl<'w, 's, D: QueryData, F: QueryFilter> IntoIterator for &'w Query<'_, 's, D, F> {
|
|
type Item = ROQueryItem<'w, D>;
|
|
type IntoIter = QueryIter<'w, 's, D::ReadOnly, F>;
|
|
|
|
fn into_iter(self) -> Self::IntoIter {
|
|
self.iter()
|
|
}
|
|
}
|
|
|
|
impl<'w, 's, D: QueryData, F: QueryFilter> IntoIterator for &'w mut Query<'_, 's, D, F> {
|
|
type Item = D::Item<'w>;
|
|
type IntoIter = QueryIter<'w, 's, D, F>;
|
|
|
|
fn into_iter(self) -> Self::IntoIter {
|
|
self.iter_mut()
|
|
}
|
|
}
|
|
|
|
impl<'w, 's, D: ReadOnlyQueryData, F: QueryFilter> Query<'w, 's, D, F> {
|
|
/// Returns an [`Iterator`] over the query items, with the actual "inner" world lifetime.
|
|
///
|
|
/// This can only return immutable data (mutable data will be cast to an immutable form).
|
|
/// See [`Self::iter_mut`] for queries that contain at least one mutable component.
|
|
///
|
|
/// # Example
|
|
///
|
|
/// Here, the `report_names_system` iterates over the `Player` component of every entity
|
|
/// that contains it:
|
|
///
|
|
/// ```
|
|
/// # use bevy_ecs::prelude::*;
|
|
/// #
|
|
/// # #[derive(Component)]
|
|
/// # struct Player { name: String }
|
|
/// #
|
|
/// fn report_names_system(query: Query<&Player>) {
|
|
/// for player in &query {
|
|
/// println!("Say hello to {}!", player.name);
|
|
/// }
|
|
/// }
|
|
/// # bevy_ecs::system::assert_is_system(report_names_system);
|
|
/// ```
|
|
#[inline]
|
|
pub fn iter_inner(&self) -> QueryIter<'w, 's, D::ReadOnly, F> {
|
|
(*self).into_iter()
|
|
}
|
|
}
|
|
|
|
/// Type returned from [`Query::transmute_lens`] containing the new [`QueryState`].
|
|
///
|
|
/// Call [`query`](QueryLens::query) or [`into`](Into::into) to construct the resulting [`Query`]
|
|
pub struct QueryLens<'w, Q: QueryData, F: QueryFilter = ()> {
|
|
world: UnsafeWorldCell<'w>,
|
|
state: QueryState<Q, F>,
|
|
last_run: Tick,
|
|
this_run: Tick,
|
|
}
|
|
|
|
impl<'w, Q: QueryData, F: QueryFilter> QueryLens<'w, Q, F> {
|
|
/// Create a [`Query`] from the underlying [`QueryState`].
|
|
pub fn query(&mut self) -> Query<'_, '_, Q, F> {
|
|
Query {
|
|
world: self.world,
|
|
state: &self.state,
|
|
last_run: self.last_run,
|
|
this_run: self.this_run,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl<'w, Q: ReadOnlyQueryData, F: QueryFilter> QueryLens<'w, Q, F> {
|
|
/// Create a [`Query`] from the underlying [`QueryState`].
|
|
/// This returns results with the actual "inner" world lifetime,
|
|
/// so it may only be used with read-only queries to prevent mutable aliasing.
|
|
pub fn query_inner(&self) -> Query<'w, '_, Q, F> {
|
|
Query {
|
|
world: self.world,
|
|
state: &self.state,
|
|
last_run: self.last_run,
|
|
this_run: self.this_run,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl<'w, 's, Q: QueryData, F: QueryFilter> From<&'s mut QueryLens<'w, Q, F>>
|
|
for Query<'s, 's, Q, F>
|
|
{
|
|
fn from(value: &'s mut QueryLens<'w, Q, F>) -> Query<'s, 's, Q, F> {
|
|
value.query()
|
|
}
|
|
}
|
|
|
|
impl<'w, 'q, Q: QueryData, F: QueryFilter> From<&'q mut Query<'w, '_, Q, F>>
|
|
for QueryLens<'q, Q, F>
|
|
{
|
|
fn from(value: &'q mut Query<'w, '_, Q, F>) -> QueryLens<'q, Q, F> {
|
|
value.transmute_lens_filtered()
|
|
}
|
|
}
|
|
|
|
/// [System parameter] that provides access to single entity's components, much like [`Query::single`]/[`Query::single_mut`].
|
|
///
|
|
/// This [`SystemParam`](crate::system::SystemParam) fails validation if zero or more than one matching entity exists.
|
|
/// This will cause the system to be skipped, according to the rules laid out in [`SystemParamValidationError`](crate::system::SystemParamValidationError).
|
|
///
|
|
/// Use [`Option<Single<D, F>>`] instead if zero or one matching entities can exist.
|
|
///
|
|
/// See [`Query`] for more details.
|
|
///
|
|
/// [System parameter]: crate::system::SystemParam
|
|
pub struct Single<'w, D: QueryData, F: QueryFilter = ()> {
|
|
pub(crate) item: D::Item<'w>,
|
|
pub(crate) _filter: PhantomData<F>,
|
|
}
|
|
|
|
impl<'w, D: QueryData, F: QueryFilter> Deref for Single<'w, D, F> {
|
|
type Target = D::Item<'w>;
|
|
|
|
fn deref(&self) -> &Self::Target {
|
|
&self.item
|
|
}
|
|
}
|
|
|
|
impl<'w, D: QueryData, F: QueryFilter> DerefMut for Single<'w, D, F> {
|
|
fn deref_mut(&mut self) -> &mut Self::Target {
|
|
&mut self.item
|
|
}
|
|
}
|
|
|
|
impl<'w, D: QueryData, F: QueryFilter> Single<'w, D, F> {
|
|
/// Returns the inner item with ownership.
|
|
pub fn into_inner(self) -> D::Item<'w> {
|
|
self.item
|
|
}
|
|
}
|
|
|
|
/// [System parameter] that works very much like [`Query`] except it always contains at least one matching entity.
|
|
///
|
|
/// This [`SystemParam`](crate::system::SystemParam) fails validation if no matching entities exist.
|
|
/// This will cause the system to be skipped, according to the rules laid out in [`SystemParamValidationError`](crate::system::SystemParamValidationError).
|
|
///
|
|
/// Much like [`Query::is_empty`] the worst case runtime will be `O(n)` where `n` is the number of *potential* matches.
|
|
/// This can be notably expensive for queries that rely on non-archetypal filters such as [`Added`](crate::query::Added) or [`Changed`](crate::query::Changed)
|
|
/// which must individually check each query result for a match.
|
|
///
|
|
/// See [`Query`] for more details.
|
|
///
|
|
/// [System parameter]: crate::system::SystemParam
|
|
pub struct Populated<'w, 's, D: QueryData, F: QueryFilter = ()>(pub(crate) Query<'w, 's, D, F>);
|
|
|
|
impl<'w, 's, D: QueryData, F: QueryFilter> Deref for Populated<'w, 's, D, F> {
|
|
type Target = Query<'w, 's, D, F>;
|
|
|
|
fn deref(&self) -> &Self::Target {
|
|
&self.0
|
|
}
|
|
}
|
|
|
|
impl<D: QueryData, F: QueryFilter> DerefMut for Populated<'_, '_, D, F> {
|
|
fn deref_mut(&mut self) -> &mut Self::Target {
|
|
&mut self.0
|
|
}
|
|
}
|
|
|
|
impl<'w, 's, D: QueryData, F: QueryFilter> Populated<'w, 's, D, F> {
|
|
/// Returns the inner item with ownership.
|
|
pub fn into_inner(self) -> Query<'w, 's, D, F> {
|
|
self.0
|
|
}
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use crate::{prelude::*, query::QueryEntityError};
|
|
use alloc::vec::Vec;
|
|
|
|
#[test]
|
|
fn get_many_uniqueness() {
|
|
let mut world = World::new();
|
|
|
|
let entities: Vec<Entity> = (0..10).map(|_| world.spawn_empty().id()).collect();
|
|
|
|
let mut query_state = world.query::<Entity>();
|
|
|
|
// It's best to test get_many_mut_inner directly, as it is shared
|
|
// We don't care about aliased mutability for the read-only equivalent
|
|
|
|
// SAFETY: Query does not access world data.
|
|
assert!(query_state
|
|
.query_mut(&mut world)
|
|
.get_many_mut_inner::<10>(entities.clone().try_into().unwrap())
|
|
.is_ok());
|
|
|
|
assert_eq!(
|
|
query_state
|
|
.query_mut(&mut world)
|
|
.get_many_mut_inner([entities[0], entities[0]])
|
|
.unwrap_err(),
|
|
QueryEntityError::AliasedMutability(entities[0])
|
|
);
|
|
|
|
assert_eq!(
|
|
query_state
|
|
.query_mut(&mut world)
|
|
.get_many_mut_inner([entities[0], entities[1], entities[0]])
|
|
.unwrap_err(),
|
|
QueryEntityError::AliasedMutability(entities[0])
|
|
);
|
|
|
|
assert_eq!(
|
|
query_state
|
|
.query_mut(&mut world)
|
|
.get_many_mut_inner([entities[9], entities[9]])
|
|
.unwrap_err(),
|
|
QueryEntityError::AliasedMutability(entities[9])
|
|
);
|
|
}
|
|
}
|