Skip to content

Commit

Permalink
Move the CoreStage::Startup to a seperate StartupSchedule label (#2434)
Browse files Browse the repository at this point in the history
# Objective

- `CoreStage::Startup` is unique in the `CoreStage` enum, in that it represents a `Schedule` and not a `SystemStage`.
- This can lead to confusion about how `CoreStage::Startup` and the `StartupStage` enum are related.
- Beginners sometimes try `.add_system_to_stage(CoreStage::Startup, setup.system())` instead of `.add_startup_system(setup.system())`, which causes a Panic:
```
thread 'main' panicked at 'Stage 'Startup' does not exist or is not a SystemStage', crates\bevy_ecs\src\schedule\mod.rs:153:13
stack backtrace:
   0: std::panicking::begin_panic_handler
             at /rustc/53cb7b09b00cbea8754ffb78e7e3cb521cb8af4b\/library\std\src\panicking.rs:493
   1: std::panicking::begin_panic_fmt
             at /rustc/53cb7b09b00cbea8754ffb78e7e3cb521cb8af4b\/library\std\src\panicking.rs:435
   2: bevy_ecs::schedule::{{impl}}::add_system_to_stage::stage_not_found
             at .\crates\bevy_ecs\src\schedule\mod.rs:153
   3: bevy_ecs::schedule::{{impl}}::add_system_to_stage::{{closure}}<tuple<bevy_ecs::system::function_system::IsFunctionSystem, tuple<bevy_ecs::system::commands::Commands, bevy_ecs::change_detection::ResMut<bevy_asset::assets::Assets<bevy_render::mesh::mesh::Me
             at .\crates\bevy_ecs\src\schedule\mod.rs:161
   4: core::option::Option<mut bevy_ecs::schedule::stage::SystemStage*>::unwrap_or_else<mut bevy_ecs::schedule::stage::SystemStage*,closure-0>
             at C:\Users\scher\.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\core\src\option.rs:427
   5: bevy_ecs::schedule::Schedule::add_system_to_stage<tuple<bevy_ecs::system::function_system::IsFunctionSystem, tuple<bevy_ecs::system::commands::Commands, bevy_ecs::change_detection::ResMut<bevy_asset::assets::Assets<bevy_render::mesh::mesh::Mesh>>, bevy_ec
             at .\crates\bevy_ecs\src\schedule\mod.rs:159
   6: bevy_app::app_builder::AppBuilder::add_system_to_stage<tuple<bevy_ecs::system::function_system::IsFunctionSystem, tuple<bevy_ecs::system::commands::Commands, bevy_ecs::change_detection::ResMut<bevy_asset::assets::Assets<bevy_render::mesh::mesh::Mesh>>, be
             at .\crates\bevy_app\src\app_builder.rs:196
   7: 3d_scene::main
             at .\examples\3d\3d_scene.rs:4
   8: core::ops::function::FnOnce::call_once<fn(),tuple<>>
             at C:\Users\scher\.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\core\src\ops\function.rs:227
```

## Solution

- Replace the `CoreStage::Startup` Label with the new `StartupSchedule` unit type.


Resolves #2229
  • Loading branch information
MinerSebas committed Feb 8, 2022
1 parent f7478f4 commit b346242
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 13 deletions.
16 changes: 9 additions & 7 deletions crates/bevy_app/src/app.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
use crate::{CoreStage, Events, Plugin, PluginGroup, PluginGroupBuilder, StartupStage};
use crate::{
CoreStage, Events, Plugin, PluginGroup, PluginGroupBuilder, StartupSchedule, StartupStage,
};
pub use bevy_derive::AppLabel;
use bevy_ecs::{
prelude::{FromWorld, IntoExclusiveSystem},
Expand Down Expand Up @@ -207,7 +209,7 @@ impl App {
/// ```
pub fn add_startup_stage<S: Stage>(&mut self, label: impl StageLabel, stage: S) -> &mut Self {
self.schedule
.stage(CoreStage::Startup, |schedule: &mut Schedule| {
.stage(StartupSchedule, |schedule: &mut Schedule| {
schedule.add_stage(label, stage)
});
self
Expand Down Expand Up @@ -238,7 +240,7 @@ impl App {
stage: S,
) -> &mut Self {
self.schedule
.stage(CoreStage::Startup, |schedule: &mut Schedule| {
.stage(StartupSchedule, |schedule: &mut Schedule| {
schedule.add_stage_after(target, label, stage)
});
self
Expand Down Expand Up @@ -269,7 +271,7 @@ impl App {
stage: S,
) -> &mut Self {
self.schedule
.stage(CoreStage::Startup, |schedule: &mut Schedule| {
.stage(StartupSchedule, |schedule: &mut Schedule| {
schedule.add_stage_before(target, label, stage)
});
self
Expand Down Expand Up @@ -483,7 +485,7 @@ impl App {
system: impl IntoSystemDescriptor<Params>,
) -> &mut Self {
self.schedule
.stage(CoreStage::Startup, |schedule: &mut Schedule| {
.stage(StartupSchedule, |schedule: &mut Schedule| {
schedule.add_system_to_stage(stage_label, system)
});
self
Expand Down Expand Up @@ -519,7 +521,7 @@ impl App {
system_set: SystemSet,
) -> &mut Self {
self.schedule
.stage(CoreStage::Startup, |schedule: &mut Schedule| {
.stage(StartupSchedule, |schedule: &mut Schedule| {
schedule.add_system_set_to_stage(stage_label, system_set)
});
self
Expand Down Expand Up @@ -588,7 +590,7 @@ impl App {
pub fn add_default_stages(&mut self) -> &mut Self {
self.add_stage(CoreStage::First, SystemStage::parallel())
.add_stage(
CoreStage::Startup,
StartupSchedule,
Schedule::default()
.with_run_criteria(RunOnce::default())
.with_stage(StartupStage::PreStartup, SystemStage::parallel())
Expand Down
18 changes: 12 additions & 6 deletions crates/bevy_app/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@ pub use schedule_runner::*;
#[allow(missing_docs)]
pub mod prelude {
#[doc(hidden)]
pub use crate::{app::App, CoreStage, DynamicPlugin, Plugin, PluginGroup, StartupStage};
pub use crate::{
app::App, CoreStage, DynamicPlugin, Plugin, PluginGroup, StartupSchedule, StartupStage,
};
}

use bevy_ecs::schedule::StageLabel;
Expand All @@ -30,11 +32,6 @@ use bevy_ecs::schedule::StageLabel;
/// The relative stages are added by [`App::add_default_stages`].
#[derive(Debug, Hash, PartialEq, Eq, Clone, StageLabel)]
pub enum CoreStage {
/// Runs only once at the beginning of the app.
///
/// Consists of the sub-stages defined in [`StartupStage`]. Systems added here are
/// referred to as "startup systems".
Startup,
/// Name of app stage that runs before all other app stages
First,
/// Name of app stage responsible for performing setup before an update. Runs before UPDATE.
Expand All @@ -47,6 +44,15 @@ pub enum CoreStage {
/// Name of app stage that runs after all other app stages
Last,
}

/// The label for the Startup [`Schedule`](bevy_ecs::schedule::Schedule),
/// which runs once at the beginning of the app.
///
/// When targeting a [`Stage`](bevy_ecs::schedule::Stage) inside this Schedule,
/// you need to use [`StartupStage`] instead.
#[derive(Debug, Hash, PartialEq, Eq, Clone, StageLabel)]
pub struct StartupSchedule;

/// The names of the default App startup stages
#[derive(Debug, Hash, PartialEq, Eq, Clone, StageLabel)]
pub enum StartupStage {
Expand Down

0 comments on commit b346242

Please sign in to comment.