Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
bevyengine
GitHub Repository: bevyengine/bevy
Path: blob/main/crates/bevy_state/src/state/states.rs
6596 views
1
use core::fmt::Debug;
2
3
use core::hash::Hash;
4
5
/// Types that can define world-wide states in a finite-state machine.
6
///
7
/// The [`Default`] trait defines the starting state.
8
/// Multiple states can be defined for the same world,
9
/// allowing you to classify the state of the world across orthogonal dimensions.
10
/// You can access the current state of type `T` with the [`State<T>`](crate::state::State) resource,
11
/// and the queued state with the [`NextState<T>`](crate::state::NextState) resource.
12
///
13
/// State transitions typically occur in the [`OnEnter<T::Variant>`](crate::state::OnEnter) and [`OnExit<T::Variant>`](crate::state::OnExit) schedules,
14
/// which can be run by triggering the [`StateTransition`](crate::state::StateTransition) schedule.
15
///
16
/// Types used as [`ComputedStates`](crate::state::ComputedStates) do not need to and should not derive [`States`].
17
/// [`ComputedStates`](crate::state::ComputedStates) should not be manually mutated: functionality provided
18
/// by the [`States`] derive and the associated [`FreelyMutableState`](crate::state::FreelyMutableState) trait.
19
///
20
/// # Example
21
///
22
/// ```
23
/// use bevy_state::prelude::*;
24
/// use bevy_ecs::prelude::IntoScheduleConfigs;
25
/// use bevy_ecs::system::{ResMut, ScheduleSystem};
26
///
27
///
28
/// #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, Default, States)]
29
/// enum GameState {
30
/// #[default]
31
/// MainMenu,
32
/// SettingsMenu,
33
/// InGame,
34
/// }
35
///
36
/// fn handle_escape_pressed(mut next_state: ResMut<NextState<GameState>>) {
37
/// # let escape_pressed = true;
38
/// if escape_pressed {
39
/// next_state.set(GameState::SettingsMenu);
40
/// }
41
/// }
42
///
43
/// fn open_settings_menu() {
44
/// // Show the settings menu...
45
/// }
46
///
47
/// # struct AppMock;
48
/// # impl AppMock {
49
/// # fn init_state<S>(&mut self) {}
50
/// # fn add_systems<S, M>(&mut self, schedule: S, systems: impl IntoScheduleConfigs<ScheduleSystem, M>) {}
51
/// # }
52
/// # struct Update;
53
/// # let mut app = AppMock;
54
///
55
/// app.init_state::<GameState>();
56
/// app.add_systems(Update, handle_escape_pressed.run_if(in_state(GameState::MainMenu)));
57
/// app.add_systems(OnEnter(GameState::SettingsMenu), open_settings_menu);
58
/// ```
59
#[diagnostic::on_unimplemented(
60
message = "`{Self}` can not be used as a state",
61
label = "invalid state",
62
note = "consider annotating `{Self}` with `#[derive(States)]`"
63
)]
64
pub trait States: 'static + Send + Sync + Clone + PartialEq + Eq + Hash + Debug {
65
/// How many other states this state depends on.
66
/// Used to help order transitions and de-duplicate [`ComputedStates`](crate::state::ComputedStates), as well as prevent cyclical
67
/// `ComputedState` dependencies.
68
const DEPENDENCY_DEPTH: usize = 1;
69
}
70
71