mirror of
https://github.com/bevyengine/bevy
synced 2025-02-17 06:28:34 +00:00
Add documentation to ParamSet
(#6998)
# Objective Fixes #4729. Continuation of #4854. ## Solution Add documentation to `ParamSet` and its methods. Includes examples suggested by community members in the original PR. Co-authored-by: Nanox19435 <50684926+Nanox19435@users.noreply.github.com> Co-authored-by: JoJoJet <21144246+JoJoJet@users.noreply.github.com>
This commit is contained in:
parent
ca87830450
commit
fa2b5f2b36
2 changed files with 118 additions and 0 deletions
|
@ -222,7 +222,17 @@ pub fn impl_param_set(_input: TokenStream) -> TokenStream {
|
||||||
for (i, param) in params.iter().enumerate() {
|
for (i, param) in params.iter().enumerate() {
|
||||||
let fn_name = Ident::new(&format!("p{i}"), Span::call_site());
|
let fn_name = Ident::new(&format!("p{i}"), Span::call_site());
|
||||||
let index = Index::from(i);
|
let index = Index::from(i);
|
||||||
|
let ordinal = match i {
|
||||||
|
1 => "1st".to_owned(),
|
||||||
|
2 => "2nd".to_owned(),
|
||||||
|
3 => "3rd".to_owned(),
|
||||||
|
x => format!("{x}th"),
|
||||||
|
};
|
||||||
|
let comment =
|
||||||
|
format!("Gets exclusive access to the {ordinal} parameter in this [`ParamSet`].");
|
||||||
param_fn_muts.push(quote! {
|
param_fn_muts.push(quote! {
|
||||||
|
#[doc = #comment]
|
||||||
|
/// No other parameters may be accessed while this one is active.
|
||||||
pub fn #fn_name<'a>(&'a mut self) -> SystemParamItem<'a, 'a, #param> {
|
pub fn #fn_name<'a>(&'a mut self) -> SystemParamItem<'a, 'a, #param> {
|
||||||
// SAFETY: systems run without conflicts with other systems.
|
// SAFETY: systems run without conflicts with other systems.
|
||||||
// Conflicting params in ParamSet are not accessible at the same time
|
// Conflicting params in ParamSet are not accessible at the same time
|
||||||
|
|
|
@ -239,6 +239,114 @@ fn assert_component_access_compatibility(
|
||||||
query_type, filter_type, system_name, accesses);
|
query_type, filter_type, system_name, accesses);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// A collection of potentially conflicting [`SystemParam`]s allowed by disjoint access.
|
||||||
|
///
|
||||||
|
/// Allows systems to safely access and interact with up to 8 mutually exclusive [`SystemParam`]s, such as
|
||||||
|
/// two queries that reference the same mutable data or an event reader and writer of the same type.
|
||||||
|
///
|
||||||
|
/// Each individual [`SystemParam`] can be accessed by using the functions `p0()`, `p1()`, ..., `p7()`,
|
||||||
|
/// according to the order they are defined in the `ParamSet`. This ensures that there's either
|
||||||
|
/// only one mutable reference to a parameter at a time or any number of immutable references.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// The following system mutably accesses the same component two times,
|
||||||
|
/// which is not allowed due to rust's mutability rules.
|
||||||
|
///
|
||||||
|
/// ```should_panic
|
||||||
|
/// # use bevy_ecs::prelude::*;
|
||||||
|
/// #
|
||||||
|
/// # #[derive(Component)]
|
||||||
|
/// # struct Health;
|
||||||
|
/// #
|
||||||
|
/// # #[derive(Component)]
|
||||||
|
/// # struct Enemy;
|
||||||
|
/// #
|
||||||
|
/// # #[derive(Component)]
|
||||||
|
/// # struct Ally;
|
||||||
|
/// #
|
||||||
|
/// // This will panic at runtime when the system gets initialized.
|
||||||
|
/// fn bad_system(
|
||||||
|
/// mut enemies: Query<&mut Health, With<Enemy>>,
|
||||||
|
/// mut allies: Query<&mut Health, With<Ally>>,
|
||||||
|
/// ) {
|
||||||
|
/// // ...
|
||||||
|
/// }
|
||||||
|
/// #
|
||||||
|
/// # let mut bad_system_system = bevy_ecs::system::IntoSystem::into_system(bad_system);
|
||||||
|
/// # let mut world = World::new();
|
||||||
|
/// # bad_system_system.initialize(&mut world);
|
||||||
|
/// # bad_system_system.run((), &mut world);
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// Conflicing `SystemParam`s like these can be placed in a `ParamSet`,
|
||||||
|
/// which leverages the borrow checker to ensure that only one of the contained parameters are accessed at a given time.
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// # use bevy_ecs::prelude::*;
|
||||||
|
/// #
|
||||||
|
/// # #[derive(Component)]
|
||||||
|
/// # struct Health;
|
||||||
|
/// #
|
||||||
|
/// # #[derive(Component)]
|
||||||
|
/// # struct Enemy;
|
||||||
|
/// #
|
||||||
|
/// # #[derive(Component)]
|
||||||
|
/// # struct Ally;
|
||||||
|
/// #
|
||||||
|
/// // Given the following system
|
||||||
|
/// fn fancy_system(
|
||||||
|
/// mut set: ParamSet<(
|
||||||
|
/// Query<&mut Health, With<Enemy>>,
|
||||||
|
/// Query<&mut Health, With<Ally>>,
|
||||||
|
/// )>
|
||||||
|
/// ) {
|
||||||
|
/// // This will access the first `SystemParam`.
|
||||||
|
/// for mut health in set.p0().iter_mut() {
|
||||||
|
/// // Do your fancy stuff here...
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// // The second `SystemParam`.
|
||||||
|
/// // This would fail to compile if the previous parameter was still borrowed.
|
||||||
|
/// for mut health in set.p1().iter_mut() {
|
||||||
|
/// // Do even fancier stuff here...
|
||||||
|
/// }
|
||||||
|
/// }
|
||||||
|
/// # bevy_ecs::system::assert_is_system(fancy_system);
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// Of course, `ParamSet`s can be used with any kind of `SystemParam`, not just [queries](Query).
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// # use bevy_ecs::prelude::*;
|
||||||
|
/// #
|
||||||
|
/// # struct MyEvent;
|
||||||
|
/// # impl MyEvent {
|
||||||
|
/// # pub fn new() -> Self { Self }
|
||||||
|
/// # }
|
||||||
|
/// fn event_system(
|
||||||
|
/// mut set: ParamSet<(
|
||||||
|
/// // `EventReader`s and `EventWriter`s conflict with each other,
|
||||||
|
/// // since they both access the event queue resource for `MyEvent`.
|
||||||
|
/// EventReader<MyEvent>,
|
||||||
|
/// EventWriter<MyEvent>,
|
||||||
|
/// // `&World` reads the entire world, so a `ParamSet` is the only way
|
||||||
|
/// // that it can be used in the same system as any mutable accesses.
|
||||||
|
/// &World,
|
||||||
|
/// )>,
|
||||||
|
/// ) {
|
||||||
|
/// for event in set.p0().iter() {
|
||||||
|
/// // ...
|
||||||
|
/// # let _event = event;
|
||||||
|
/// }
|
||||||
|
/// set.p1().send(MyEvent::new());
|
||||||
|
///
|
||||||
|
/// let entities = set.p2().entities();
|
||||||
|
/// // ...
|
||||||
|
/// # let _entities = entities;
|
||||||
|
/// }
|
||||||
|
/// # bevy_ecs::system::assert_is_system(event_system);
|
||||||
|
/// ```
|
||||||
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: &'w World,
|
world: &'w World,
|
||||||
|
|
Loading…
Add table
Reference in a new issue