1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210
//! This crate is about everything concerning the highest-level, application layer of a Bevy app.
#![warn(missing_docs)]
mod app;
mod config;
mod plugin;
mod plugin_group;
mod schedule_runner;
#[cfg(feature = "bevy_ci_testing")]
mod ci_testing;
pub use app::*;
pub use bevy_derive::DynamicPlugin;
pub use config::*;
pub use plugin::*;
pub use plugin_group::*;
pub use schedule_runner::*;
#[allow(missing_docs)]
pub mod prelude {
#[cfg(feature = "bevy_reflect")]
#[doc(hidden)]
pub use crate::AppTypeRegistry;
#[doc(hidden)]
pub use crate::{
app::App,
config::{IntoSystemAppConfig, IntoSystemAppConfigs},
CoreSchedule, CoreSet, DynamicPlugin, Plugin, PluginGroup, StartupSet,
};
}
use bevy_ecs::{
schedule::{
apply_system_buffers, IntoSystemConfig, IntoSystemSetConfig, IntoSystemSetConfigs,
Schedule, ScheduleLabel, SystemSet,
},
system::Local,
world::World,
};
/// The names of the default [`App`] schedules.
///
/// The corresponding [`Schedule`](bevy_ecs::schedule::Schedule) objects are added by [`App::add_default_schedules`].
#[derive(ScheduleLabel, Clone, Debug, PartialEq, Eq, Hash)]
pub enum CoreSchedule {
/// The schedule that runs once when the app starts.
Startup,
/// The schedule that contains the app logic that is evaluated each tick of [`App::update()`].
Main,
/// The schedule that controls which schedules run.
///
/// This is typically created using the [`CoreSchedule::outer_schedule`] method,
/// and does not need to manipulated during ordinary use.
Outer,
/// The schedule that contains systems which only run after a fixed period of time has elapsed.
///
/// The exclusive `run_fixed_update_schedule` system runs this schedule during the [`CoreSet::FixedUpdate`] system set.
FixedUpdate,
}
impl CoreSchedule {
/// An exclusive system that controls which schedule should be running.
///
/// [`CoreSchedule::Main`] is always run.
///
/// If this is the first time this system has been run, [`CoreSchedule::Startup`] will run before [`CoreSchedule::Main`].
pub fn outer_loop(world: &mut World, mut run_at_least_once: Local<bool>) {
if !*run_at_least_once {
world.run_schedule(CoreSchedule::Startup);
*run_at_least_once = true;
}
world.run_schedule(CoreSchedule::Main);
}
/// Initializes a single threaded schedule for [`CoreSchedule::Outer`] that contains the [`outer_loop`](CoreSchedule::outer_loop) system.
pub fn outer_schedule() -> Schedule {
let mut schedule = Schedule::new();
schedule.set_executor_kind(bevy_ecs::schedule::ExecutorKind::SingleThreaded);
schedule.add_system(Self::outer_loop);
schedule
}
}
/// The names of the default [`App`] system sets.
///
/// These are ordered in the same order they are listed.
///
/// The corresponding [`SystemSets`](bevy_ecs::schedule::SystemSet) are added by [`App::add_default_schedules`].
///
/// The `*Flush` sets are assigned to the copy of [`apply_system_buffers`]
/// that runs immediately after the matching system set.
/// These can be useful for ordering, but you almost never want to add your systems to these sets.
#[derive(Debug, Hash, PartialEq, Eq, Clone, SystemSet)]
#[system_set(base)]
pub enum CoreSet {
/// Runs before all other members of this set.
First,
/// The copy of [`apply_system_buffers`] that runs immediately after `First`.
FirstFlush,
/// Runs before [`CoreSet::Update`].
PreUpdate,
/// The copy of [`apply_system_buffers`] that runs immediately after `PreUpdate`.
PreUpdateFlush,
/// Applies [`State`](bevy_ecs::schedule::State) transitions
StateTransitions,
/// Runs systems that should only occur after a fixed period of time.
///
/// The `run_fixed_update_schedule` system runs the [`CoreSchedule::FixedUpdate`] system in this system set.
FixedUpdate,
/// Responsible for doing most app logic. Systems should be registered here by default.
Update,
/// The copy of [`apply_system_buffers`] that runs immediately after `Update`.
UpdateFlush,
/// Runs after [`CoreSet::Update`].
PostUpdate,
/// The copy of [`apply_system_buffers`] that runs immediately after `PostUpdate`.
PostUpdateFlush,
/// Runs after all other members of this set.
Last,
/// The copy of [`apply_system_buffers`] that runs immediately after `Last`.
LastFlush,
}
impl CoreSet {
/// Sets up the base structure of [`CoreSchedule::Main`].
///
/// The sets defined in this enum are configured to run in order,
/// and a copy of [`apply_system_buffers`] is inserted into each `*Flush` set.
pub fn base_schedule() -> Schedule {
use CoreSet::*;
let mut schedule = Schedule::new();
// Create "stage-like" structure using buffer flushes + ordering
schedule
.set_default_base_set(Update)
.add_system(apply_system_buffers.in_base_set(FirstFlush))
.add_system(apply_system_buffers.in_base_set(PreUpdateFlush))
.add_system(apply_system_buffers.in_base_set(UpdateFlush))
.add_system(apply_system_buffers.in_base_set(PostUpdateFlush))
.add_system(apply_system_buffers.in_base_set(LastFlush))
.configure_sets(
(
First,
FirstFlush,
PreUpdate,
PreUpdateFlush,
StateTransitions,
FixedUpdate,
Update,
UpdateFlush,
PostUpdate,
PostUpdateFlush,
Last,
LastFlush,
)
.chain(),
);
schedule
}
}
/// The names of the default [`App`] startup sets, which live in [`CoreSchedule::Startup`].
///
/// The corresponding [`SystemSets`](bevy_ecs::schedule::SystemSet) are added by [`App::add_default_schedules`].
///
/// The `*Flush` sets are assigned to the copy of [`apply_system_buffers`]
/// that runs immediately after the matching system set.
/// These can be useful for ordering, but you almost never want to add your systems to these sets.
#[derive(Debug, Hash, PartialEq, Eq, Clone, SystemSet)]
#[system_set(base)]
pub enum StartupSet {
/// Runs once before [`StartupSet::Startup`].
PreStartup,
/// The copy of [`apply_system_buffers`] that runs immediately after `PreStartup`.
PreStartupFlush,
/// Runs once when an [`App`] starts up.
Startup,
/// The copy of [`apply_system_buffers`] that runs immediately after `Startup`.
StartupFlush,
/// Runs once after [`StartupSet::Startup`].
PostStartup,
/// The copy of [`apply_system_buffers`] that runs immediately after `PostStartup`.
PostStartupFlush,
}
impl StartupSet {
/// Sets up the base structure of [`CoreSchedule::Startup`].
///
/// The sets defined in this enum are configured to run in order,
/// and a copy of [`apply_system_buffers`] is inserted into each `*Flush` set.
pub fn base_schedule() -> Schedule {
use StartupSet::*;
let mut schedule = Schedule::new();
schedule.set_default_base_set(Startup);
// Create "stage-like" structure using buffer flushes + ordering
schedule.add_system(apply_system_buffers.in_base_set(PreStartupFlush));
schedule.add_system(apply_system_buffers.in_base_set(StartupFlush));
schedule.add_system(apply_system_buffers.in_base_set(PostStartupFlush));
schedule.configure_set(PreStartup.before(PreStartupFlush));
schedule.configure_set(Startup.after(PreStartupFlush).before(StartupFlush));
schedule.configure_set(PostStartup.after(StartupFlush).before(PostStartupFlush));
schedule
}
}