Skip to content

Commit ce32b5c

Browse files
authored
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); } ```
1 parent 82e416d commit ce32b5c

File tree

2 files changed

+34
-0
lines changed

2 files changed

+34
-0
lines changed

crates/bevy_state/src/commands.rs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
use bevy_ecs::{system::Commands, world::World};
2+
use bevy_utils::tracing::debug;
3+
4+
use crate::state::{FreelyMutableState, NextState};
5+
6+
/// Extension trait for [`Commands`] adding `bevy_state` helpers.
7+
pub trait CommandsStatesExt {
8+
/// Sets the next state the app should move to.
9+
///
10+
/// Internally this schedules a command that updates the [`NextState<S>`](crate::prelude::NextState)
11+
/// resource with `state`.
12+
///
13+
/// Note that commands introduce sync points to the ECS schedule, so modifying `NextState`
14+
/// directly may be more efficient depending on your use-case.
15+
fn set_state<S: FreelyMutableState>(&mut self, state: S);
16+
}
17+
18+
impl CommandsStatesExt for Commands<'_, '_> {
19+
fn set_state<S: FreelyMutableState>(&mut self, state: S) {
20+
self.add(move |w: &mut World| {
21+
let mut next = w.resource_mut::<NextState<S>>();
22+
if let NextState::Pending(prev) = &*next {
23+
if *prev != state {
24+
debug!("overwriting next state {:?} with {:?}", prev, state);
25+
}
26+
}
27+
next.set(state);
28+
});
29+
}
30+
}

crates/bevy_state/src/lib.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@
3434
#[cfg(feature = "bevy_app")]
3535
/// Provides [`App`](bevy_app::App) and [`SubApp`](bevy_app::SubApp) with state installation methods
3636
pub mod app;
37+
/// Provides extension methods for [`Commands`](bevy_ecs::prelude::Commands).
38+
pub mod commands;
3739
/// Provides definitions for the runtime conditions that interact with the state system
3840
pub mod condition;
3941
/// Provides definitions for the basic traits required by the state system
@@ -55,6 +57,8 @@ pub mod prelude {
5557
#[doc(hidden)]
5658
pub use crate::app::AppExtStates;
5759
#[doc(hidden)]
60+
pub use crate::commands::CommandsStatesExt;
61+
#[doc(hidden)]
5862
pub use crate::condition::*;
5963
#[cfg(feature = "bevy_reflect")]
6064
#[doc(hidden)]

0 commit comments

Comments
 (0)