bevy
bevy copied to clipboard
Add PreviousState Resource accessible in OnEnter
Objective
- Adds a
PreviousStateresource to track the last active state, making it accessible during state transitions (e.g., inOnEnterschedules). - Fixes #21882.
Solution
- Added a new
PreviousState<S: States>resource. - Updated
internal_apply_state_transitionto manage the lifecycle ofPreviousState:- Standard Transition: Updates
PreviousStateto the exited state. - Creation: If a state is initialized (transition from None), any existing
PreviousStateis removed. - Removal: If a state is removed,
PreviousStateis updated to preserve the last known state.
- Standard Transition: Updates
- Registered
PreviousStateinAppExtStatesfor reflection and general access. - Ensured
PreviousStateis available forOnEntersystems by usingApplyDeferredordering insetup_state_transitions_in_world.
Testing
- Added a temporary local unit test previous_state_is_tracked_correctly which verifies that
PreviousStateis created, updated, and persisted correctly across multiple state transitions. - The implementation covered scenarios including standard transitions, state initialization (where no previous state exists), and state removal.
- Don't think I handled all edge cases, would appreciate a second look.
Showcase
You can now access the state you just transitioned from directly in your systems!
fn handle_state_refresh<S: FreelyMutableState>(
prev_state: Option<Res<PreviousState<S>>>,
mut next_state: ResMut<NextState<S>>
) {
if let Some(prev) = prev_state {
println!("We just came from {:?}", prev.0);
// Example: revert to previous state
next_state.set(prev.0.clone());
}
}
app.add_systems(OnEnter(GameState::Refresh), handle_state_refresh::<GameState>);
This is my first contribution, would highly appreciate some feedback!
Welcome, new contributor!
Please make sure you've read our contributing guide and we look forward to reviewing your pull request shortly ✨
Alright, so I've removed the ApplyDeferred section now. There's a merge conflict due to #21792, but as far as I see it's a quick fix. Should I be the one to handle that, or would you prefer to?
Yes please; handling merge conflicts is done by authors around here :)