Reorganize SystemParamBuilder docs and examples. (#15102)
# Objective Improve the documentation of `SystemParamBuilder`. Not all builder types have documentation, and the documentation is spread around and not linked together well. ## Solution Reorganize `SystemParamBuilder` docs and examples. All builder types now have their own examples, and the list of builder types is linked from the `SystemParamBuilder` trait. Add some examples to `FilteredEntityRef` and `FilteredEntityMut` so that `QueryParamBuilder` can reference them.
This commit is contained in:
		
							parent
							
								
									2ec164d279
								
							
						
					
					
						commit
						86e5a5ad9c
					
				| @ -4,8 +4,7 @@ use crate::{ | |||||||
|     prelude::QueryBuilder, |     prelude::QueryBuilder, | ||||||
|     query::{QueryData, QueryFilter, QueryState}, |     query::{QueryData, QueryFilter, QueryState}, | ||||||
|     system::{ |     system::{ | ||||||
|         system_param::{DynSystemParam, DynSystemParamState, Local, ParamSet, SystemParam}, |         DynSystemParam, DynSystemParamState, Local, ParamSet, Query, SystemMeta, SystemParam, | ||||||
|         Query, SystemMeta, |  | ||||||
|     }, |     }, | ||||||
|     world::{FromWorld, World}, |     world::{FromWorld, World}, | ||||||
| }; | }; | ||||||
| @ -13,66 +12,85 @@ use core::fmt::Debug; | |||||||
| 
 | 
 | ||||||
| use super::{init_query_param, Res, ResMut, Resource, SystemState}; | use super::{init_query_param, Res, ResMut, Resource, SystemState}; | ||||||
| 
 | 
 | ||||||
| /// A builder that can create a [`SystemParam`]
 | /// A builder that can create a [`SystemParam`].
 | ||||||
| ///
 | ///
 | ||||||
| /// ```
 | /// ```
 | ||||||
| /// # use bevy_ecs::prelude::*;
 | /// # use bevy_ecs::{
 | ||||||
| /// # use bevy_ecs_macros::SystemParam;
 | /// #     prelude::*,
 | ||||||
| /// # use bevy_ecs::system::{RunSystemOnce, ParamBuilder, LocalBuilder, QueryParamBuilder};
 | /// #     system::{SystemParam, ParamBuilder},
 | ||||||
| /// #
 | /// # };
 | ||||||
| /// # #[derive(Component)]
 |  | ||||||
| /// # struct A;
 |  | ||||||
| /// #
 |  | ||||||
| /// # #[derive(Component)]
 |  | ||||||
| /// # struct B;
 |  | ||||||
| /// #
 |  | ||||||
| /// # #[derive(Resource)]
 | /// # #[derive(Resource)]
 | ||||||
| /// # struct R;
 | /// # struct R;
 | ||||||
| /// #
 | /// #
 | ||||||
| /// # #[derive(SystemParam)]
 | /// # #[derive(SystemParam)]
 | ||||||
| /// # struct MyParam;
 | /// # struct MyParam;
 | ||||||
| /// #
 | /// #
 | ||||||
| /// # let mut world = World::new();
 | /// fn some_system(param: MyParam) {}
 | ||||||
| /// # world.insert_resource(R);
 | ///
 | ||||||
| /// #
 | /// fn build_system(builder: impl SystemParamBuilder<MyParam>) {
 | ||||||
| /// fn my_system(res: Res<R>, query: Query<&A>, param: MyParam) {
 | ///     let mut world = World::new();
 | ||||||
| ///     // ...
 | ///     // To build a system, create a tuple of `SystemParamBuilder`s
 | ||||||
|  | ///     // with a builder for each parameter.
 | ||||||
|  | ///     // Note that the builder for a system must be a tuple,
 | ||||||
|  | ///     // even if there is only one parameter.
 | ||||||
|  | ///     (builder,)
 | ||||||
|  | ///         .build_state(&mut world)
 | ||||||
|  | ///         .build_system(some_system);
 | ||||||
| /// }
 | /// }
 | ||||||
| ///
 | ///
 | ||||||
| /// // To build a system, create a tuple of `SystemParamBuilder`s with a builder for each param.
 | /// fn build_closure_system_infer(builder: impl SystemParamBuilder<MyParam>) {
 | ||||||
| /// // `ParamBuilder` can be used to build a parameter using its default initialization,
 | ///     let mut world = World::new();
 | ||||||
| /// // and has helper methods to create typed builders.
 | ///     // Closures can be used in addition to named functions.
 | ||||||
| /// let system = (
 | ///     // If a closure is used, the parameter types must all be inferred
 | ||||||
