Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
bevyengine
GitHub Repository: bevyengine/bevy
Path: blob/main/crates/bevy_state/src/state/freely_mutable_state.rs
6596 views
1
use bevy_ecs::{
2
event::EventWriter,
3
prelude::Schedule,
4
schedule::IntoScheduleConfigs,
5
system::{Commands, IntoSystem, ResMut},
6
};
7
8
use super::{states::States, take_next_state, transitions::*, NextState, State};
9
10
/// This trait allows a state to be mutated directly using the [`NextState<S>`](crate::state::NextState) resource.
11
///
12
/// While ordinary states are freely mutable (and implement this trait as part of their derive macro),
13
/// computed states are not: instead, they can *only* change when the states that drive them do.
14
#[diagnostic::on_unimplemented(note = "consider annotating `{Self}` with `#[derive(States)]`")]
15
pub trait FreelyMutableState: States {
16
/// This function registers all the necessary systems to apply state changes and run transition schedules
17
fn register_state(schedule: &mut Schedule) {
18
schedule.configure_sets((
19
ApplyStateTransition::<Self>::default()
20
.in_set(StateTransitionSystems::DependentTransitions),
21
ExitSchedules::<Self>::default().in_set(StateTransitionSystems::ExitSchedules),
22
TransitionSchedules::<Self>::default()
23
.in_set(StateTransitionSystems::TransitionSchedules),
24
EnterSchedules::<Self>::default().in_set(StateTransitionSystems::EnterSchedules),
25
));
26
27
schedule
28
.add_systems(
29
apply_state_transition::<Self>.in_set(ApplyStateTransition::<Self>::default()),
30
)
31
.add_systems(
32
last_transition::<Self>
33
.pipe(run_exit::<Self>)
34
.in_set(ExitSchedules::<Self>::default()),
35
)
36
.add_systems(
37
last_transition::<Self>
38
.pipe(run_transition::<Self>)
39
.in_set(TransitionSchedules::<Self>::default()),
40
)
41
.add_systems(
42
last_transition::<Self>
43
.pipe(run_enter::<Self>)
44
.in_set(EnterSchedules::<Self>::default()),
45
);
46
}
47
}
48
49
fn apply_state_transition<S: FreelyMutableState>(
50
event: EventWriter<StateTransitionEvent<S>>,
51
commands: Commands,
52
current_state: Option<ResMut<State<S>>>,
53
next_state: Option<ResMut<NextState<S>>>,
54
) {
55
let Some(next_state) = take_next_state(next_state) else {
56
return;
57
};
58
let Some(current_state) = current_state else {
59
return;
60
};
61
internal_apply_state_transition(event, commands, Some(current_state), Some(next_state));
62
}
63
64