diff --git a/crates/bevy_state/src/commands.rs b/crates/bevy_state/src/commands.rs new file mode 100644 index 0000000000000..b392d6b39498b --- /dev/null +++ b/crates/bevy_state/src/commands.rs @@ -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`](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(&mut self, state: S); +} + +impl CommandsStatesExt for Commands<'_, '_> { + fn set_state(&mut self, state: S) { + self.add(move |w: &mut World| { + let mut next = w.resource_mut::>(); + if let NextState::Pending(prev) = &*next { + if *prev != state { + debug!("overwriting next state {:?} with {:?}", prev, state); + } + } + next.set(state); + }); + } +} diff --git a/crates/bevy_state/src/lib.rs b/crates/bevy_state/src/lib.rs index e8dc8264ef522..88598db0b9ba7 100644 --- a/crates/bevy_state/src/lib.rs +++ b/crates/bevy_state/src/lib.rs @@ -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)]