Closed
Description
What problem does this solve or what need does it fill?
Suppose we wanted a State<Direction>
to switch from Direction::Down
, to Direction::Up
, then again to Direction::Down
, within one tick. While this seems pointless, we may want distinct systems to displace the current scheduled state operation. With the current semantics of overwrite_set
this is not possible.
use bevy::{log::LogPlugin, prelude::*};
#[derive(Clone, PartialEq, Eq, Debug, Hash)]
enum Switch {
On,
Off,
}
#[derive(Clone, PartialEq, Eq, Debug, Hash)]
enum Direction {
Up,
Down,
}
fn main() {
let up = SystemSet::on_enter(Switch::On)
.label("A")
.with_system(set_up);
let down = SystemSet::on_enter(Switch::On)
.label("B")
.after("A")
.with_system(set_down);
App::new()
.add_plugins(MinimalPlugins)
.add_plugin(LogPlugin::default())
.add_state(Switch::Off)
.add_state(Direction::Down)
.add_startup_system(switch_on)
.add_system_set(up)
.add_system_set(down)
.add_system(print_direction)
.run()
}
fn switch_on(mut state: ResMut<State<Switch>>) {
state.set(Switch::On);
}
fn set_up(mut state: ResMut<State<Direction>>) {
state.overwrite_set(Direction::Up);
}
fn set_down(mut state: ResMut<State<Direction>>) {
state.overwrite_set(Direction::Down);
}
fn print_direction(state: Res<State<Direction>>) {
info!("{:?}", state.current());
}
The following will print Up
despite set_down
being called strictly after set_up
.
This is a direct result of the form of overwrite_set
pub fn overwrite_set(&mut self, state: T) -> Result<(), StateError> {
if self.stack.last().unwrap() == &state {
// We're accepted into this branch and return early
return Err(StateError::AlreadyInState);
}
self.scheduled = Some(ScheduledOperation::Set(state));
Ok(())
}
What solution would you like?
A non-breaking work around would be to add a clear_schedule
method onto State
which sets self.scheduled = None
. This could then be called in the case when set_overwrite
returns Err
.
What alternative(s) have you considered?
Changing the semantics of overwrite_set
, this would be a breaking change and non-obvious implementation.