mirror of
https://github.com/bevyengine/bevy
synced 2024-11-25 22:20:20 +00:00
Remove .on_update method to improve API consistency and clarity (#7667)
# Objective Fixes #7632. As discussed in #7634, it can be quite challenging for users to intuit the mental model of how states now work. ## Solution Rather than change the behavior of the `OnUpdate` system set, instead work on making sure it's easy to understand what's going on. Two things have been done: 1. Remove the `.on_update` method from our bevy of system building traits. This was special-cased and made states feel much more magical than they need to. 2. Improve the docs for the `OnUpdate` system set.
This commit is contained in:
parent
17ed41d707
commit
0a9c469d19
8 changed files with 19 additions and 54 deletions
|
@ -317,7 +317,7 @@ impl App {
|
|||
/// initial state.
|
||||
///
|
||||
/// This also adds an [`OnUpdate`] system set for each state variant,
|
||||
/// which run during [`CoreSet::StateTransitions`] after the transitions are applied.
|
||||
/// which run during [`CoreSet::Update`] after the transitions are applied.
|
||||
/// These systems sets only run if the [`State<S>`] resource matches their label.
|
||||
///
|
||||
/// If you would like to control how other systems run based on the current state,
|
||||
|
@ -341,7 +341,7 @@ impl App {
|
|||
for variant in S::variants() {
|
||||
main_schedule.configure_set(
|
||||
OnUpdate(variant.clone())
|
||||
.in_base_set(CoreSet::StateTransitions)
|
||||
.in_base_set(CoreSet::Update)
|
||||
.run_if(state_equals(variant))
|
||||
.after(apply_state_transition::<S>),
|
||||
);
|
||||
|
|
|
@ -5,7 +5,6 @@ use crate::{
|
|||
condition::{BoxedCondition, Condition},
|
||||
graph_utils::{Ambiguity, Dependency, DependencyKind, GraphInfo},
|
||||
set::{BoxedSystemSet, IntoSystemSet, SystemSet},
|
||||
state::{OnUpdate, States},
|
||||
},
|
||||
system::{BoxedSystem, IntoSystem, System},
|
||||
};
|
||||
|
@ -102,8 +101,6 @@ pub trait IntoSystemSetConfig: sealed::IntoSystemSetConfig {
|
|||
/// The `Condition` will be evaluated at most once (per schedule run),
|
||||
/// the first time a system in this set prepares to run.
|
||||
fn run_if<P>(self, condition: impl Condition<P>) -> SystemSetConfig;
|
||||
/// Add this set to the [`OnUpdate(state)`](OnUpdate) set.
|
||||
fn on_update(self, state: impl States) -> SystemSetConfig;
|
||||
/// Suppress warnings and errors that would result from systems in this set having ambiguities
|
||||
/// (conflicting access but indeterminate order) with systems in `set`.
|
||||
fn ambiguous_with<M>(self, set: impl IntoSystemSet<M>) -> SystemSetConfig;
|
||||
|
@ -146,10 +143,6 @@ where
|
|||
self.into_config().run_if(condition)
|
||||
}
|
||||
|
||||
fn on_update(self, state: impl States) -> SystemSetConfig {
|
||||
self.into_config().on_update(state)
|
||||
}
|
||||
|
||||
fn ambiguous_with<M>(self, set: impl IntoSystemSet<M>) -> SystemSetConfig {
|
||||
self.into_config().ambiguous_with(set)
|
||||
}
|
||||
|
@ -190,10 +183,6 @@ impl IntoSystemSetConfig for BoxedSystemSet {
|
|||
self.into_config().run_if(condition)
|
||||
}
|
||||
|
||||
fn on_update(self, state: impl States) -> SystemSetConfig {
|
||||
self.into_config().on_update(state)
|
||||
}
|
||||
|
||||
fn ambiguous_with<M>(self, set: impl IntoSystemSet<M>) -> SystemSetConfig {
|
||||
self.into_config().ambiguous_with(set)
|
||||
}
|
||||
|
@ -270,10 +259,6 @@ impl IntoSystemSetConfig for SystemSetConfig {
|
|||
self
|
||||
}
|
||||
|
||||
fn on_update(self, state: impl States) -> SystemSetConfig {
|
||||
self.in_set(OnUpdate(state))
|
||||
}
|
||||
|
||||
fn ambiguous_with<M>(mut self, set: impl IntoSystemSet<M>) -> Self {
|
||||
ambiguous_with(&mut self.graph_info, Box::new(set.into_system_set()));
|
||||
self
|
||||
|
@ -310,8 +295,6 @@ pub trait IntoSystemConfig<Params>: sealed::IntoSystemConfig<Params> {
|
|||
/// The `Condition` will be evaluated at most once (per schedule run),
|
||||
/// when the system prepares to run.
|
||||
fn run_if<P>(self, condition: impl Condition<P>) -> SystemConfig;
|
||||
/// Add this system to the [`OnUpdate(state)`](OnUpdate) set.
|
||||
fn on_update(self, state: impl States) -> SystemConfig;
|
||||
/// Suppress warnings and errors that would result from this system having ambiguities
|
||||
/// (conflicting access but indeterminate order) with systems in `set`.
|
||||
fn ambiguous_with<M>(self, set: impl IntoSystemSet<M>) -> SystemConfig;
|
||||
|
@ -354,10 +337,6 @@ where
|
|||
self.into_config().run_if(condition)
|
||||
}
|
||||
|
||||
fn on_update(self, state: impl States) -> SystemConfig {
|
||||
self.into_config().on_update(state)
|
||||
}
|
||||
|
||||
fn ambiguous_with<M>(self, set: impl IntoSystemSet<M>) -> SystemConfig {
|
||||
self.into_config().ambiguous_with(set)
|
||||
}
|
||||
|
@ -398,10 +377,6 @@ impl IntoSystemConfig<()> for BoxedSystem<(), ()> {
|
|||
self.into_config().run_if(condition)
|
||||
}
|
||||
|
||||
fn on_update(self, state: impl States) -> SystemConfig {
|
||||
self.into_config().on_update(state)
|
||||
}
|
||||
|
||||
fn ambiguous_with<M>(self, set: impl IntoSystemSet<M>) -> SystemConfig {
|
||||
self.into_config().ambiguous_with(set)
|
||||
}
|
||||
|
@ -470,10 +445,6 @@ impl IntoSystemConfig<()> for SystemConfig {
|
|||
self
|
||||
}
|
||||
|
||||
fn on_update(self, state: impl States) -> Self {
|
||||
self.in_set(OnUpdate(state))
|
||||
}
|
||||
|
||||
fn ambiguous_with<M>(mut self, set: impl IntoSystemSet<M>) -> Self {
|
||||
ambiguous_with(&mut self.graph_info, Box::new(set.into_system_set()));
|
||||
self
|
||||
|
@ -549,11 +520,6 @@ where
|
|||
self.into_configs().after(set)
|
||||
}
|
||||
|
||||
/// Add this set to the [`OnUpdate(state)`](OnUpdate) set.
|
||||
fn on_update(self, state: impl States) -> SystemConfigs {
|
||||
self.into_configs().on_update(state)
|
||||
}
|
||||
|
||||
/// Suppress warnings and errors that would result from these systems having ambiguities
|
||||
/// (conflicting access but indeterminate order) with systems in `set`.
|
||||
fn ambiguous_with<M>(self, set: impl IntoSystemSet<M>) -> SystemConfigs {
|
||||
|
@ -654,10 +620,6 @@ impl IntoSystemConfigs<()> for SystemConfigs {
|
|||
self
|
||||
}
|
||||
|
||||
fn on_update(self, state: impl States) -> Self {
|
||||
self.in_set(OnUpdate(state))
|
||||
}
|
||||
|
||||
fn chain(mut self) -> Self {
|
||||
self.chained = true;
|
||||
self
|
||||
|
|
|
@ -53,10 +53,11 @@ pub struct OnEnter<S: States>(pub S);
|
|||
#[derive(ScheduleLabel, Clone, Debug, PartialEq, Eq, Hash)]
|
||||
pub struct OnExit<S: States>(pub S);
|
||||
|
||||
/// A [`SystemSet`] that will run within `CoreSet::StateTransitions` when this state is active.
|
||||
/// A [`SystemSet`] that will run within `CoreSet::Update` when this state is active.
|
||||
///
|
||||
/// This is provided for convenience. A more general [`state_equals`](crate::schedule::common_conditions::state_equals)
|
||||
/// [condition](super::Condition) also exists for systems that need to run elsewhere.
|
||||
/// This set, when created via `App::add_state`, is configured with both a base set and a run condition.
|
||||
/// If all you want is the run condition, use the [`state_equals`](crate::schedule::common_conditions::state_equals)
|
||||
/// [condition](super::Condition) directly.
|
||||
#[derive(SystemSet, Clone, Debug, PartialEq, Eq, Hash)]
|
||||
pub struct OnUpdate<S: States>(pub S);
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@ fn main() {
|
|||
.add_plugins(DefaultPlugins.set(ImagePlugin::default_nearest())) // prevents blurry sprites
|
||||
.add_state::<AppState>()
|
||||
.add_system_to_schedule(OnEnter(AppState::Setup), load_textures)
|
||||
.add_system(check_textures.on_update(AppState::Setup))
|
||||
.add_system(check_textures.in_set(OnUpdate(AppState::Setup)))
|
||||
.add_system_to_schedule(OnEnter(AppState::Finished), setup)
|
||||
.run();
|
||||
}
|
||||
|
|
|
@ -44,7 +44,7 @@ fn main() {
|
|||
.add_state::<AppState>()
|
||||
.add_startup_system(setup_system)
|
||||
.add_system(print_text_system)
|
||||
.add_system(transition_to_in_game_system.on_update(AppState::MainMenu))
|
||||
.add_system(transition_to_in_game_system.in_set(OnUpdate(AppState::MainMenu)))
|
||||
// add the cleanup systems
|
||||
.add_system_to_schedule(
|
||||
OnExit(AppState::MainMenu),
|
||||
|
|
|
@ -18,10 +18,10 @@ fn main() {
|
|||
.add_system_to_schedule(OnEnter(AppState::Menu), setup_menu)
|
||||
// By contrast, on_update systems are stored in the main schedule, during CoreSet::Update,
|
||||
// and simply check the value of the `State<T>` resource to see if they should run each frame.
|
||||
.add_system(menu.on_update(AppState::Menu))
|
||||
.add_system(menu.in_set(OnUpdate(AppState::Menu)))
|
||||
.add_system_to_schedule(OnExit(AppState::Menu), cleanup_menu)
|
||||
.add_system_to_schedule(OnEnter(AppState::InGame), setup_game)
|
||||
.add_systems((movement, change_color).on_update(AppState::InGame))
|
||||
.add_systems((movement, change_color).in_set(OnUpdate(AppState::InGame)))
|
||||
.run();
|
||||
}
|
||||
|
||||
|
|
|
@ -34,11 +34,11 @@ fn main() {
|
|||
scoreboard_system,
|
||||
spawn_bonus,
|
||||
)
|
||||
.on_update(GameState::Playing),
|
||||
.in_set(OnUpdate(GameState::Playing)),
|
||||
)
|
||||
.add_system_to_schedule(OnExit(GameState::Playing), teardown)
|
||||
.add_system_to_schedule(OnEnter(GameState::GameOver), display_score)
|
||||
.add_system(gameover_keyboard.on_update(GameState::GameOver))
|
||||
.add_system(gameover_keyboard.in_set(OnUpdate(GameState::GameOver)))
|
||||
.add_system_to_schedule(OnExit(GameState::GameOver), teardown)
|
||||
.add_system(bevy::window::close_on_esc)
|
||||
.run();
|
||||
|
|
|
@ -62,7 +62,7 @@ mod splash {
|
|||
// When entering the state, spawn everything needed for this screen
|
||||
.add_system_to_schedule(OnEnter(GameState::Splash), splash_setup)
|
||||
// While in this state, run the `countdown` system
|
||||
.add_system(countdown.on_update(GameState::Splash))
|
||||
.add_system(countdown.in_set(OnUpdate(GameState::Splash)))
|
||||
// When exiting the state, despawn everything that was spawned for this screen
|
||||
.add_system_to_schedule(
|
||||
OnExit(GameState::Splash),
|
||||
|
@ -134,7 +134,7 @@ mod game {
|
|||
impl Plugin for GamePlugin {
|
||||
fn build(&self, app: &mut App) {
|
||||
app.add_system_to_schedule(OnEnter(GameState::Game), game_setup)
|
||||
.add_system(game.on_update(GameState::Game))
|
||||
.add_system(game.in_set(OnUpdate(GameState::Game)))
|
||||
.add_system_to_schedule(OnExit(GameState::Game), despawn_screen::<OnGameScreen>);
|
||||
}
|
||||
}
|
||||
|
@ -283,7 +283,9 @@ mod menu {
|
|||
OnEnter(MenuState::SettingsDisplay),
|
||||
display_settings_menu_setup,
|
||||
)
|
||||
.add_system(setting_button::<DisplayQuality>.on_update(MenuState::SettingsDisplay))
|
||||
.add_system(
|
||||
setting_button::<DisplayQuality>.in_set(OnUpdate(MenuState::SettingsDisplay)),
|
||||
)
|
||||
.add_system_to_schedule(
|
||||
OnExit(MenuState::SettingsDisplay),
|
||||
despawn_screen::<OnDisplaySettingsMenuScreen>,
|
||||
|
@ -293,13 +295,13 @@ mod menu {
|
|||
OnEnter(MenuState::SettingsSound),
|
||||
sound_settings_menu_setup,
|
||||
)
|
||||
.add_system(setting_button::<Volume>.on_update(MenuState::SettingsSound))
|
||||
.add_system(setting_button::<Volume>.in_set(OnUpdate(MenuState::SettingsSound)))
|
||||
.add_system_to_schedule(
|
||||
OnExit(MenuState::SettingsSound),
|
||||
despawn_screen::<OnSoundSettingsMenuScreen>,
|
||||
)
|
||||
// Common systems to all screens that handles buttons behaviour
|
||||
.add_systems((menu_action, button_system).on_update(GameState::Menu));
|
||||
.add_systems((menu_action, button_system).in_set(OnUpdate(GameState::Menu)));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue