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
9418 views
1
use bevy_ecs::{
2
message::MessageWriter,
3
prelude::Schedule,
4
schedule::IntoScheduleConfigs,
5
system::{Commands, IntoSystem, ResMut},
6
};
7
8
use super::{states::States, take_next_state, transitions::*, NextState, PreviousState, 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: MessageWriter<StateTransitionEvent<S>>,
51
commands: Commands,
52
current_state: Option<ResMut<State<S>>>,
53
previous_state: Option<ResMut<PreviousState<S>>>,
54
next_state: Option<ResMut<NextState<S>>>,
55
) {
56
let Some((next_state, allow_same_state_transitions)) = take_next_state(next_state) else {
57
return;
58
};
59
let Some(current_state) = current_state else {
60
return;
61
};
62
internal_apply_state_transition(
63
event,
64
commands,
65
Some(current_state),
66
previous_state,
67
Some(next_state),
68
allow_same_state_transitions,
69
);
70
}
71
72