Add set_state extension method to Commands (#15083)
# Objective - Improve the ergonomics of managing states. ## Solution - Add `set_state` extension method to `Commands` so you don't need to type out `ResMut<NextState<S>>` to update a state. It also reduces system parameter list size when you already have `Commands`. - I only updated a couple examples to showcase how it can be used. There *is* a potential perf cost to introducing `Commands` so this method shouldn't necessarily be used everywhere. ## Testing - Tested the updated examples: `game_menu` and `alien_cake_addict`. --- ## Showcase Add `Commands::set_state` method for easily updating states. Set directly: ```rust fn go_to_game(mut game_state: ResMut<NextState<GameState>>) { game_state.set(GameState::Play); } ``` Set with commands (**NEW**): ```rust fn go_to_game(mut commands: Commands) { commands.set_state(GameState::Play); } ```
This commit is contained in:
parent
82e416dc48
commit
ce32b5ca06
30
crates/bevy_state/src/commands.rs
Normal file
30
crates/bevy_state/src/commands.rs
Normal file
@ -0,0 +1,30 @@
|
||||
use bevy_ecs::{system::Commands, world::World};
|
||||
use bevy_utils::tracing::debug;
|
||||
|
||||
use crate::state::{FreelyMutableState, NextState};
|
||||
|
||||
/// Extension trait for [`Commands`] adding `bevy_state` helpers.
|
||||
pub trait CommandsStatesExt {
|
||||
/// Sets the next state the app should move to.
|
||||
///
|
||||
/// Internally this schedules a command that updates the [`NextState<S>`](crate::prelude::NextState)
|
||||
/// resource with `state`.
|
||||
///
|
||||
/// Note that commands introduce sync points to the ECS schedule, so modifying `NextState`
|
||||
/// directly may be more efficient depending on your use-case.
|
||||
fn set_state<S: FreelyMutableState>(&mut self, state: S);
|
||||
}
|
||||
|
||||
impl CommandsStatesExt for Commands<'_, '_> {
|
||||
fn set_state<S: FreelyMutableState>(&mut self, state: S) {
|
||||
self.add(move |w: &mut World| {
|
||||
let mut next = w.resource_mut::<NextState<S>>();
|
||||
if let NextState::Pending(prev) = &*next {
|
||||
if *prev != state {
|
||||
debug!("overwriting next state {:?} with {:?}", prev, state);
|
||||
}
|
||||
}
|
||||
next.set(state);
|
||||
});
|
||||
}
|
||||
}
|
@ -34,6 +34,8 @@
|
||||
#[cfg(feature = "bevy_app")]
|
||||
/// Provides [`App`](bevy_app::App) and [`SubApp`](bevy_app::SubApp) with state installation methods
|
||||
pub mod app;
|
||||
/// Provides extension methods for [`Commands`](bevy_ecs::prelude::Commands).
|
||||
pub mod commands;
|
||||
/// Provides definitions for the runtime conditions that interact with the state system
|
||||
pub mod condition;
|
||||
/// Provides definitions for the basic traits required by the state system
|
||||
@ -55,6 +57,8 @@ pub mod prelude {
|
||||
#[doc(hidden)]
|
||||
pub use crate::app::AppExtStates;
|
||||
#[doc(hidden)]
|
||||
pub use crate::commands::CommandsStatesExt;
|
||||
#[doc(hidden)]
|
||||
pub use crate::condition::*;
|
||||
#[cfg(feature = "bevy_reflect")]
|
||||
#[doc(hidden)]
|
||||
|
Loading…
Reference in New Issue
Block a user