Skip to content

Commit 2bda628

Browse files
Clarify docs for transmute_lens functions (#19233)
# Objective Make the restrictions of `transmute_lens` and related functions clearer. Related issue: #12156 Related PR: #12157 ## Solution * Make it clearer that the set of returned entities is a subset of those from the original query * Move description of read/write/required access to a table * Reference the new table in `transmute_lens` docs from the other `transmute_lens*` functions ## Testing cargo doc --open locally to check this render correctly --------- Co-authored-by: Chris Russell <[email protected]>
1 parent 4836c78 commit 2bda628

File tree

1 file changed

+67
-59
lines changed

1 file changed

+67
-59
lines changed

crates/bevy_ecs/src/system/query.rs

Lines changed: 67 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -2016,17 +2016,67 @@ impl<'w, 's, D: QueryData, F: QueryFilter> Query<'w, 's, D, F> {
20162016
self.as_nop().get(entity).is_ok()
20172017
}
20182018

2019-
/// Returns a [`QueryLens`] that can be used to get a query with a more general fetch.
2019+
/// Returns a [`QueryLens`] that can be used to construct a new [`Query`] giving more
2020+
/// restrictive access to the entities matched by the current query.
2021+
///
2022+
/// A transmute is valid only if `NewD` has a subset of the read, write, and required access
2023+
/// of the current query. A precise description of the access required by each parameter
2024+
/// type is given in the table below, but typical uses are to:
2025+
/// * Remove components, e.g. `Query<(&A, &B)>` to `Query<&A>`.
2026+
/// * Retrieve an existing component with reduced or equal access, e.g. `Query<&mut A>` to `Query<&A>`
2027+
/// or `Query<&T>` to `Query<Ref<T>>`.
2028+
/// * Add parameters with no new access, for example adding an `Entity` parameter.
2029+
///
2030+
/// Note that since filter terms are dropped, non-archetypal filters like
2031+
/// [`Added`], [`Changed`] and [`Spawned`] will not be respected. To maintain or change filter
2032+
/// terms see [`Self::transmute_lens_filtered`].
2033+
///
2034+
/// |`QueryData` parameter type|Access required|
2035+
/// |----|----|
2036+
/// |[`Entity`], [`EntityLocation`], [`SpawnDetails`], [`&Archetype`], [`Has<T>`], [`PhantomData<T>`]|No access|
2037+
/// |[`EntityMut`]|Read and write access to all components, but no required access|
2038+
/// |[`EntityRef`]|Read access to all components, but no required access|
2039+
/// |`&T`, [`Ref<T>`]|Read and required access to `T`|
2040+
/// |`&mut T`, [`Mut<T>`]|Read, write and required access to `T`|
2041+
/// |[`Option<T>`], [`AnyOf<(D, ...)>`]|Read and write access to `T`, but no required access|
2042+
/// |Tuples of query data and<br/>`#[derive(QueryData)]` structs|The union of the access of their subqueries|
2043+
/// |[`FilteredEntityRef`], [`FilteredEntityMut`]|Determined by the [`QueryBuilder`] used to construct them. Any query can be transmuted to them, and they will receive the access of the source query. When combined with other `QueryData`, they will receive any access of the source query that does not conflict with the other data|
2044+
///
2045+
/// `transmute_lens` drops filter terms, but [`Self::transmute_lens_filtered`] supports returning a [`QueryLens`] with a new
2046+
/// filter type - the access required by filter parameters are as follows.
2047+
///
2048+
/// |`QueryFilter` parameter type|Access required|
2049+
/// |----|----|
2050+
/// |[`Added<T>`], [`Changed<T>`]|Read and required access to `T`|
2051+
/// |[`With<T>`], [`Without<T>`]|No access|
2052+
/// |[`Or<(T, ...)>`]|Read access of the subqueries, but no required access|
2053+
/// |Tuples of query filters and `#[derive(QueryFilter)]` structs|The union of the access of their subqueries|
20202054
///
2021-
/// For example, this can transform a `Query<(&A, &mut B)>` to a `Query<&B>`.
2022-
/// This can be useful for passing the query to another function. Note that since
2023-
/// filter terms are dropped, non-archetypal filters like [`Added`](crate::query::Added),
2024-
/// [`Changed`](crate::query::Changed) and [`Spawned`](crate::query::Spawned) will not be
2025-
/// respected. To maintain or change filter terms see [`Self::transmute_lens_filtered`]
2055+
/// [`Added`]: crate::query::Added
2056+
/// [`Added<T>`]: crate::query::Added
2057+
/// [`AnyOf<(D, ...)>`]: crate::query::AnyOf
2058+
/// [`&Archetype`]: crate::archetype::Archetype
2059+
/// [`Changed`]: crate::query::Changed
2060+
/// [`Changed<T>`]: crate::query::Changed
2061+
/// [`EntityMut`]: crate::world::EntityMut
2062+
/// [`EntityLocation`]: crate::entity::EntityLocation
2063+
/// [`EntityRef`]: crate::world::EntityRef
2064+
/// [`FilteredEntityRef`]: crate::world::FilteredEntityRef
2065+
/// [`FilteredEntityMut`]: crate::world::FilteredEntityMut
2066+
/// [`Has<T>`]: crate::query::Has
2067+
/// [`Mut<T>`]: crate::world::Mut
2068+
/// [`Or<(T, ...)>`]: crate::query::Or
2069+
/// [`QueryBuilder`]: crate::query::QueryBuilder
2070+
/// [`Ref<T>`]: crate::world::Ref
2071+
/// [`SpawnDetails`]: crate::query::SpawnDetails
2072+
/// [`Spawned`]: crate::query::Spawned
2073+
/// [`With<T>`]: crate::query::With
2074+
/// [`Without<T>`]: crate::query::Without
20262075
///
20272076
/// ## Panics
20282077
///
2029-
/// This will panic if `NewD` is not a subset of the original fetch `D`
2078+
/// This will panic if the access required by `NewD` is not a subset of that required by
2079+
/// the original fetch `D`.
20302080
///
20312081
/// ## Example
20322082
///
@@ -2065,30 +2115,6 @@ impl<'w, 's, D: QueryData, F: QueryFilter> Query<'w, 's, D, F> {
20652115
/// # schedule.run(&mut world);
20662116
/// ```
20672117
///
2068-
/// ## Allowed Transmutes
2069-
///
2070-
/// Besides removing parameters from the query,
2071-
/// you can also make limited changes to the types of parameters.
2072-
/// The new query must have a subset of the *read*, *write*, and *required* access of the original query.
2073-
///
2074-
/// * `&mut T` and [`Mut<T>`](crate::change_detection::Mut) have read, write, and required access to `T`
2075-
/// * `&T` and [`Ref<T>`](crate::change_detection::Ref) have read and required access to `T`
2076-
/// * [`Option<D>`] and [`AnyOf<(D, ...)>`](crate::query::AnyOf) have the read and write access of the subqueries, but no required access
2077-
/// * Tuples of query data and `#[derive(QueryData)]` structs have the union of the access of their subqueries
2078-
/// * [`EntityMut`](crate::world::EntityMut) has read and write access to all components, but no required access
2079-
/// * [`EntityRef`](crate::world::EntityRef) has read access to all components, but no required access
2080-
/// * [`Entity`], [`EntityLocation`], [`SpawnDetails`], [`&Archetype`], [`Has<T>`], and [`PhantomData<T>`] have no access at all,
2081-
/// so can be added to any query
2082-
/// * [`FilteredEntityRef`](crate::world::FilteredEntityRef) and [`FilteredEntityMut`](crate::world::FilteredEntityMut)
2083-
/// have access determined by the [`QueryBuilder`](crate::query::QueryBuilder) used to construct them.
2084-
/// Any query can be transmuted to them, and they will receive the access of the source query.
2085-
/// When combined with other `QueryData`, they will receive any access of the source query that does not conflict with the other data.
2086-
/// * [`Added<T>`](crate::query::Added) and [`Changed<T>`](crate::query::Changed) filters have read and required access to `T`
2087-
/// * [`With<T>`](crate::query::With) and [`Without<T>`](crate::query::Without) filters have no access at all,
2088-
/// so can be added to any query
2089-
/// * Tuples of query filters and `#[derive(QueryFilter)]` structs have the union of the access of their subqueries
2090-
/// * [`Or<(F, ...)>`](crate::query::Or) filters have the read access of the subqueries, but no required access
2091-
///
20922118
/// ### Examples of valid transmutes
20932119
///
20942120
/// ```rust
@@ -2165,28 +2191,21 @@ impl<'w, 's, D: QueryData, F: QueryFilter> Query<'w, 's, D, F> {
21652191
/// // Nested inside of an `Or` filter, they have the same access as `Option<&T>`.
21662192
/// assert_valid_transmute_filtered::<Option<&T>, (), Entity, Or<(Changed<T>, With<U>)>>();
21672193
/// ```
2168-
///
2169-
/// [`EntityLocation`]: crate::entity::EntityLocation
2170-
/// [`SpawnDetails`]: crate::query::SpawnDetails
2171-
/// [`&Archetype`]: crate::archetype::Archetype
2172-
/// [`Has<T>`]: crate::query::Has
21732194
#[track_caller]
21742195
pub fn transmute_lens<NewD: QueryData>(&mut self) -> QueryLens<'_, NewD> {
21752196
self.transmute_lens_filtered::<NewD, ()>()
21762197
}
21772198

2178-
/// Returns a [`QueryLens`] that can be used to get a query with a more general fetch.
2199+
/// Returns a [`QueryLens`] that can be used to construct a new `Query` giving more restrictive
2200+
/// access to the entities matched by the current query.
2201+
///
21792202
/// This consumes the [`Query`] to return results with the actual "inner" world lifetime.
21802203
///
2181-
/// For example, this can transform a `Query<(&A, &mut B)>` to a `Query<&B>`.
2182-
/// This can be useful for passing the query to another function. Note that since
2183-
/// filter terms are dropped, non-archetypal filters like [`Added`](crate::query::Added),
2184-
/// [`Changed`](crate::query::Changed) and [`Spawned`](crate::query::Spawned) will not be
2185-
/// respected. To maintain or change filter terms see [`Self::transmute_lens_filtered`]
2204+
/// See [`Self::transmute_lens`] for a description of allowed transmutes.
21862205
///
21872206
/// ## Panics
21882207
///
2189-
/// This will panic if `NewD` is not a subset of the original fetch `Q`
2208+
/// This will panic if `NewD` is not a subset of the original fetch `D`
21902209
///
21912210
/// ## Example
21922211
///
@@ -2225,22 +2244,6 @@ impl<'w, 's, D: QueryData, F: QueryFilter> Query<'w, 's, D, F> {
22252244
/// # schedule.run(&mut world);
22262245
/// ```
22272246
///
2228-
/// ## Allowed Transmutes
2229-
///
2230-
/// Besides removing parameters from the query, you can also
2231-
/// make limited changes to the types of parameters.
2232-
///
2233-
/// * Can always add/remove [`Entity`]
2234-
/// * Can always add/remove [`EntityLocation`]
2235-
/// * Can always add/remove [`&Archetype`]
2236-
/// * `Ref<T>` <-> `&T`
2237-
/// * `&mut T` -> `&T`
2238-
/// * `&mut T` -> `Ref<T>`
2239-
/// * [`EntityMut`](crate::world::EntityMut) -> [`EntityRef`](crate::world::EntityRef)
2240-
///
2241-
/// [`EntityLocation`]: crate::entity::EntityLocation
2242-
/// [`&Archetype`]: crate::archetype::Archetype
2243-
///
22442247
/// # See also
22452248
///
22462249
/// - [`transmute_lens`](Self::transmute_lens) to convert to a lens using a mutable borrow of the [`Query`].
@@ -2251,6 +2254,8 @@ impl<'w, 's, D: QueryData, F: QueryFilter> Query<'w, 's, D, F> {
22512254

22522255
/// Equivalent to [`Self::transmute_lens`] but also includes a [`QueryFilter`] type.
22532256
///
2257+
/// See [`Self::transmute_lens`] for a description of allowed transmutes.
2258+
///
22542259
/// Note that the lens will iterate the same tables and archetypes as the original query. This means that
22552260
/// additional archetypal query terms like [`With`](crate::query::With) and [`Without`](crate::query::Without)
22562261
/// will not necessarily be respected and non-archetypal terms like [`Added`](crate::query::Added),
@@ -2266,10 +2271,13 @@ impl<'w, 's, D: QueryData, F: QueryFilter> Query<'w, 's, D, F> {
22662271
/// Equivalent to [`Self::transmute_lens_inner`] but also includes a [`QueryFilter`] type.
22672272
/// This consumes the [`Query`] to return results with the actual "inner" world lifetime.
22682273
///
2274+
/// See [`Self::transmute_lens`] for a description of allowed transmutes.
2275+
///
22692276
/// Note that the lens will iterate the same tables and archetypes as the original query. This means that
22702277
/// additional archetypal query terms like [`With`](crate::query::With) and [`Without`](crate::query::Without)
22712278
/// will not necessarily be respected and non-archetypal terms like [`Added`](crate::query::Added),
22722279
/// [`Changed`](crate::query::Changed) and [`Spawned`](crate::query::Spawned) will only be respected if they
2280+
/// are in the type signature.
22732281
///
22742282
/// # See also
22752283
///

0 commit comments

Comments
 (0)