| ///     ParamBuilder,
 | ///     // from the builders, so you cannot use plain `ParamBuilder`.
 | ||||||
| ///     ParamBuilder::query::<&A>(),
 | ///     (builder, ParamBuilder::resource())
 | ||||||
| ///     ParamBuilder::of::<MyParam>(),
 | ///         .build_state(&mut world)
 | ||||||
| /// )
 | ///         .build_system(|param, res| {
 | ||||||
| ///     .build_state(&mut world)
 | ///             let param: MyParam = param;
 | ||||||
| ///     .build_system(my_system);
 | ///             let res: Res<R> = res;
 | ||||||
| ///
 | ///         });
 | ||||||
| /// // Other implementations of `SystemParamBuilder` can be used to configure the parameters.
 |  | ||||||
| /// let system = (
 |  | ||||||
| ///     ParamBuilder,
 |  | ||||||
| ///     QueryParamBuilder::new::<&A, ()>(|builder| {
 |  | ||||||
| ///         builder.with::<B>();
 |  | ||||||
| ///     }),
 |  | ||||||
| ///     ParamBuilder,
 |  | ||||||
| /// )
 |  | ||||||
| ///     .build_state(&mut world)
 |  | ||||||
| ///     .build_system(my_system);
 |  | ||||||
| ///
 |  | ||||||
| /// fn single_parameter_system(local: Local<u64>) {
 |  | ||||||
| ///     // ...
 |  | ||||||
| /// }
 | /// }
 | ||||||
| ///
 | ///
 | ||||||
| /// // Note that the builder for a system must be a tuple, even if there is only one parameter.
 | /// fn build_closure_system_explicit(builder: impl SystemParamBuilder<MyParam>) {
 | ||||||
| /// let system = (LocalBuilder(2),)
 | ///     let mut world = World::new();
 | ||||||
| ///     .build_state(&mut world)
 | ///     // Alternately, you can provide all types in the closure
 | ||||||
| ///     .build_system(single_parameter_system);
 | ///     // parameter list and call `build_any_system()`.
 | ||||||
| ///
 | ///     (builder, ParamBuilder)
 | ||||||
| /// world.run_system_once(system);
 | ///         .build_state(&mut world)
 | ||||||
|  | ///         .build_any_system(|param: MyParam, res: Res<R>| {});
 | ||||||
|  | /// }
 | ||||||
| /// ```
 | /// ```
 | ||||||
| ///
 | ///
 | ||||||
|  | /// See the documentation for individual builders for more examples.
 | ||||||
|  | ///
 | ||||||
|  | /// # List of Builders
 | ||||||
|  | ///
 | ||||||
|  | /// [`ParamBuilder`] can be used for parameters that don't require any special building.
 | ||||||
|  | /// Using a `ParamBuilder` will build the system parameter the same way it would be initialized in an ordinary system.
 | ||||||
|  | ///
 | ||||||
|  | /// `ParamBuilder` also provides factory methods that return a `ParamBuilder` typed as `impl SystemParamBuilder<P>`
 | ||||||
|  | /// for common system parameters that can be used to guide closure parameter inference.
 | ||||||
|  | ///
 | ||||||
|  | /// [`QueryParamBuilder`] can build a [`Query`] to add additional filters,
 | ||||||
|  | /// or to configure the components available to [`FilteredEntityRef`](crate::world::FilteredEntityRef) or [`FilteredEntityMut`](crate::world::FilteredEntityMut).
 | ||||||
|  | /// You can also use a [`QueryState`] to build a [`Query`].
 | ||||||
|  | ///
 | ||||||
|  | /// [`LocalBuilder`] can build a [`Local`] to supply the initial value for the `Local`.
 | ||||||
|  | ///
 | ||||||
|  | /// [`DynParamBuilder`] can build a [`DynSystemParam`] to determine the type of the inner parameter,
 | ||||||
|  | /// and to supply any `SystemParamBuilder` it needs.
 | ||||||
|  | ///
 | ||||||
|  | /// Tuples of builders can build tuples of parameters, one builder for each element.
 | ||||||
|  | /// Note that since systems require a tuple as a parameter, the outer builder for a system will always be a tuple.
 | ||||||
|  | ///
 | ||||||
|  | /// A [`Vec`] of builders can build a `Vec` of parameters, one builder for each element.
 | ||||||
|  | ///
 | ||||||
|  | /// A [`ParamSetBuilder`] can build a [`ParamSet`].
 | ||||||
|  | /// This can wrap either a tuple or a `Vec`, one builder for each element.
 | ||||||
|  | ///
 | ||||||
