Skip to content

Commit 3cb3fb6

Browse files
Apply documentation suggestions
Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
1 parent ba31c9b commit 3cb3fb6

File tree

3 files changed

+64
-22
lines changed

3 files changed

+64
-22
lines changed

crates/bevy_ecs/macros/src/fetch.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -374,7 +374,7 @@ pub fn derive_filter_fetch_impl(input: TokenStream) -> TokenStream {
374374
type ReadOnlyFetch = #fetch_struct_name #ty_generics;
375375
}
376376

377-
/// SAFETY: each item in the struct is read only
377+
/// SAFETY: each item in the struct is read-only as filters never actually fetch any data that could be mutated
378378
unsafe impl #impl_generics #path::query::ReadOnlyFetch for #fetch_struct_name #ty_generics #where_clause {}
379379
});
380380
tokens

crates/bevy_ecs/src/query/fetch.rs

Lines changed: 61 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -145,48 +145,90 @@ pub type QueryItem<'w, 's, Q> = <<Q as WorldQuery>::Fetch as Fetch<'w, 's>>::Ite
145145
/// optional_foo: Option<&'w OptionalFoo>,
146146
/// }
147147
///
148+
/// // You can also compose derived queries with regular ones in tuples.
149+
/// fn my_system(query: Query<(&Foo, MyQuery, FooQuery)>) {
150+
/// for (foo, my_query, foo_query) in query.iter() {
151+
/// foo; my_query; foo_query;
152+
/// }
153+
/// }
154+
///
155+
/// # my_system.system();
148156
/// ```
149157
///
150158
/// ## Read-only queries
151159
///
152160
/// All queries that are derived with `Fetch` macro have their read-only variants with `ReadOnly`
153-
/// suffix. If you are going to use a query only for reading, you can mark it with `read_only`
154-
/// attribute.
161+
/// suffix. If you are going to use a query which can only read data from the ECS, you can mark it
162+
/// with the `read_only` attribute.
155163
///
156164
/// ```
157165
/// # use bevy_ecs::prelude::*;
158166
/// use bevy_ecs::query::{Fetch, ReadOnlyFetch, WorldQuery};
159167
///
160168
/// #[derive(Component)]
161-
/// struct Foo;
169+
/// struct A(i32);
162170
/// #[derive(Component)]
163-
/// struct Bar;
171+
/// struct B(i32);
164172
///
165173
/// #[derive(Fetch)]
166-
/// #[read_only]
167-
/// struct FooQuery<'w> {
168-
/// foo: &'w Foo,
169-
/// bar_query: BarQueryReadOnly<'w>,
174+
/// struct SumQuery<'w> {
175+
/// a: &'w A,
176+
/// b: &'w B,
177+
/// }
178+
///
179+
/// // This implementation is only available when iterating with `iter_mut`.
180+
/// impl<'w> SumQuery<'w> {
181+
/// fn calc(&self) -> i32 {
182+
/// let Self { a: A(a), b: B(b) } = self;
183+
/// a + b
184+
/// }
185+
/// }
186+
///
187+
/// // If you want to use it with `iter`, you'll need to write an additional implementation.
188+
/// impl<'w> SumQueryReadOnly<'w> {
189+
/// fn calc(&self) -> i32 {
190+
/// let Self { a: A(a), b: B(b) } = self;
191+
/// a + b
192+
/// }
170193
/// }
171194
///
195+
/// // If you are never going to mutate the data, you can mark the query with the `read_only`
196+
/// // attribute and write the implementation only once.
172197
/// #[derive(Fetch)]
173-
/// struct BarQuery<'w> {
174-
/// bar: &'w Bar,
198+
/// #[read_only]
199+
/// struct ProductQuery<'w> {
200+
/// a: &'w A,
201+
/// b: &'w B,
175202
/// }
176203
///
177-
/// fn assert_read_only<T: ReadOnlyFetch>() {}
204+
/// impl<'w> ProductQuery<'w> {
205+
/// fn calc(&self) -> i32 {
206+
/// let Self { a: A(a), b: B(b) } = self;
207+
/// a * b
208+
/// }
209+
/// }
178210
///
179-
/// assert_read_only::<<FooQuery as WorldQuery>::Fetch>();
180-
/// assert_read_only::<<BarQuery as WorldQuery>::ReadOnlyFetch>();
181-
/// // the following will fail to compile:
182-
/// // assert_read_only::<<BarQuery as WorldQuery>::Fetch>();
211+
/// fn my_system(mut sum_query: Query<SumQuery>, product_query: Query<ProductQuery>) {
212+
/// // Iterator's item is `SumQueryReadOnly`.
213+
/// for sum in sum_query.iter() {
214+
/// println!("Sum: {}", sum.calc());
215+
/// }
216+
/// // Iterator's item is `SumQuery`.
217+
/// for sum in sum_query.iter_mut() {
218+
/// println!("Sum (mut): {}", sum.calc());
219+
/// }
220+
/// // Iterator's item is `ProductQuery`.
221+
/// for product in product_query.iter() {
222+
/// println!("Product: {}", product.calc());
223+
/// }
224+
/// }
183225
/// ```
184226
///
185227
/// If you want to use derive macros with read-only query variants, you need to pass them with
186-
/// using `read_only_derive` attribute.
187-
///
188-
/// # use bevy_ecs::prelude::*;
189-
/// use bevy_ecs::query::{Fetch, ReadOnlyFetch, WorldQuery};
228+
/// using the `read_only_derive` attribute. As the `Fetch` macro generates an additional struct
229+
/// for `ReadOnlyFetch` implementation (granted it isn't marked with the `read_only` attribute),
230+
/// you may want it to inherit the same derives. Since derive macros can't access information about
231+
/// other derives, they need to be passed manually with the `read_only_derive` attribute.
190232
///
191233
/// ```
192234
/// # use bevy_ecs::prelude::*;

examples/ecs/custom_query_param.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ use std::{fmt::Debug, marker::PhantomData};
1414
/// declared as named structs can bring the following advantages:
1515
/// - They help to avoid destructuring or using `q.0, q.1, ...` access pattern.
1616
/// - Adding, removing components or changing items order with structs greatly reduces maintenance
17-
/// burden, as you don't need to update statements that destructure tuples, care abort order
17+
/// burden, as you don't need to update statements that destructure tuples, care about order
1818
/// of elements, etc. Instead, you can just add or remove places where a certain element is used.
1919
/// - Named structs enable the composition pattern, that makes query types easier to re-use.
2020
/// - You can bypass the limit of 15 components that exists for query tuples.
@@ -130,7 +130,7 @@ fn print_components_iter(
130130
println!();
131131
}
132132

133-
// If you are going to use a query only for reading, you can mark it with `read_only` attribute
133+
// If you are never going to mutate the data in a query, you can mark it with `read_only` attribute
134134
// to avoid creating an additional type with `ReadOnly` suffix.
135135
#[derive(Fetch)]
136136
#[read_only]

0 commit comments

Comments
 (0)