Skip to content

Commit

Permalink
Support system.in_schedule() and system.on_startup() (#7790)
Browse files Browse the repository at this point in the history
# Objective

Support the following syntax for adding systems:

```rust
App::new()
    .add_system(setup.on_startup())
    .add_systems((
        show_menu.in_schedule(OnEnter(GameState::Paused)),
        menu_ssytem.in_set(OnUpdate(GameState::Paused)),
        hide_menu.in_schedule(OnExit(GameState::Paused)),
    ))
```

## Solution

Add the traits `IntoSystemAppConfig{s}`, which provide the extension methods necessary for configuring which schedule a system belongs to. These extension methods return `IntoSystemAppConfig{s}`, which `App::add_system{s}` uses to choose which schedule to add systems to.

---

## Changelog

+ Added the extension methods `in_schedule(label)` and  `on_startup()` for configuring the schedule a system belongs to.

## Future Work

* Replace all uses of `add_startup_system` in the engine.
* Deprecate this method
  • Loading branch information
joseph-gio committed Feb 24, 2023
1 parent 40e90b5 commit b8263b5
Show file tree
Hide file tree
Showing 32 changed files with 444 additions and 189 deletions.
81 changes: 36 additions & 45 deletions crates/bevy_app/src/app.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
use crate::{CoreSchedule, CoreSet, Plugin, PluginGroup, StartupSet};
use crate::{
CoreSchedule, CoreSet, IntoSystemAppConfig, IntoSystemAppConfigs, Plugin, PluginGroup,
StartupSet, SystemAppConfig,
};
pub use bevy_derive::AppLabel;
use bevy_ecs::{
prelude::*,
Expand Down Expand Up @@ -378,10 +381,18 @@ impl App {
/// #
/// app.add_system(my_system);
/// ```
pub fn add_system<M>(&mut self, system: impl IntoSystemConfig<M>) -> &mut Self {
pub fn add_system<M>(&mut self, system: impl IntoSystemAppConfig<M>) -> &mut Self {
let mut schedules = self.world.resource_mut::<Schedules>();

if let Some(default_schedule) = schedules.get_mut(&*self.default_schedule_label) {
let SystemAppConfig { system, schedule } = system.into_app_config();

if let Some(schedule_label) = schedule {
if let Some(schedule) = schedules.get_mut(&*schedule_label) {
schedule.add_system(system);
} else {
panic!("Schedule {schedule_label:?} does not exist.")
}
} else if let Some(default_schedule) = schedules.get_mut(&*self.default_schedule_label) {
default_schedule.add_system(system);
} else {
let schedule_label = &self.default_schedule_label;
Expand All @@ -406,48 +417,28 @@ impl App {
/// #
/// app.add_systems((system_a, system_b, system_c));
/// ```
pub fn add_systems<M>(&mut self, systems: impl IntoSystemConfigs<M>) -> &mut Self {
let mut schedules = self.world.resource_mut::<Schedules>();

if let Some(default_schedule) = schedules.get_mut(&*self.default_schedule_label) {
default_schedule.add_systems(systems);
} else {
let schedule_label = &self.default_schedule_label;
panic!("Default schedule {schedule_label:?} does not exist.")
}

self
}

/// Adds a system to the provided [`Schedule`].
pub fn add_system_to_schedule<M>(
&mut self,
schedule_label: impl ScheduleLabel,
system: impl IntoSystemConfig<M>,
) -> &mut Self {
let mut schedules = self.world.resource_mut::<Schedules>();

if let Some(schedule) = schedules.get_mut(&schedule_label) {
schedule.add_system(system);
} else {
panic!("Provided schedule {schedule_label:?} does not exist.")
}

self
}

/// Adds a collection of system to the provided [`Schedule`].
pub fn add_systems_to_schedule<M>(
&mut self,
schedule_label: impl ScheduleLabel,
systems: impl IntoSystemConfigs<M>,
) -> &mut Self {
pub fn add_systems<M>(&mut self, systems: impl IntoSystemAppConfigs<M>) -> &mut Self {
let mut schedules = self.world.resource_mut::<Schedules>();

if let Some(schedule) = schedules.get_mut(&schedule_label) {
schedule.add_systems(systems);
} else {
panic!("Provided schedule {schedule_label:?} does not exist.")
match systems.into_app_configs().0 {
crate::InnerConfigs::Blanket { systems, schedule } => {
let schedule = if let Some(label) = schedule {
schedules
.get_mut(&*label)
.unwrap_or_else(|| panic!("Schedule '{label:?}' does not exist."))
} else {
let label = &*self.default_schedule_label;
schedules
.get_mut(label)
.unwrap_or_else(|| panic!("Default schedule '{label:?}' does not exist."))
};
schedule.add_systems(systems);
}
crate::InnerConfigs::Granular(systems) => {
for system in systems {
self.add_system(system);
}
}
}

self
Expand All @@ -472,7 +463,7 @@ impl App {
/// .add_startup_system(my_startup_system);
/// ```
pub fn add_startup_system<M>(&mut self, system: impl IntoSystemConfig<M>) -> &mut Self {
self.add_system_to_schedule(CoreSchedule::Startup, system)
self.add_system(system.in_schedule(CoreSchedule::Startup))
}

/// Adds a collection of systems to [`CoreSchedule::Startup`].
Expand All @@ -497,7 +488,7 @@ impl App {
/// );
/// ```
pub fn add_startup_systems<M>(&mut self, systems: impl IntoSystemConfigs<M>) -> &mut Self {
self.add_systems_to_schedule(CoreSchedule::Startup, systems)
self.add_systems(systems.into_configs().in_schedule(CoreSchedule::Startup))
}

/// Configures a system set in the default schedule, adding the set if it does not exist.
Expand Down
Loading

0 comments on commit b8263b5

Please sign in to comment.