|  | /// A custom system param created with `#[derive(SystemParam)]` can be buildable if it includes a `#[system_param(builder)]` attribute.
 | ||||||
|  | /// See [the documentation for `SystemParam` derives](SystemParam#builders).
 | ||||||
|  | ///
 | ||||||
| /// # Safety
 | /// # Safety
 | ||||||
| ///
 | ///
 | ||||||
| /// The implementor must ensure the following is true.
 | /// The implementor must ensure the following is true.
 | ||||||
| @ -97,6 +115,44 @@ pub unsafe trait SystemParamBuilder<P: SystemParam>: Sized { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /// A [`SystemParamBuilder`] for any [`SystemParam`] that uses its default initialization.
 | /// A [`SystemParamBuilder`] for any [`SystemParam`] that uses its default initialization.
 | ||||||
|  | ///
 | ||||||
|  | /// ## Example
 | ||||||
|  | ///
 | ||||||
|  | /// ```
 | ||||||
|  | /// # use bevy_ecs::{
 | ||||||
|  | /// #     prelude::*,
 | ||||||
|  | /// #     system::{SystemParam, ParamBuilder},
 | ||||||
|  | /// # };
 | ||||||
|  | /// #
 | ||||||
|  | /// # #[derive(Component)]
 | ||||||
|  | /// # struct A;
 | ||||||
|  | /// #
 | ||||||
|  | /// # #[derive(Resource)]
 | ||||||
|  | /// # struct R;
 | ||||||
|  | /// #
 | ||||||
|  | /// # #[derive(SystemParam)]
 | ||||||
|  | /// # struct MyParam;
 | ||||||
|  | /// #
 | ||||||
|  | /// # let mut world = World::new();
 | ||||||
|  | /// # world.insert_resource(R);
 | ||||||
|  | /// #
 | ||||||
|  | /// fn my_system(res: Res<R>, param: MyParam, query: Query<&A>) {
 | ||||||
|  | ///     // ...
 | ||||||
|  | /// }
 | ||||||
|  | ///
 | ||||||
|  | /// let system = (
 | ||||||
|  | ///     // A plain ParamBuilder can build any parameter type.
 | ||||||
|  | ///     ParamBuilder,
 | ||||||
|  | ///     // The `of::<P>()` method returns a `ParamBuilder`
 | ||||||
|  | ///     // typed as `impl SystemParamBuilder<P>`.
 | ||||||
|  | ///     ParamBuilder::of::<MyParam>(),
 | ||||||
|  | ///     // The other factory methods return typed builders
 | ||||||
|  | ///     // for common parameter types.
 | ||||||
|  | ///     ParamBuilder::query::<&A>(),
 | ||||||
|  | /// )
 | ||||||
|  | ///     .build_state(&mut world)
 | ||||||
|  | ///     .build_system(my_system);
 | ||||||
|  | /// ```
 | ||||||
| #[derive(Default, Debug, Copy, Clone)] | #[derive(Default, Debug, Copy, Clone)] | ||||||
| pub struct ParamBuilder; | pub struct ParamBuilder; | ||||||
| 
 | 
 | ||||||
| @ -153,6 +209,45 @@ unsafe impl<'w, 's, D: QueryData + 'static, F: QueryFilter + 'static> | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /// A [`SystemParamBuilder`] for a [`Query`].
 | /// A [`SystemParamBuilder`] for a [`Query`].
 | ||||||
|  | /// This takes a closure accepting an `&mut` [`QueryBuilder`] and uses the builder to construct the query's state.
 | ||||||
|  | /// This can be used to add additional filters,
 | ||||||
|  | /// or to configure the components available to [`FilteredEntityRef`](crate::world::FilteredEntityRef) or [`FilteredEntityMut`](crate::world::FilteredEntityMut).
 | ||||||
|  | ///
 | ||||||
|  | /// ## Example
 | ||||||
|  | ///
 | ||||||
|  | /// ```
 | ||||||
|  | /// # use bevy_ecs::{
 | ||||||
|  | /// #     prelude::*,
 | ||||||
|  | /// #     system::{SystemParam, QueryParamBuilder},
 | ||||||
|  | /// # };
 | ||||||
|  | /// #
 | ||||||
|  | /// # #[derive(Component)]
 | ||||||
|  | /// # struct Player;
 | ||||||
|  | /// #
 | ||||||
|  | /// # let mut world = World::new();
 | ||||||
|  | /// let system = (QueryParamBuilder::new(|builder| {
 | ||||||
|  | ///     builder.with::<Player>();
 | ||||||
|  | /// }),)
 | ||||||
|  | ///     .build_state(&mut world)
 | ||||||
|  | ///     .build_system(|query: Query<()>| {
 | ||||||
|  | ///         for _ in &query {
 | ||||||
|  | ///             // This only includes entities with an `Player` component.
 | ||||||
|  | ///         }
 | ||||||
|  | ///     });
 | ||||||
|  | ///
 | ||||||
|  | /// // When collecting multiple builders into a `Vec`,
 | ||||||
|  | /// // use `new_box()` to erase the closure type.
 | ||||||
|  | /// let system = (vec![
 | ||||||
|  | ///     QueryParamBuilder::new_box(|builder| {
 | ||||||
|  | ///         builder.with::<Player>();
 | ||||||
|  | ///     }),
 | ||||||
|  | ///     QueryParamBuilder::new_box(|builder| {
 | ||||||
|  | ///         builder.without::<Player>();
 | ||||||
|  | ///     }),
 | ||||||
|  | /// ],)
 | ||||||
|  | ///     .build_state(&mut world)
 | ||||||
|  | ///     .build_system(|query: Vec<Query<()>>| {});
 | ||||||
|  | /// ```
 | ||||||
| pub struct QueryParamBuilder<T>(T); | pub struct QueryParamBuilder<T>(T); | ||||||
| 
 | 
 | ||||||
| impl<T> QueryParamBuilder<T> { | impl<T> QueryParamBuilder<T> { | ||||||
| @ -229,7 +324,74 @@ unsafe impl<P: SystemParam, B: SystemParamBuilder<P>> SystemParamBuilder<Vec<P>> | |||||||
| /// A [`SystemParamBuilder`] for a [`ParamSet`].
 | /// A [`SystemParamBuilder`] for a [`ParamSet`].
 | ||||||
| ///
 | ///
 | ||||||
| /// To build a [`ParamSet`] with a tuple of system parameters, pass a tuple of matching [`SystemParamBuilder`]s.
 | /// To build a [`ParamSet`] with a tuple of system parameters, pass a tuple of matching [`SystemParamBuilder`]s.
 | ||||||
| /// To build a [`ParamSet`] with a `Vec` of system parameters, pass a `Vec` of matching [`SystemParamBuilder`]s.
 | /// To build a [`ParamSet`] with a [`Vec`] of system parameters, pass a `Vec` of matching [`SystemParamBuilder`]s.
 | ||||||
|  | ///
 | ||||||
|  | /// # Examples
 | ||||||
|  | ///
 | ||||||
|  | /// ```
 | ||||||
|  | /// # use bevy_ecs::{prelude::*, system::*};
 | ||||||
|  | /// #
 | ||||||
|  | /// # #[derive(Component)]
 | ||||||
|  | /// # struct Health;
 | ||||||
|  | /// #
 | ||||||
|  | /// # #[derive(Component)]
 | ||||||
|  | /// # struct Enemy;
 | ||||||
|  | /// #
 | ||||||
|  | /// # #[derive(Component)]
 | ||||||
|  | /// # struct Ally;
 | ||||||
|  | /// #
 | ||||||
|  | /// # let mut world = World::new();
 | ||||||
|  | /// #
 | ||||||
|  | /// let system = (ParamSetBuilder((
 | ||||||
|  | ///     QueryParamBuilder::new(|builder| {
 | ||||||
|  | ///         builder.with::<Enemy>();
 | ||||||
|  | ///     }),
 | ||||||
|  | ///     QueryParamBuilder::new(|builder| {
 | ||||||
|  | ///         builder.with::<Ally>();
 | ||||||
|  | ///     }),
 | ||||||
|  | ///     ParamBuilder,
 | ||||||
|  | /// )),)
 | ||||||
|  | ///     .build_state(&mut world)
 | ||||||
|  | ///     .build_system(buildable_system_with_tuple);
 | ||||||
|  | /// # world.run_system_once(system);
 | ||||||
|  | ///
 | ||||||
|  | /// fn buildable_system_with_tuple(
 | ||||||
|  | ///     mut set: ParamSet<(Query<&mut Health>, Query<&mut Health>, &World)>,
 | ||||||
|  | /// ) {
 | ||||||
|  | ///     // The first parameter is built from the first builder,
 | ||||||
|  | ///     // so this will iterate over enemies.
 | ||||||
|  | ///     for mut health in set.p0().iter_mut() {}
 | ||||||
|  | ///     // And the second parameter is built from the second builder,
 | ||||||
|  | ///     // so this will iterate over allies.
 | ||||||
|  | ///     for mut health in set.p1().iter_mut() {}
 | ||||||
|  | ///     // Parameters that don't need special building can use `ParamBuilder`.
 | ||||||
|  | ///     let entities = set.p2().entities();
 | ||||||
|  | /// }
 | ||||||
|  | ///
 | ||||||
|  | /// let system = (ParamSetBuilder(vec![
 | ||||||
|  | ///     QueryParamBuilder::new_box(|builder| {
 | ||||||
|  | ///         builder.with::<Enemy>();
 | ||||||
|  | ///     }),
 | ||||||
|  | ///     QueryParamBuilder::new_box(|builder| {
 | ||||||
|  | ///         builder.with::<Ally>();
 | ||||||
|  | ///     }),
 | ||||||
|  | /// ]),)
 | ||||||
|  | ///     .build_state(&mut world)
 | ||||||
|  | ///     .build_system(buildable_system_with_vec);
 | ||||||
|  | /// # world.run_system_once(system);
 | ||||||
|  | ///
 | ||||||
|  | /// fn buildable_system_with_vec(mut set: ParamSet<Vec<Query<&mut Health>>>) {
 | ||||||
|  | ///     // As with tuples, the first parameter is built from the first builder,
 | ||||||
|  | ///     // so this will iterate over enemies.
 | ||||||
|  | ///     for mut health in set.get_mut(0).iter_mut() {}
 | ||||||
|  | ///     // And the second parameter is built from the second builder,
 | ||||||
|  | ///     // so this will iterate over allies.
 | ||||||
|  | ///     for mut health in set.get_mut(1).iter_mut() {}
 | ||||||
|  | ///     // You can iterate over the parameters either by index,
 | ||||||
|  | ///     // or using the `for_each` method.
 | ||||||
|  | ///     set.for_each(|mut query| for mut health in query.iter_mut() {});
 | ||||||
|  | /// }
 | ||||||
|  | /// ```
 | ||||||
| pub struct ParamSetBuilder<T>(pub T); | pub struct ParamSetBuilder<T>(pub T); | ||||||
| 
 | 
 | ||||||
| macro_rules! impl_param_set_builder_tuple { | macro_rules! impl_param_set_builder_tuple { | ||||||
| @ -302,6 +464,7 @@ unsafe impl<'w, 's, P: SystemParam, B: SystemParamBuilder<P>> | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /// A [`SystemParamBuilder`] for a [`DynSystemParam`].
 | /// A [`SystemParamBuilder`] for a [`DynSystemParam`].
 | ||||||
|  | /// See the [`DynSystemParam`] docs for examples.
 | ||||||
| pub struct DynParamBuilder<'a>( | pub struct DynParamBuilder<'a>( | ||||||
|     Box<dyn FnOnce(&mut World, &mut SystemMeta) -> DynSystemParamState + 'a>, |     Box<dyn FnOnce(&mut World, &mut SystemMeta) -> DynSystemParamState + 'a>, | ||||||
| ); | ); | ||||||
| @ -331,6 +494,23 @@ unsafe impl<'a, 'w, 's> SystemParamBuilder<DynSystemParam<'w, 's>> for DynParamB | |||||||
| 
 | 
 | ||||||
| /// A [`SystemParamBuilder`] for a [`Local`].
 | /// A [`SystemParamBuilder`] for a [`Local`].
 | ||||||
| /// The provided value will be used as the initial value of the `Local`.
 | /// The provided value will be used as the initial value of the `Local`.
 | ||||||
|  | ///
 | ||||||
|  | /// ## Example
 | ||||||
|  | ///
 | ||||||
|  | /// ```
 | ||||||
|  | /// # use bevy_ecs::{
 | ||||||
|  | /// #     prelude::*,
 | ||||||
|  | /// #     system::{SystemParam, LocalBuilder, RunSystemOnce},
 | ||||||
|  | /// # };
 | ||||||
|  | /// #
 | ||||||
|  | /// # let mut world = World::new();
 | ||||||
|  | /// let system = (LocalBuilder(100),)
 | ||||||
|  | ///     .build_state(&mut world)
 | ||||||
|  | ///     .build_system(|local: Local<usize>| {
 | ||||||
|  | ///         assert_eq!(*local, 100);
 | ||||||
|  | ///     });
 | ||||||
|  | /// # world.run_system_once(system);
 | ||||||
|  | /// ```
 | ||||||
| pub struct LocalBuilder<T>(pub T); | pub struct LocalBuilder<T>(pub T); | ||||||
| 
 | 
 | ||||||
| // SAFETY: `Local` performs no world access.
 | // SAFETY: `Local` performs no world access.
 | ||||||
|  | |||||||
| @ -99,7 +99,15 @@ | |||||||
| //! - [`Components`](crate::component::Components) (Provides Components metadata)
 | //! - [`Components`](crate::component::Components) (Provides Components metadata)
 | ||||||
| //! - [`Entities`](crate::entity::Entities) (Provides Entities metadata)
 | //! - [`Entities`](crate::entity::Entities) (Provides Entities metadata)
 | ||||||
| //! - All tuples between 1 to 16 elements where each element implements [`SystemParam`]
 | //! - All tuples between 1 to 16 elements where each element implements [`SystemParam`]
 | ||||||
|  | //! - [`ParamSet`]
 | ||||||
| //! - [`()` (unit primitive type)](https://doc.rust-lang.org/stable/std/primitive.unit.html)
 | //! - [`()` (unit primitive type)](https://doc.rust-lang.org/stable/std/primitive.unit.html)
 | ||||||
|  | //!
 | ||||||
|  | //! In addition, the following parameters can be used when constructing a dynamic system with [`SystemParamBuilder`],
 | ||||||
|  | //! but will only provide an empty value when used with an ordinary system:
 | ||||||
|  | //!
 | ||||||
|  | //! - [`DynSystemParam`]
 | ||||||
|  | //! - [`Vec<P>`] where `P: SystemParam`
 | ||||||
|  | //! - [`ParamSet<Vec<P>>`] where `P: SystemParam`
 | ||||||
| 
 | 
 | ||||||
| mod adapter_system; | mod adapter_system; | ||||||
| mod builder; | mod builder; | ||||||
|  | |||||||
| @ -606,46 +606,6 @@ unsafe impl<'a, D: ReadOnlyQueryData + 'static, F: QueryFilter + 'static> ReadOn | |||||||
| /// }
 | /// }
 | ||||||
| /// # bevy_ecs::system::assert_is_system(event_system);
 | /// # bevy_ecs::system::assert_is_system(event_system);
 | ||||||
| /// ```
 | /// ```
 | ||||||
| ///
 |  | ||||||
| /// If you want to use `ParamSet` with a [`SystemParamBuilder`](crate::system::SystemParamBuilder), use [`ParamSetBuilder`](crate::system::ParamSetBuilder) and pass a builder for each param.
 |  | ||||||
| /// ```
 |  | ||||||
| /// # use bevy_ecs::{prelude::*, system::*};
 |  | ||||||
| /// #
 |  | ||||||
| /// # #[derive(Component)]
 |  | ||||||
| /// # struct Health;
 |  | ||||||
| /// #
 |  | ||||||
| /// # #[derive(Component)]
 |  | ||||||
| /// # struct Enemy;
 |  | ||||||
| /// #
 |  | ||||||
| /// # #[derive(Component)]
 |  | ||||||
| /// # struct Ally;
 |  | ||||||
| /// #
 |  | ||||||
| /// let mut world = World::new();
 |  | ||||||
| ///
 |  | ||||||
| /// let system = (ParamSetBuilder((
 |  | ||||||
| ///     QueryParamBuilder::new(|builder| {
 |  | ||||||
| ///         builder.with::<Enemy>();
 |  | ||||||
| ///     }),
 |  | ||||||
| ///     QueryParamBuilder::new(|builder| {
 |  | ||||||
| ///         builder.with::<Ally>();
 |  | ||||||
| ///     }),
 |  | ||||||
| ///     ParamBuilder,
 |  | ||||||
| /// )),)
 |  | ||||||
| ///     .build_state(&mut world)
 |  | ||||||
| ///     .build_system(buildable_system);
 |  | ||||||
| /// world.run_system_once(system);
 |  | ||||||
| ///
 |  | ||||||
| /// fn buildable_system(mut set: ParamSet<(Query<&mut Health>, Query<&mut Health>, &World)>) {
 |  | ||||||
| ///     // The first parameter is built from the first builder,
 |  | ||||||
| ///     // so this will iterate over enemies.
 |  | ||||||
| ///     for mut health in set.p0().iter_mut() {}
 |  | ||||||
| ///     // And the second parameter is built from the second builder,
 |  | ||||||
| ///     // so this will iterate over allies.
 |  | ||||||
| ///     for mut health in set.p1().iter_mut() {}
 |  | ||||||
| ///     // Parameters that don't need special building can use `ParamBuilder`.
 |  | ||||||
| ///     let entities = set.p2().entities();
 |  | ||||||
| /// }
 |  | ||||||
| /// ```
 |  | ||||||
| pub struct ParamSet<'w, 's, T: SystemParam> { | pub struct ParamSet<'w, 's, T: SystemParam> { | ||||||
|     param_states: &'s mut T::State, |     param_states: &'s mut T::State, | ||||||
|     world: UnsafeWorldCell<'w>, |     world: UnsafeWorldCell<'w>, | ||||||
| @ -2124,22 +2084,22 @@ unsafe impl<T: ?Sized> ReadOnlySystemParam for PhantomData<T> {} | |||||||
| /// # #[derive(Default, Resource)]
 | /// # #[derive(Default, Resource)]
 | ||||||
| /// # struct B;
 | /// # struct B;
 | ||||||
| /// #
 | /// #
 | ||||||
| /// let mut world = World::new();
 | /// # let mut world = World::new();
 | ||||||
| /// world.init_resource::<A>();
 | /// # world.init_resource::<A>();
 | ||||||
| /// world.init_resource::<B>();
 | /// # world.init_resource::<B>();
 | ||||||
| ///
 | /// #
 | ||||||
| /// // If the inner parameter doesn't require any special building, use `ParamBuilder`.
 | /// // If the inner parameter doesn't require any special building, use `ParamBuilder`.
 | ||||||
| /// // Either specify the type parameter on `DynParamBuilder::new()` ...
 | /// // Either specify the type parameter on `DynParamBuilder::new()` ...
 | ||||||
| /// let system = (DynParamBuilder::new::<Res<A>>(ParamBuilder),)
 | /// let system = (DynParamBuilder::new::<Res<A>>(ParamBuilder),)
 | ||||||
| ///     .build_state(&mut world)
 | ///     .build_state(&mut world)
 | ||||||
| ///     .build_system(expects_res_a);
 | ///     .build_system(expects_res_a);
 | ||||||
| /// world.run_system_once(system);
 | /// # world.run_system_once(system);
 | ||||||
| ///
 | ///
 | ||||||
| /// // ... or use a factory method on `ParamBuilder` that returns a specific type.
 | /// // ... or use a factory method on `ParamBuilder` that returns a specific type.
 | ||||||
| /// let system = (DynParamBuilder::new(ParamBuilder::resource::<A>()),)
 | /// let system = (DynParamBuilder::new(ParamBuilder::resource::<A>()),)
 | ||||||
| ///     .build_state(&mut world)
 | ///     .build_state(&mut world)
 | ||||||
| ///     .build_system(expects_res_a);
 | ///     .build_system(expects_res_a);
 | ||||||
| /// world.run_system_once(system);
 | /// # world.run_system_once(system);
 | ||||||
| ///
 | ///
 | ||||||
| /// fn expects_res_a(mut param: DynSystemParam) {
 | /// fn expects_res_a(mut param: DynSystemParam) {
 | ||||||
| ///     // Use the `downcast` methods to retrieve the inner parameter.
 | ///     // Use the `downcast` methods to retrieve the inner parameter.
 | ||||||
| @ -2165,7 +2125,7 @@ unsafe impl<T: ?Sized> ReadOnlySystemParam for PhantomData<T> {} | |||||||
| ///         let local: Local<usize> = param.downcast::<Local<usize>>().unwrap();
 | ///         let local: Local<usize> = param.downcast::<Local<usize>>().unwrap();
 | ||||||
| ///         assert_eq!(*local, 10);
 | ///         assert_eq!(*local, 10);
 | ||||||
| ///     });
 | ///     });
 | ||||||
| /// world.run_system_once(system);
 | /// # world.run_system_once(system);
 | ||||||
| /// ```
 | /// ```
 | ||||||
| pub struct DynSystemParam<'w, 's> { | pub struct DynSystemParam<'w, 's> { | ||||||
|     /// A `ParamState<T>` wrapping the state for the underlying system param.
 |     /// A `ParamState<T>` wrapping the state for the underlying system param.
 | ||||||
|  | |||||||
| @ -1895,6 +1895,36 @@ impl<'w, 'a, T: Component> VacantEntry<'w, 'a, T> { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /// Provides read-only access to a single entity and some of its components defined by the contained [`Access`].
 | /// Provides read-only access to a single entity and some of its components defined by the contained [`Access`].
 | ||||||
|  | ///
 | ||||||
|  | /// To define the access when used as a [`QueryData`](crate::query::QueryData),
 | ||||||
|  | /// use a [`QueryBuilder`](crate::query::QueryBuilder) or [`QueryParamBuilder`](crate::system::QueryParamBuilder).
 | ||||||
|  | /// The `FilteredEntityRef` must be the entire `QueryData`, and not nested inside a tuple with other data.
 | ||||||
|  | ///
 | ||||||
|  | /// ```
 | ||||||
|  | /// # use bevy_ecs::{prelude::*, world::FilteredEntityRef};
 | ||||||
|  | /// #
 | ||||||
|  | /// # #[derive(Component)]
 | ||||||
|  | /// # struct A;
 | ||||||
|  | /// #
 | ||||||
|  | /// # let mut world = World::new();
 | ||||||
|  | /// # world.spawn(A);
 | ||||||
|  | /// #
 | ||||||
|  | /// // This gives the `FilteredEntityRef` access to `&A`.
 | ||||||
|  | /// let mut query = QueryBuilder::<FilteredEntityRef>::new(&mut world)
 | ||||||
|  | ///     .data::<&A>()
 | ||||||
|  | ///     .build();
 | ||||||
|  | ///
 | ||||||
|  | /// let filtered_entity: FilteredEntityRef = query.single(&mut world);
 | ||||||
|  | /// let component: &A = filtered_entity.get().unwrap();
 | ||||||
|  | ///
 | ||||||
|  | /// // Here `FilteredEntityRef` is nested in a tuple, so it does not have access to `&A`.
 | ||||||
|  | /// let mut query = QueryBuilder::<(Entity, FilteredEntityRef)>::new(&mut world)
 | ||||||
|  | ///     .data::<&A>()
 | ||||||
|  | ///     .build();
 | ||||||
|  | ///
 | ||||||
|  | /// let (_, filtered_entity) = query.single(&mut world);
 | ||||||
|  | /// assert!(filtered_entity.get::<A>().is_none());
 | ||||||
|  | /// ```
 | ||||||
| #[derive(Clone)] | #[derive(Clone)] | ||||||
| pub struct FilteredEntityRef<'w> { | pub struct FilteredEntityRef<'w> { | ||||||
|     entity: UnsafeEntityCell<'w>, |     entity: UnsafeEntityCell<'w>, | ||||||
| @ -2136,6 +2166,36 @@ impl<'a> From<&'a EntityWorldMut<'_>> for FilteredEntityRef<'a> { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /// Provides mutable access to a single entity and some of its components defined by the contained [`Access`].
 | /// Provides mutable access to a single entity and some of its components defined by the contained [`Access`].
 | ||||||
|  | ///
 | ||||||
|  | /// To define the access when used as a [`QueryData`](crate::query::QueryData),
 | ||||||
|  | /// use a [`QueryBuilder`](crate::query::QueryBuilder) or [`QueryParamBuilder`](crate::system::QueryParamBuilder).
 | ||||||
|  | /// The `FilteredEntityMut` must be the entire `QueryData`, and not nested inside a tuple with other data.
 | ||||||
|  | ///
 | ||||||
|  | /// ```
 | ||||||
|  | /// # use bevy_ecs::{prelude::*, world::FilteredEntityMut};
 | ||||||
|  | /// #
 | ||||||
|  | /// # #[derive(Component)]
 | ||||||
|  | /// # struct A;
 | ||||||
|  | /// #
 | ||||||
|  | /// # let mut world = World::new();
 | ||||||
|  | /// # world.spawn(A);
 | ||||||
|  | /// #
 | ||||||
|  | /// // This gives the `FilteredEntityMut` access to `&mut A`.
 | ||||||
|  | /// let mut query = QueryBuilder::<FilteredEntityMut>::new(&mut world)
 | ||||||
|  | ///     .data::<&mut A>()
 | ||||||
|  | ///     .build();
 | ||||||
|  | ///
 | ||||||
|  | /// let mut filtered_entity: FilteredEntityMut = query.single_mut(&mut world);
 | ||||||
|  | /// let component: Mut<A> = filtered_entity.get_mut().unwrap();
 | ||||||
|  | ///
 | ||||||
|  | /// // Here `FilteredEntityMut` is nested in a tuple, so it does not have access to `&mut A`.
 | ||||||
|  | /// let mut query = QueryBuilder::<(Entity, FilteredEntityMut)>::new(&mut world)
 | ||||||
|  | ///     .data::<&mut A>()
 | ||||||
|  | ///     .build();
 | ||||||
|  | ///
 | ||||||
|  | /// let (_, mut filtered_entity) = query.single_mut(&mut world);
 | ||||||
|  | /// assert!(filtered_entity.get_mut::<A>().is_none());
 | ||||||
|  | /// ```
 | ||||||
| pub struct FilteredEntityMut<'w> { | pub struct FilteredEntityMut<'w> { | ||||||
|     entity: UnsafeEntityCell<'w>, |     entity: UnsafeEntityCell<'w>, | ||||||
|     access: Access<ComponentId>, |     access: Access<ComponentId>, | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 Chris Russell
						Chris Russell