1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
use Schedule;
use ;
pub use SubStates;
/// A sub-state is a state that exists only when the source state meet certain conditions,
/// but unlike [`ComputedStates`](crate::state::ComputedStates) - while they exist they can be manually modified.
///
/// The default approach to creating [`SubStates`] is using the derive macro, and defining a single source state
/// and value to determine its existence.
///
/// ```
/// # use bevy_ecs::prelude::*;
/// # use bevy_state::prelude::*;
///
/// #[derive(States, Clone, PartialEq, Eq, Hash, Debug, Default)]
/// enum AppState {
/// #[default]
/// Menu,
/// InGame
/// }
///
///
/// #[derive(SubStates, Clone, PartialEq, Eq, Hash, Debug, Default)]
/// #[source(AppState = AppState::InGame)]
/// enum GamePhase {
/// #[default]
/// Setup,
/// Battle,
/// Conclusion
/// }
/// ```
///
/// you can then add it to an App, and from there you use the state as normal:
///
/// ```
/// # use bevy_ecs::prelude::*;
/// # use bevy_state::prelude::*;
///
/// # struct App;
/// # impl App {
/// # fn new() -> Self { App }
/// # fn init_state<S>(&mut self) -> &mut Self {self}
/// # fn add_sub_state<S>(&mut self) -> &mut Self {self}
/// # }
/// # struct AppState;
/// # struct GamePhase;
///
/// App::new()
/// .init_state::<AppState>()
/// .add_sub_state::<GamePhase>();
/// ```
///
/// In more complex situations, the recommendation is to use an intermediary computed state, like so:
///
/// ```
/// # use bevy_ecs::prelude::*;
/// # use bevy_state::prelude::*;
///
/// /// Computed States require some state to derive from
/// #[derive(States, Clone, PartialEq, Eq, Hash, Debug, Default)]
/// enum AppState {
/// #[default]
/// Menu,
/// InGame { paused: bool }
/// }
///
/// #[derive(Clone, PartialEq, Eq, Hash, Debug)]
/// struct InGame;
///
/// impl ComputedStates for InGame {
/// /// We set the source state to be the state, or set of states,
/// /// we want to depend on. Any of the states can be wrapped in an Option.
/// type SourceStates = Option<AppState>;
///
/// /// We then define the compute function, which takes in the AppState
/// fn compute(sources: Option<AppState>) -> Option<Self> {
/// match sources {
/// /// When we are in game, we want to return the InGame state
/// Some(AppState::InGame { .. }) => Some(InGame),
/// /// Otherwise, we don't want the `State<InGame>` resource to exist,
/// /// so we return None.
/// _ => None
/// }
/// }
/// }
///
/// #[derive(SubStates, Clone, PartialEq, Eq, Hash, Debug, Default)]
/// #[source(InGame = InGame)]
/// enum GamePhase {
/// #[default]
/// Setup,
/// Battle,
/// Conclusion
/// }
/// ```
///
/// However, you can also manually implement them. If you do so, you'll also need to manually implement the `States` & `FreelyMutableState` traits.
///
/// ```
/// # use bevy_ecs::prelude::*;
/// # use bevy_state::prelude::*;
/// # use bevy_state::state::{FreelyMutableState, NextState};
///
/// /// Computed States require some state to derive from
/// #[derive(States, Clone, PartialEq, Eq, Hash, Debug, Default)]
/// enum AppState {
/// #[default]
/// Menu,
/// InGame { paused: bool }
/// }
///
/// #[derive(Clone, PartialEq, Eq, Hash, Debug)]
/// enum GamePhase {
/// Setup,
/// Battle,
/// Conclusion
/// }
///
/// impl SubStates for GamePhase {
/// /// We set the source state to be the state, or set of states,
/// /// we want to depend on. Any of the states can be wrapped in an Option.
/// type SourceStates = Option<AppState>;
///
/// /// We then define the compute function, which takes in the [`Self::SourceStates`]
/// fn should_exist(sources: Option<AppState>) -> Option<Self> {
/// match sources {
/// /// When we are in game, we want a GamePhase state to exist.
/// /// We can set the initial value here or overwrite it through [`NextState`].
/// Some(AppState::InGame { .. }) => Some(Self::Setup),
/// /// If we don't want the `State<GamePhase>` resource to exist we return [`None`].
/// _ => None
/// }
/// }
/// }
///
/// impl States for GamePhase {
/// const DEPENDENCY_DEPTH : usize = <GamePhase as SubStates>::SourceStates::SET_DEPENDENCY_DEPTH + 1;
/// }
///
/// impl FreelyMutableState for GamePhase {}
/// ```