Skip to content

Commit

Permalink
Initialize empty schedules when calling .in_schedule if they do not…
Browse files Browse the repository at this point in the history
… already exist (#7911)
  • Loading branch information
SET001 authored Mar 9, 2023
1 parent 2e7b915 commit 3ec764e
Show file tree
Hide file tree
Showing 2 changed files with 73 additions and 7 deletions.
75 changes: 69 additions & 6 deletions crates/bevy_app/src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -313,7 +313,7 @@ impl App {
}

/// Adds [`State<S>`] and [`NextState<S>`] resources, [`OnEnter`] and [`OnExit`] schedules
/// for each state variant, an instance of [`apply_state_transition::<S>`] in
/// for each state variant (if they don't already exist), an instance of [`apply_state_transition::<S>`] in
/// [`CoreSet::StateTransitions`] so that transitions happen before [`CoreSet::Update`] and
/// a instance of [`run_enter_schedule::<S>`] in [`CoreSet::StateTransitions`] with a
/// [`run_once`](`run_once_condition`) condition to run the on enter schedule of the
Expand Down Expand Up @@ -355,11 +355,14 @@ impl App {
.run_if(in_state(variant)),
);
}

// These are different for loops to avoid conflicting access to self
for variant in S::variants() {
self.add_schedule(OnEnter(variant.clone()), Schedule::new());
self.add_schedule(OnExit(variant), Schedule::new());
if self.get_schedule(OnEnter(variant.clone())).is_none() {
self.add_schedule(OnEnter(variant.clone()), Schedule::new());
}
if self.get_schedule(OnExit(variant.clone())).is_none() {
self.add_schedule(OnExit(variant), Schedule::new());
}
}

self
Expand Down Expand Up @@ -390,7 +393,9 @@ impl App {
if let Some(schedule) = schedules.get_mut(&*schedule_label) {
schedule.add_system(system);
} else {
panic!("Schedule {schedule_label:?} does not exist.")
let mut schedule = Schedule::new();
schedule.add_system(system);
schedules.insert(schedule_label, schedule);
}
} else if let Some(default_schedule) = schedules.get_mut(&*self.default_schedule_label) {
default_schedule.add_system(system);
Expand Down Expand Up @@ -1014,7 +1019,12 @@ pub struct AppExit;

#[cfg(test)]
mod tests {
use crate::{App, Plugin};
use bevy_ecs::{
schedule::{OnEnter, States},
system::Commands,
};

use crate::{App, IntoSystemAppConfig, IntoSystemAppConfigs, Plugin};

struct PluginA;
impl Plugin for PluginA {
Expand Down Expand Up @@ -1068,4 +1078,57 @@ mod tests {
}
App::new().add_plugin(PluginRun);
}

#[derive(States, PartialEq, Eq, Debug, Default, Hash, Clone)]
enum AppState {
#[default]
MainMenu,
}
fn bar(mut commands: Commands) {
commands.spawn_empty();
}

fn foo(mut commands: Commands) {
commands.spawn_empty();
}

#[test]
fn add_system_should_create_schedule_if_it_does_not_exist() {
let mut app = App::new();
app.add_system(foo.in_schedule(OnEnter(AppState::MainMenu)))
.add_state::<AppState>();

app.world.run_schedule(OnEnter(AppState::MainMenu));
assert_eq!(app.world.entities().len(), 1);
}

#[test]
fn add_system_should_create_schedule_if_it_does_not_exist2() {
let mut app = App::new();
app.add_state::<AppState>()
.add_system(foo.in_schedule(OnEnter(AppState::MainMenu)));

app.world.run_schedule(OnEnter(AppState::MainMenu));
assert_eq!(app.world.entities().len(), 1);
}

#[test]
fn add_systems_should_create_schedule_if_it_does_not_exist() {
let mut app = App::new();
app.add_state::<AppState>()
.add_systems((foo, bar).in_schedule(OnEnter(AppState::MainMenu)));

app.world.run_schedule(OnEnter(AppState::MainMenu));
assert_eq!(app.world.entities().len(), 2);
}

#[test]
fn add_systems_should_create_schedule_if_it_does_not_exist2() {
let mut app = App::new();
app.add_systems((foo, bar).in_schedule(OnEnter(AppState::MainMenu)))
.add_state::<AppState>();

app.world.run_schedule(OnEnter(AppState::MainMenu));
assert_eq!(app.world.entities().len(), 2);
}
}
5 changes: 4 additions & 1 deletion crates/bevy_app/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,10 @@ pub trait IntoSystemAppConfigs<Marker>: Sized {

/// Adds the systems to the provided `schedule`.
///
/// If a schedule is not specified, they will be added to the [`App`]'s default schedule.
/// If a schedule with specified label does not exist, it will be created.
///
/// If a schedule with the specified label does not exist, an empty one will be created.
///
///
/// [`App`]: crate::App
///
Expand Down

0 comments on commit 3ec764e

Please sign in to comment.