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
					
				@ -222,7 +222,17 @@ pub fn impl_param_set(_input: TokenStream) -> TokenStream {
 | 
			
		||||
    for (i, param) in params.iter().enumerate() {
 | 
			
		||||
        let fn_name = Ident::new(&format!("p{i}"), Span::call_site());
 | 
			
		||||
        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! {
 | 
			
		||||
            #[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> {
 | 
			
		||||
                // SAFETY: systems run without conflicts with other systems.
 | 
			
		||||
                // 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);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// 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> {
 | 
			
		||||
    param_states: &'s mut T::State,
 | 
			
		||||
    world: &'w World,
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user