mirror of
https://github.com/bevyengine/bevy
synced 2025-02-16 14:08:32 +00:00
Move state installation methods from bevy_app
to bevy_state
(#13637)
# Objective After separating `bevy_states`, state installation methods like `init_state` were kept in `bevy_app` under the `bevy_state` feature flag. This is problematic, because `bevy_state` is not a core module, `bevy_app` is, yet it depends on `bevy_state`. This causes practical problems like the inability to use `bevy_hierarchy` inside `bevy_state`, because of circular dependencies. ## Solution - `bevy_state` now has a `bevy_app` feature flag, which gates the new `AppStateExt` trait. All previous state installation methods were moved to this trait. It's implemented for both `SubApp` and `App`. ## Changelog - All state related app methods are now in `AppExtStates` trait in `bevy_state`. - Added `StatesPlugin` which is in `DefaultPlugins` when `bevy_state` is enabled. ## Migration Guide `App::init_state` is now provided by the `bevy_state::app::AppExtStates;` trait: import it if you need this method and are not blob-importing the `bevy` prelude.
This commit is contained in:
parent
7307d76fb3
commit
25f7a29a2f
9 changed files with 173 additions and 153 deletions
|
@ -11,10 +11,9 @@ keywords = ["bevy"]
|
||||||
[features]
|
[features]
|
||||||
trace = []
|
trace = []
|
||||||
bevy_debug_stepping = []
|
bevy_debug_stepping = []
|
||||||
default = ["bevy_reflect", "bevy_state"]
|
default = ["bevy_reflect"]
|
||||||
bevy_reflect = ["dep:bevy_reflect", "bevy_ecs/bevy_reflect"]
|
bevy_reflect = ["dep:bevy_reflect", "bevy_ecs/bevy_reflect"]
|
||||||
serialize = ["bevy_ecs/serde"]
|
serialize = ["bevy_ecs/serde"]
|
||||||
bevy_state = ["dep:bevy_state"]
|
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
# bevy
|
# bevy
|
||||||
|
@ -23,7 +22,6 @@ bevy_ecs = { path = "../bevy_ecs", version = "0.14.0-dev", default-features = fa
|
||||||
bevy_reflect = { path = "../bevy_reflect", version = "0.14.0-dev", optional = true }
|
bevy_reflect = { path = "../bevy_reflect", version = "0.14.0-dev", optional = true }
|
||||||
bevy_utils = { path = "../bevy_utils", version = "0.14.0-dev" }
|
bevy_utils = { path = "../bevy_utils", version = "0.14.0-dev" }
|
||||||
bevy_tasks = { path = "../bevy_tasks", version = "0.14.0-dev" }
|
bevy_tasks = { path = "../bevy_tasks", version = "0.14.0-dev" }
|
||||||
bevy_state = { path = "../bevy_state", optional = true, version = "0.14.0-dev" }
|
|
||||||
|
|
||||||
# other
|
# other
|
||||||
serde = { version = "1.0", features = ["derive"], optional = true }
|
serde = { version = "1.0", features = ["derive"], optional = true }
|
||||||
|
|
|
@ -10,8 +10,6 @@ use bevy_ecs::{
|
||||||
schedule::{ScheduleBuildSettings, ScheduleLabel},
|
schedule::{ScheduleBuildSettings, ScheduleLabel},
|
||||||
system::SystemId,
|
system::SystemId,
|
||||||
};
|
};
|
||||||
#[cfg(feature = "bevy_state")]
|
|
||||||
use bevy_state::{prelude::*, state::FreelyMutableState};
|
|
||||||
#[cfg(feature = "trace")]
|
#[cfg(feature = "trace")]
|
||||||
use bevy_utils::tracing::info_span;
|
use bevy_utils::tracing::info_span;
|
||||||
use bevy_utils::{tracing::debug, HashMap};
|
use bevy_utils::{tracing::debug, HashMap};
|
||||||
|
@ -266,59 +264,6 @@ impl App {
|
||||||
self.sub_apps.iter().any(|s| s.is_building_plugins())
|
self.sub_apps.iter().any(|s| s.is_building_plugins())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "bevy_state")]
|
|
||||||
/// Initializes a [`State`] with standard starting values.
|
|
||||||
///
|
|
||||||
/// This method is idempotent: it has no effect when called again using the same generic type.
|
|
||||||
///
|
|
||||||
/// Adds [`State<S>`] and [`NextState<S>`] resources, and enables use of the [`OnEnter`], [`OnTransition`] and [`OnExit`] schedules.
|
|
||||||
/// These schedules are triggered before [`Update`](crate::Update) and at startup.
|
|
||||||
///
|
|
||||||
/// If you would like to control how other systems run based on the current state, you can
|
|
||||||
/// emulate this behavior using the [`in_state`] [`Condition`].
|
|
||||||
///
|
|
||||||
/// Note that you can also apply state transitions at other points in the schedule
|
|
||||||
/// by triggering the [`StateTransition`](`bevy_ecs::schedule::StateTransition`) schedule manually.
|
|
||||||
pub fn init_state<S: FreelyMutableState + FromWorld>(&mut self) -> &mut Self {
|
|
||||||
self.main_mut().init_state::<S>();
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature = "bevy_state")]
|
|
||||||
/// Inserts a specific [`State`] to the current [`App`] and overrides any [`State`] previously
|
|
||||||
/// added of the same type.
|
|
||||||
///
|
|
||||||
/// Adds [`State<S>`] and [`NextState<S>`] resources, and enables use of the [`OnEnter`], [`OnTransition`] and [`OnExit`] schedules.
|
|
||||||
/// These schedules are triggered before [`Update`](crate::Update) and at startup.
|
|
||||||
///
|
|
||||||
/// If you would like to control how other systems run based on the current state, you can
|
|
||||||
/// emulate this behavior using the [`in_state`] [`Condition`].
|
|
||||||
///
|
|
||||||
/// Note that you can also apply state transitions at other points in the schedule
|
|
||||||
/// by triggering the [`StateTransition`](`bevy_ecs::schedule::StateTransition`) schedule manually.
|
|
||||||
pub fn insert_state<S: FreelyMutableState>(&mut self, state: S) -> &mut Self {
|
|
||||||
self.main_mut().insert_state::<S>(state);
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature = "bevy_state")]
|
|
||||||
/// Sets up a type implementing [`ComputedStates`].
|
|
||||||
///
|
|
||||||
/// This method is idempotent: it has no effect when called again using the same generic type.
|
|
||||||
pub fn add_computed_state<S: ComputedStates>(&mut self) -> &mut Self {
|
|
||||||
self.main_mut().add_computed_state::<S>();
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature = "bevy_state")]
|
|
||||||
/// Sets up a type implementing [`SubStates`].
|
|
||||||
///
|
|
||||||
/// This method is idempotent: it has no effect when called again using the same generic type.
|
|
||||||
pub fn add_sub_state<S: SubStates>(&mut self) -> &mut Self {
|
|
||||||
self.main_mut().add_sub_state::<S>();
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Adds one or more systems to the given schedule in this app's [`Schedules`].
|
/// Adds one or more systems to the given schedule in this app's [`Schedules`].
|
||||||
///
|
///
|
||||||
/// # Examples
|
/// # Examples
|
||||||
|
|
|
@ -4,8 +4,6 @@ use bevy_ecs::{
|
||||||
system::{Local, Resource},
|
system::{Local, Resource},
|
||||||
world::{Mut, World},
|
world::{Mut, World},
|
||||||
};
|
};
|
||||||
#[cfg(feature = "bevy_state")]
|
|
||||||
use bevy_state::state::StateTransition;
|
|
||||||
|
|
||||||
/// The schedule that contains the app logic that is evaluated each tick of [`App::update()`].
|
/// The schedule that contains the app logic that is evaluated each tick of [`App::update()`].
|
||||||
///
|
///
|
||||||
|
@ -175,8 +173,6 @@ impl Default for MainScheduleOrder {
|
||||||
labels: vec![
|
labels: vec![
|
||||||
First.intern(),
|
First.intern(),
|
||||||
PreUpdate.intern(),
|
PreUpdate.intern(),
|
||||||
#[cfg(feature = "bevy_state")]
|
|
||||||
StateTransition.intern(),
|
|
||||||
RunFixedMainLoop.intern(),
|
RunFixedMainLoop.intern(),
|
||||||
Update.intern(),
|
Update.intern(),
|
||||||
SpawnScene.intern(),
|
SpawnScene.intern(),
|
||||||
|
|
|
@ -1,15 +1,10 @@
|
||||||
use crate::{App, InternedAppLabel, Plugin, Plugins, PluginsState, Startup};
|
use crate::{App, InternedAppLabel, Plugin, Plugins, PluginsState};
|
||||||
use bevy_ecs::{
|
use bevy_ecs::{
|
||||||
event::EventRegistry,
|
event::EventRegistry,
|
||||||
prelude::*,
|
prelude::*,
|
||||||
schedule::{InternedScheduleLabel, ScheduleBuildSettings, ScheduleLabel},
|
schedule::{InternedScheduleLabel, ScheduleBuildSettings, ScheduleLabel},
|
||||||
system::SystemId,
|
system::SystemId,
|
||||||
};
|
};
|
||||||
#[cfg(feature = "bevy_state")]
|
|
||||||
use bevy_state::{
|
|
||||||
prelude::*,
|
|
||||||
state::{setup_state_transitions_in_world, FreelyMutableState},
|
|
||||||
};
|
|
||||||
|
|
||||||
#[cfg(feature = "trace")]
|
#[cfg(feature = "trace")]
|
||||||
use bevy_utils::tracing::info_span;
|
use bevy_utils::tracing::info_span;
|
||||||
|
@ -298,88 +293,6 @@ impl SubApp {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "bevy_state")]
|
|
||||||
/// See [`App::init_state`].
|
|
||||||
pub fn init_state<S: FreelyMutableState + FromWorld>(&mut self) -> &mut Self {
|
|
||||||
if !self.world.contains_resource::<State<S>>() {
|
|
||||||
setup_state_transitions_in_world(&mut self.world, Some(Startup.intern()));
|
|
||||||
self.init_resource::<State<S>>()
|
|
||||||
.init_resource::<NextState<S>>()
|
|
||||||
.add_event::<StateTransitionEvent<S>>();
|
|
||||||
let schedule = self.get_schedule_mut(StateTransition).unwrap();
|
|
||||||
S::register_state(schedule);
|
|
||||||
let state = self.world.resource::<State<S>>().get().clone();
|
|
||||||
self.world.send_event(StateTransitionEvent {
|
|
||||||
exited: None,
|
|
||||||
entered: Some(state),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature = "bevy_state")]
|
|
||||||
/// See [`App::insert_state`].
|
|
||||||
pub fn insert_state<S: FreelyMutableState>(&mut self, state: S) -> &mut Self {
|
|
||||||
if !self.world.contains_resource::<State<S>>() {
|
|
||||||
setup_state_transitions_in_world(&mut self.world, Some(Startup.intern()));
|
|
||||||
self.insert_resource::<State<S>>(State::new(state.clone()))
|
|
||||||
.init_resource::<NextState<S>>()
|
|
||||||
.add_event::<StateTransitionEvent<S>>();
|
|
||||||
let schedule = self.get_schedule_mut(StateTransition).unwrap();
|
|
||||||
S::register_state(schedule);
|
|
||||||
self.world.send_event(StateTransitionEvent {
|
|
||||||
exited: None,
|
|
||||||
entered: Some(state),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature = "bevy_state")]
|
|
||||||
/// See [`App::add_computed_state`].
|
|
||||||
pub fn add_computed_state<S: ComputedStates>(&mut self) -> &mut Self {
|
|
||||||
if !self
|
|
||||||
.world
|
|
||||||
.contains_resource::<Events<StateTransitionEvent<S>>>()
|
|
||||||
{
|
|
||||||
setup_state_transitions_in_world(&mut self.world, Some(Startup.intern()));
|
|
||||||
self.add_event::<StateTransitionEvent<S>>();
|
|
||||||
let schedule = self.get_schedule_mut(StateTransition).unwrap();
|
|
||||||
S::register_computed_state_systems(schedule);
|
|
||||||
let state = self.world.resource::<State<S>>().get().clone();
|
|
||||||
self.world.send_event(StateTransitionEvent {
|
|
||||||
exited: None,
|
|
||||||
entered: Some(state),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature = "bevy_state")]
|
|
||||||
/// See [`App::add_sub_state`].
|
|
||||||
pub fn add_sub_state<S: SubStates>(&mut self) -> &mut Self {
|
|
||||||
if !self
|
|
||||||
.world
|
|
||||||
.contains_resource::<Events<StateTransitionEvent<S>>>()
|
|
||||||
{
|
|
||||||
setup_state_transitions_in_world(&mut self.world, Some(Startup.intern()));
|
|
||||||
self.init_resource::<NextState<S>>();
|
|
||||||
self.add_event::<StateTransitionEvent<S>>();
|
|
||||||
let schedule = self.get_schedule_mut(StateTransition).unwrap();
|
|
||||||
S::register_sub_state_systems(schedule);
|
|
||||||
let state = self.world.resource::<State<S>>().get().clone();
|
|
||||||
self.world.send_event(StateTransitionEvent {
|
|
||||||
exited: None,
|
|
||||||
entered: Some(state),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
/// See [`App::add_event`].
|
/// See [`App::add_event`].
|
||||||
pub fn add_event<T>(&mut self) -> &mut Self
|
pub fn add_event<T>(&mut self) -> &mut Self
|
||||||
where
|
where
|
||||||
|
|
|
@ -183,7 +183,7 @@ bevy_dev_tools = ["dep:bevy_dev_tools"]
|
||||||
ios_simulator = ["bevy_pbr?/ios_simulator", "bevy_render?/ios_simulator"]
|
ios_simulator = ["bevy_pbr?/ios_simulator", "bevy_render?/ios_simulator"]
|
||||||
|
|
||||||
# Enable built in global state machines
|
# Enable built in global state machines
|
||||||
bevy_state = ["dep:bevy_state", "bevy_app/bevy_state"]
|
bevy_state = ["dep:bevy_state"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
# bevy
|
# bevy
|
||||||
|
|
|
@ -138,6 +138,11 @@ impl PluginGroup for DefaultPlugins {
|
||||||
group = group.add(bevy_gizmos::GizmoPlugin);
|
group = group.add(bevy_gizmos::GizmoPlugin);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "bevy_state")]
|
||||||
|
{
|
||||||
|
group = group.add(bevy_state::app::StatesPlugin);
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(feature = "bevy_dev_tools")]
|
#[cfg(feature = "bevy_dev_tools")]
|
||||||
{
|
{
|
||||||
group = group.add(bevy_dev_tools::DevToolsPlugin);
|
group = group.add(bevy_dev_tools::DevToolsPlugin);
|
||||||
|
|
|
@ -12,14 +12,16 @@ categories = ["game-engines", "data-structures"]
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["bevy_reflect"]
|
default = ["bevy_reflect", "bevy_app"]
|
||||||
|
bevy_reflect = ["dep:bevy_reflect", "bevy_ecs/bevy_reflect"]
|
||||||
|
bevy_app = ["dep:bevy_app"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
bevy_ecs = { path = "../bevy_ecs", version = "0.14.0-dev" }
|
bevy_ecs = { path = "../bevy_ecs", version = "0.14.0-dev" }
|
||||||
bevy_state_macros = { path = "macros", version = "0.14.0-dev" }
|
bevy_state_macros = { path = "macros", version = "0.14.0-dev" }
|
||||||
bevy_utils = { path = "../bevy_utils", version = "0.14.0-dev" }
|
bevy_utils = { path = "../bevy_utils", version = "0.14.0-dev" }
|
||||||
bevy_reflect = { path = "../bevy_reflect", version = "0.14.0-dev", optional = true }
|
bevy_reflect = { path = "../bevy_reflect", version = "0.14.0-dev", optional = true }
|
||||||
|
bevy_app = { path = "../bevy_app", version = "0.14.0-dev", optional = true }
|
||||||
|
|
||||||
[lints]
|
[lints]
|
||||||
workspace = true
|
workspace = true
|
||||||
|
|
155
crates/bevy_state/src/app.rs
Normal file
155
crates/bevy_state/src/app.rs
Normal file
|
@ -0,0 +1,155 @@
|
||||||
|
use bevy_app::{App, MainScheduleOrder, Plugin, PreUpdate, Startup, SubApp};
|
||||||
|
use bevy_ecs::{event::Events, schedule::ScheduleLabel, world::FromWorld};
|
||||||
|
|
||||||
|
use crate::state::{
|
||||||
|
setup_state_transitions_in_world, ComputedStates, FreelyMutableState, NextState, State,
|
||||||
|
StateTransition, StateTransitionEvent, SubStates,
|
||||||
|
};
|
||||||
|
|
||||||
|
/// State installation methods for [`App`](bevy_app::App) and [`SubApp`](bevy_app::SubApp).
|
||||||
|
pub trait AppExtStates {
|
||||||
|
/// Initializes a [`State`] with standard starting values.
|
||||||
|
///
|
||||||
|
/// This method is idempotent: it has no effect when called again using the same generic type.
|
||||||
|
///
|
||||||
|
/// Adds [`State<S>`] and [`NextState<S>`] resources, and enables use of the [`OnEnter`], [`OnTransition`] and [`OnExit`] schedules.
|
||||||
|
/// These schedules are triggered before [`Update`](crate::Update) and at startup.
|
||||||
|
///
|
||||||
|
/// If you would like to control how other systems run based on the current state, you can
|
||||||
|
/// emulate this behavior using the [`in_state`] [`Condition`].
|
||||||
|
///
|
||||||
|
/// Note that you can also apply state transitions at other points in the schedule
|
||||||
|
/// by triggering the [`StateTransition`](`bevy_ecs::schedule::StateTransition`) schedule manually.
|
||||||
|
fn init_state<S: FreelyMutableState + FromWorld>(&mut self) -> &mut Self;
|
||||||
|
|
||||||
|
/// Inserts a specific [`State`] to the current [`App`] and overrides any [`State`] previously
|
||||||
|
/// added of the same type.
|
||||||
|
///
|
||||||
|
/// Adds [`State<S>`] and [`NextState<S>`] resources, and enables use of the [`OnEnter`], [`OnTransition`] and [`OnExit`] schedules.
|
||||||
|
/// These schedules are triggered before [`Update`](crate::Update) and at startup.
|
||||||
|
///
|
||||||
|
/// If you would like to control how other systems run based on the current state, you can
|
||||||
|
/// emulate this behavior using the [`in_state`] [`Condition`].
|
||||||
|
///
|
||||||
|
/// Note that you can also apply state transitions at other points in the schedule
|
||||||
|
/// by triggering the [`StateTransition`](`bevy_ecs::schedule::StateTransition`) schedule manually.
|
||||||
|
fn insert_state<S: FreelyMutableState>(&mut self, state: S) -> &mut Self;
|
||||||
|
|
||||||
|
/// Sets up a type implementing [`ComputedStates`].
|
||||||
|
///
|
||||||
|
/// This method is idempotent: it has no effect when called again using the same generic type.
|
||||||
|
fn add_computed_state<S: ComputedStates>(&mut self) -> &mut Self;
|
||||||
|
|
||||||
|
/// Sets up a type implementing [`SubStates`].
|
||||||
|
///
|
||||||
|
/// This method is idempotent: it has no effect when called again using the same generic type.
|
||||||
|
fn add_sub_state<S: SubStates>(&mut self) -> &mut Self;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AppExtStates for SubApp {
|
||||||
|
fn init_state<S: FreelyMutableState + FromWorld>(&mut self) -> &mut Self {
|
||||||
|
if !self.world().contains_resource::<State<S>>() {
|
||||||
|
setup_state_transitions_in_world(self.world_mut(), Some(Startup.intern()));
|
||||||
|
self.init_resource::<State<S>>()
|
||||||
|
.init_resource::<NextState<S>>()
|
||||||
|
.add_event::<StateTransitionEvent<S>>();
|
||||||
|
let schedule = self.get_schedule_mut(StateTransition).unwrap();
|
||||||
|
S::register_state(schedule);
|
||||||
|
let state = self.world().resource::<State<S>>().get().clone();
|
||||||
|
self.world_mut().send_event(StateTransitionEvent {
|
||||||
|
exited: None,
|
||||||
|
entered: Some(state),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
fn insert_state<S: FreelyMutableState>(&mut self, state: S) -> &mut Self {
|
||||||
|
if !self.world().contains_resource::<State<S>>() {
|
||||||
|
setup_state_transitions_in_world(self.world_mut(), Some(Startup.intern()));
|
||||||
|
self.insert_resource::<State<S>>(State::new(state.clone()))
|
||||||
|
.init_resource::<NextState<S>>()
|
||||||
|
.add_event::<StateTransitionEvent<S>>();
|
||||||
|
let schedule = self.get_schedule_mut(StateTransition).unwrap();
|
||||||
|
S::register_state(schedule);
|
||||||
|
self.world_mut().send_event(StateTransitionEvent {
|
||||||
|
exited: None,
|
||||||
|
entered: Some(state),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
fn add_computed_state<S: ComputedStates>(&mut self) -> &mut Self {
|
||||||
|
if !self
|
||||||
|
.world()
|
||||||
|
.contains_resource::<Events<StateTransitionEvent<S>>>()
|
||||||
|
{
|
||||||
|
setup_state_transitions_in_world(self.world_mut(), Some(Startup.intern()));
|
||||||
|
self.add_event::<StateTransitionEvent<S>>();
|
||||||
|
let schedule = self.get_schedule_mut(StateTransition).unwrap();
|
||||||
|
S::register_computed_state_systems(schedule);
|
||||||
|
let state = self.world().resource::<State<S>>().get().clone();
|
||||||
|
self.world_mut().send_event(StateTransitionEvent {
|
||||||
|
exited: None,
|
||||||
|
entered: Some(state),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
fn add_sub_state<S: SubStates>(&mut self) -> &mut Self {
|
||||||
|
if !self
|
||||||
|
.world()
|
||||||
|
.contains_resource::<Events<StateTransitionEvent<S>>>()
|
||||||
|
{
|
||||||
|
setup_state_transitions_in_world(self.world_mut(), Some(Startup.intern()));
|
||||||
|
self.init_resource::<NextState<S>>();
|
||||||
|
self.add_event::<StateTransitionEvent<S>>();
|
||||||
|
let schedule = self.get_schedule_mut(StateTransition).unwrap();
|
||||||
|
S::register_sub_state_systems(schedule);
|
||||||
|
let state = self.world().resource::<State<S>>().get().clone();
|
||||||
|
self.world_mut().send_event(StateTransitionEvent {
|
||||||
|
exited: None,
|
||||||
|
entered: Some(state),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AppExtStates for App {
|
||||||
|
fn init_state<S: FreelyMutableState + FromWorld>(&mut self) -> &mut Self {
|
||||||
|
self.main_mut().init_state::<S>();
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
fn insert_state<S: FreelyMutableState>(&mut self, state: S) -> &mut Self {
|
||||||
|
self.main_mut().insert_state::<S>(state);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
fn add_computed_state<S: ComputedStates>(&mut self) -> &mut Self {
|
||||||
|
self.main_mut().add_computed_state::<S>();
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
fn add_sub_state<S: SubStates>(&mut self) -> &mut Self {
|
||||||
|
self.main_mut().add_sub_state::<S>();
|
||||||
|
self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Registers the [`StateTransition`] schedule in the [`MainScheduleOrder`] to enable state processing.
|
||||||
|
pub struct StatesPlugin;
|
||||||
|
|
||||||
|
impl Plugin for StatesPlugin {
|
||||||
|
fn build(&self, app: &mut App) {
|
||||||
|
let mut schedule = app.world_mut().resource_mut::<MainScheduleOrder>();
|
||||||
|
schedule.insert_after(PreUpdate, StateTransition);
|
||||||
|
}
|
||||||
|
}
|
|
@ -27,6 +27,9 @@
|
||||||
//! - The [`in_state<S>`](crate::condition::in_state) and [`state_changed<S>`](crate::condition::state_changed) run conditions - which are used
|
//! - The [`in_state<S>`](crate::condition::in_state) and [`state_changed<S>`](crate::condition::state_changed) run conditions - which are used
|
||||||
//! to determine whether a system should run based on the current state.
|
//! to determine whether a system should run based on the current state.
|
||||||
|
|
||||||
|
#[cfg(feature = "bevy_app")]
|
||||||
|
/// Provides [`App`](bevy_app::App) and [`SubApp`](bevy_app::SubApp) with state installation methods
|
||||||
|
pub mod app;
|
||||||
/// Provides definitions for the runtime conditions that interact with the state system
|
/// Provides definitions for the runtime conditions that interact with the state system
|
||||||
pub mod condition;
|
pub mod condition;
|
||||||
/// Provides definitions for the basic traits required by the state system
|
/// Provides definitions for the basic traits required by the state system
|
||||||
|
@ -34,6 +37,9 @@ pub mod state;
|
||||||
|
|
||||||
/// Most commonly used re-exported types.
|
/// Most commonly used re-exported types.
|
||||||
pub mod prelude {
|
pub mod prelude {
|
||||||
|
#[cfg(feature = "bevy_app")]
|
||||||
|
#[doc(hidden)]
|
||||||
|
pub use crate::app::AppExtStates;
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
pub use crate::condition::*;
|
pub use crate::condition::*;
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
|
|
Loading…
Add table
Reference in a new issue