use crate::{1First, Main, MainSchedulePlugin, PlaceholderPlugin, Plugin, Plugins, PluginsState, SubApp,2SubApps,3};4use alloc::{5boxed::Box,6string::{String, ToString},7vec::Vec,8};9pub use bevy_derive::AppLabel;10use bevy_ecs::{11component::RequiredComponentsError,12error::{DefaultErrorHandler, ErrorHandler},13intern::Interned,14message::{message_update_system, MessageCursor},15observer::IntoObserver,16prelude::*,17schedule::{18InternedSystemSet, ScheduleBuildSettings, ScheduleCleanupPolicy, ScheduleError,19ScheduleLabel,20},21system::{ScheduleSystem, SystemId, SystemInput},22};23use bevy_platform::collections::HashMap;24use core::{fmt::Debug, num::NonZero, panic::AssertUnwindSafe};25use log::debug;2627#[cfg(feature = "trace")]28use tracing::info_span;2930#[cfg(feature = "std")]31use std::{32panic::{catch_unwind, resume_unwind},33process::{ExitCode, Termination},34};3536bevy_ecs::define_label!(37/// A strongly-typed class of labels used to identify an [`App`].38#[diagnostic::on_unimplemented(39note = "consider annotating `{Self}` with `#[derive(AppLabel)]`"40)]41AppLabel,42APP_LABEL_INTERNER43);4445pub use bevy_ecs::label::DynEq;4647/// A shorthand for `Interned<dyn AppLabel>`.48pub type InternedAppLabel = Interned<dyn AppLabel>;4950#[derive(Debug, thiserror::Error)]51pub(crate) enum AppError {52#[error("duplicate plugin {plugin_name:?}")]53DuplicatePlugin { plugin_name: String },54}5556/// [`App`] is the primary API for writing user applications. It automates the setup of a57/// [standard lifecycle](Main) and provides interface glue for [plugins](`Plugin`).58///59/// A single [`App`] can contain multiple [`SubApp`] instances, but [`App`] methods only affect60/// the "main" one. To access a particular [`SubApp`], use [`get_sub_app`](App::get_sub_app)61/// or [`get_sub_app_mut`](App::get_sub_app_mut).62///63///64/// # Examples65///66/// Here is a simple "Hello World" Bevy app:67///68/// ```69/// # use bevy_app::prelude::*;70/// # use bevy_ecs::prelude::*;71/// #72/// fn main() {73/// App::new()74/// .add_systems(Update, hello_world_system)75/// .run();76/// }77///78/// fn hello_world_system() {79/// println!("hello world");80/// }81/// ```82#[must_use]83pub struct App {84pub(crate) sub_apps: SubApps,85/// The function that will manage the app's lifecycle.86///87/// Bevy provides the [`WinitPlugin`] and [`ScheduleRunnerPlugin`] for windowed and headless88/// applications, respectively.89///90/// [`WinitPlugin`]: https://docs.rs/bevy/latest/bevy/winit/struct.WinitPlugin.html91/// [`ScheduleRunnerPlugin`]: https://docs.rs/bevy/latest/bevy/app/struct.ScheduleRunnerPlugin.html92pub(crate) runner: RunnerFn,93default_error_handler: Option<ErrorHandler>,94}9596impl Debug for App {97fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {98write!(f, "App {{ sub_apps: ")?;99f.debug_map()100.entries(self.sub_apps.sub_apps.iter())101.finish()?;102write!(f, "}}")103}104}105106impl Default for App {107fn default() -> Self {108let mut app = App::empty();109app.sub_apps.main.update_schedule = Some(Main.intern());110111#[cfg(feature = "bevy_reflect")]112{113#[cfg(not(feature = "reflect_auto_register"))]114app.init_resource::<AppTypeRegistry>();115116#[cfg(feature = "reflect_auto_register")]117app.insert_resource(AppTypeRegistry::new_with_derived_types());118}119120#[cfg(feature = "reflect_functions")]121app.init_resource::<AppFunctionRegistry>();122123app.add_plugins(MainSchedulePlugin);124app.add_systems(125First,126message_update_system127.in_set(bevy_ecs::message::MessageUpdateSystems)128.run_if(bevy_ecs::message::message_update_condition),129);130app.add_message::<AppExit>();131132app133}134}135136impl App {137/// Creates a new [`App`] with some default structure to enable core engine features.138/// This is the preferred constructor for most use cases.139pub fn new() -> App {140App::default()141}142143/// Creates a new empty [`App`] with minimal default configuration.144///145/// Use this constructor if you want to customize scheduling, exit handling, cleanup, etc.146pub fn empty() -> App {147Self {148sub_apps: SubApps {149main: SubApp::new(),150sub_apps: HashMap::default(),151},152runner: Box::new(run_once),153default_error_handler: None,154}155}156157/// Runs the default schedules of all sub-apps (starting with the "main" app) once.158pub fn update(&mut self) {159if self.is_building_plugins() {160panic!("App::update() was called while a plugin was building.");161}162163self.sub_apps.update();164}165166/// Runs the [`App`] by calling its [runner](Self::set_runner).167///168/// This will (re)build the [`App`] first. For general usage, see the example on the item169/// level documentation.170///171/// # Caveats172///173/// Calls to [`App::run()`] will never return on iOS and Web.174///175/// Headless apps can generally expect this method to return control to the caller when176/// it completes, but that is not the case for windowed apps. Windowed apps are typically177/// driven by an event loop and some platforms expect the program to terminate when the178/// event loop ends.179///180/// By default, *Bevy* uses the `winit` crate for window creation.181///182/// # Panics183///184/// Panics if not all plugins have been built.185pub fn run(&mut self) -> AppExit {186#[cfg(feature = "trace")]187let _bevy_app_run_span = info_span!("bevy_app").entered();188if self.is_building_plugins() {189panic!("App::run() was called while a plugin was building.");190}191192let runner = core::mem::replace(&mut self.runner, Box::new(run_once));193let app = core::mem::replace(self, App::empty());194(runner)(app)195}196197/// Sets the function that will be called when the app is run.198///199/// The runner function `f` is called only once by [`App::run`]. If the200/// presence of a main loop in the app is desired, it is the responsibility of the runner201/// function to provide it.202///203/// The runner function is usually not set manually, but by Bevy integrated plugins204/// (e.g. `WinitPlugin`).205///206/// # Examples207///208/// ```209/// # use bevy_app::prelude::*;210/// #211/// fn my_runner(mut app: App) -> AppExit {212/// loop {213/// println!("In main loop");214/// app.update();215/// if let Some(exit) = app.should_exit() {216/// return exit;217/// }218/// }219/// }220///221/// App::new()222/// .set_runner(my_runner);223/// ```224pub fn set_runner(&mut self, f: impl FnOnce(App) -> AppExit + 'static) -> &mut Self {225self.runner = Box::new(f);226self227}228229/// Returns the state of all plugins. This is usually called by the event loop, but can be230/// useful for situations where you want to use [`App::update`].231// TODO: &mut self -> &self232#[inline]233pub fn plugins_state(&mut self) -> PluginsState {234let mut overall_plugins_state = match self.main_mut().plugins_state {235PluginsState::Adding => {236let mut state = PluginsState::Ready;237let plugins = core::mem::take(&mut self.main_mut().plugin_registry);238for plugin in &plugins {239// plugins installed to main need to see all sub-apps240if !plugin.ready(self) {241state = PluginsState::Adding;242break;243}244}245self.main_mut().plugin_registry = plugins;246state247}248state => state,249};250251// overall state is the earliest state of any sub-app252self.sub_apps.iter_mut().skip(1).for_each(|s| {253overall_plugins_state = overall_plugins_state.min(s.plugins_state());254});255256overall_plugins_state257}258259/// Runs [`Plugin::finish`] for each plugin. This is usually called by the event loop once all260/// plugins are ready, but can be useful for situations where you want to use [`App::update`].261pub fn finish(&mut self) {262#[cfg(feature = "trace")]263let _finish_span = info_span!("plugin finish").entered();264// plugins installed to main should see all sub-apps265// do hokey pokey with a boxed zst plugin (doesn't allocate)266let mut hokeypokey: Box<dyn Plugin> = Box::new(HokeyPokey);267for i in 0..self.main().plugin_registry.len() {268core::mem::swap(&mut self.main_mut().plugin_registry[i], &mut hokeypokey);269#[cfg(feature = "trace")]270let _plugin_finish_span =271info_span!("plugin finish", plugin = hokeypokey.name()).entered();272hokeypokey.finish(self);273core::mem::swap(&mut self.main_mut().plugin_registry[i], &mut hokeypokey);274}275self.main_mut().plugins_state = PluginsState::Finished;276self.sub_apps.iter_mut().skip(1).for_each(SubApp::finish);277}278279/// Runs [`Plugin::cleanup`] for each plugin. This is usually called by the event loop after280/// [`App::finish`], but can be useful for situations where you want to use [`App::update`].281pub fn cleanup(&mut self) {282#[cfg(feature = "trace")]283let _cleanup_span = info_span!("plugin cleanup").entered();284// plugins installed to main should see all sub-apps285// do hokey pokey with a boxed zst plugin (doesn't allocate)286let mut hokeypokey: Box<dyn Plugin> = Box::new(HokeyPokey);287for i in 0..self.main().plugin_registry.len() {288core::mem::swap(&mut self.main_mut().plugin_registry[i], &mut hokeypokey);289#[cfg(feature = "trace")]290let _plugin_cleanup_span =291info_span!("plugin cleanup", plugin = hokeypokey.name()).entered();292hokeypokey.cleanup(self);293core::mem::swap(&mut self.main_mut().plugin_registry[i], &mut hokeypokey);294}295self.main_mut().plugins_state = PluginsState::Cleaned;296self.sub_apps.iter_mut().skip(1).for_each(SubApp::cleanup);297}298299/// Returns `true` if any of the sub-apps are building plugins.300pub(crate) fn is_building_plugins(&self) -> bool {301self.sub_apps.iter().any(SubApp::is_building_plugins)302}303304/// Adds one or more systems to the given schedule in this app's [`Schedules`].305///306/// # Examples307///308/// ```309/// # use bevy_app::prelude::*;310/// # use bevy_ecs::prelude::*;311/// #312/// # let mut app = App::new();313/// # fn system_a() {}314/// # fn system_b() {}315/// # fn system_c() {}316/// # fn should_run() -> bool { true }317/// #318/// app.add_systems(Update, (system_a, system_b, system_c));319/// app.add_systems(Update, (system_a, system_b).run_if(should_run));320/// ```321pub fn add_systems<M>(322&mut self,323schedule: impl ScheduleLabel,324systems: impl IntoScheduleConfigs<ScheduleSystem, M>,325) -> &mut Self {326self.main_mut().add_systems(schedule, systems);327self328}329330/// Removes all systems in a [`SystemSet`]. This will cause the schedule to be rebuilt when331/// the schedule is run again and can be slow. A [`ScheduleError`] is returned if the schedule needs to be332/// [`Schedule::initialize`]'d or the `set` is not found.333///334/// Note that this can remove all systems of a type if you pass335/// the system to this function as systems implicitly create a set based336/// on the system type.337///338/// ## Example339/// ```340/// # use bevy_app::prelude::*;341/// # use bevy_ecs::schedule::ScheduleCleanupPolicy;342/// #343/// # let mut app = App::new();344/// # fn system_a() {}345/// # fn system_b() {}346/// #347/// // add the system348/// app.add_systems(Update, system_a);349///350/// // remove the system351/// app.remove_systems_in_set(Update, system_a, ScheduleCleanupPolicy::RemoveSystemsOnly);352/// ```353pub fn remove_systems_in_set<M>(354&mut self,355schedule: impl ScheduleLabel,356set: impl IntoSystemSet<M>,357policy: ScheduleCleanupPolicy,358) -> Result<usize, ScheduleError> {359self.main_mut().remove_systems_in_set(schedule, set, policy)360}361362/// Registers a system and returns a [`SystemId`] so it can later be called by [`World::run_system`].363///364/// It's possible to register the same systems more than once, they'll be stored separately.365///366/// This is different from adding systems to a [`Schedule`] with [`App::add_systems`],367/// because the [`SystemId`] that is returned can be used anywhere in the [`World`] to run the associated system.368/// This allows for running systems in a push-based fashion.369/// Using a [`Schedule`] is still preferred for most cases370/// due to its better performance and ability to run non-conflicting systems simultaneously.371pub fn register_system<I, O, M>(372&mut self,373system: impl IntoSystem<I, O, M> + 'static,374) -> SystemId<I, O>375where376I: SystemInput + 'static,377O: 'static,378{379self.main_mut().register_system(system)380}381382/// Configures a collection of system sets in the provided schedule, adding any sets that do not exist.383#[track_caller]384pub fn configure_sets<M>(385&mut self,386schedule: impl ScheduleLabel,387sets: impl IntoScheduleConfigs<InternedSystemSet, M>,388) -> &mut Self {389self.main_mut().configure_sets(schedule, sets);390self391}392393/// Initializes [`Message`] handling for `T` by inserting a message queue resource ([`Messages::<T>`])394/// and scheduling an [`message_update_system`] in [`First`].395///396/// See [`Messages`] for information on how to define messages.397///398/// # Examples399///400/// ```401/// # use bevy_app::prelude::*;402/// # use bevy_ecs::prelude::*;403/// #404/// # #[derive(Message)]405/// # struct MyMessage;406/// # let mut app = App::new();407/// #408/// app.add_message::<MyMessage>();409/// ```410pub fn add_message<M: Message>(&mut self) -> &mut Self {411self.main_mut().add_message::<M>();412self413}414415/// Inserts the [`Resource`] into the app, overwriting any existing resource of the same type.416///417/// There is also an [`init_resource`](Self::init_resource) for resources that have418/// [`Default`] or [`FromWorld`] implementations.419///420/// # Examples421///422/// ```423/// # use bevy_app::prelude::*;424/// # use bevy_ecs::prelude::*;425/// #426/// #[derive(Resource)]427/// struct MyCounter {428/// counter: usize,429/// }430///431/// App::new()432/// .insert_resource(MyCounter { counter: 0 });433/// ```434pub fn insert_resource<R: Resource>(&mut self, resource: R) -> &mut Self {435self.main_mut().insert_resource(resource);436self437}438439/// Inserts the [`Resource`], initialized with its default value, into the app,440/// if there is no existing instance of `R`.441///442/// `R` must implement [`FromWorld`].443/// If `R` implements [`Default`], [`FromWorld`] will be automatically implemented and444/// initialize the [`Resource`] with [`Default::default`].445///446/// # Examples447///448/// ```449/// # use bevy_app::prelude::*;450/// # use bevy_ecs::prelude::*;451/// #452/// #[derive(Resource)]453/// struct MyCounter {454/// counter: usize,455/// }456///457/// impl Default for MyCounter {458/// fn default() -> MyCounter {459/// MyCounter {460/// counter: 100461/// }462/// }463/// }464///465/// App::new()466/// .init_resource::<MyCounter>();467/// ```468pub fn init_resource<R: Resource + FromWorld>(&mut self) -> &mut Self {469self.main_mut().init_resource::<R>();470self471}472473/// Inserts the [`!Send`](Send) resource into the app, overwriting any existing data474/// of the same type.475#[deprecated(since = "0.19.0", note = "use App::insert_non_send")]476pub fn insert_non_send_resource<R: 'static>(&mut self, resource: R) -> &mut Self {477self.insert_non_send(resource)478}479480/// Inserts the [`!Send`](Send) data into the app, overwriting any existing data481/// of the same type.482///483/// There is also an [`init_non_send`](Self::init_non_send) for [`!Send`](Send) data484/// that implement [`Default`]485///486/// # Examples487///488/// ```489/// # use bevy_app::prelude::*;490/// # use bevy_ecs::prelude::*;491/// #492/// struct MyCounter {493/// counter: usize,494/// }495///496/// App::new()497/// .insert_non_send(MyCounter { counter: 0 });498/// ```499pub fn insert_non_send<R: 'static>(&mut self, resource: R) -> &mut Self {500self.world_mut().insert_non_send(resource);501self502}503504/// Inserts the [`!Send`](Send) resource into the app if there is no existing instance of `R`.505#[deprecated(since = "0.19.0", note = "use App::init_non_send")]506pub fn init_non_send_resource<R: 'static + FromWorld>(&mut self) -> &mut Self {507self.init_non_send::<R>()508}509510/// Inserts the [`!Send`](Send) data into the app if there is no existing instance of `R`.511///512/// `R` must implement [`FromWorld`].513/// If `R` implements [`Default`], [`FromWorld`] will be automatically implemented and514/// initialize the [`Resource`] with [`Default::default`].515pub fn init_non_send<R: 'static + FromWorld>(&mut self) -> &mut Self {516self.world_mut().init_non_send::<R>();517self518}519520pub(crate) fn add_boxed_plugin(521&mut self,522plugin: Box<dyn Plugin>,523) -> Result<&mut Self, AppError> {524debug!("added plugin: {}", plugin.name());525if plugin.is_unique() && self.main_mut().plugin_names.contains(plugin.name()) {526Err(AppError::DuplicatePlugin {527plugin_name: plugin.name().to_string(),528})?;529}530531// Reserve position in the plugin registry. If the plugin adds more plugins,532// they'll all end up in insertion order.533let index = self.main().plugin_registry.len();534self.main_mut()535.plugin_registry536.push(Box::new(PlaceholderPlugin));537538self.main_mut().plugin_build_depth += 1;539540#[cfg(feature = "trace")]541let _plugin_build_span = info_span!("plugin build", plugin = plugin.name()).entered();542543let f = AssertUnwindSafe(|| plugin.build(self));544545#[cfg(feature = "std")]546let result = catch_unwind(f);547548#[cfg(not(feature = "std"))]549f();550551self.main_mut()552.plugin_names553.insert(plugin.name().to_string());554self.main_mut().plugin_build_depth -= 1;555556#[cfg(feature = "std")]557if let Err(payload) = result {558resume_unwind(payload);559}560561self.main_mut().plugin_registry[index] = plugin;562Ok(self)563}564565/// Returns `true` if the [`Plugin`] has already been added.566pub fn is_plugin_added<T>(&self) -> bool567where568T: Plugin,569{570self.main().is_plugin_added::<T>()571}572573/// Returns a vector of references to all plugins of type `T` that have been added.574///575/// This can be used to read the settings of any existing plugins.576/// This vector will be empty if no plugins of that type have been added.577/// If multiple copies of the same plugin are added to the [`App`], they will be listed in insertion order in this vector.578///579/// ```580/// # use bevy_app::prelude::*;581/// # #[derive(Default)]582/// # struct ImagePlugin {583/// # default_sampler: bool,584/// # }585/// # impl Plugin for ImagePlugin {586/// # fn build(&self, app: &mut App) {}587/// # }588/// # let mut app = App::new();589/// # app.add_plugins(ImagePlugin::default());590/// let default_sampler = app.get_added_plugins::<ImagePlugin>()[0].default_sampler;591/// ```592pub fn get_added_plugins<T>(&self) -> Vec<&T>593where594T: Plugin,595{596self.main().get_added_plugins::<T>()597}598599/// Installs a [`Plugin`] collection.600///601/// Bevy prioritizes modularity as a core principle. **All** engine features are implemented602/// as plugins, even the complex ones like rendering.603///604/// [`Plugin`]s can be grouped into a set by using a [`PluginGroup`].605///606/// There are built-in [`PluginGroup`]s that provide core engine functionality.607/// The [`PluginGroup`]s available by default are `DefaultPlugins` and `MinimalPlugins`.608///609/// To customize the plugins in the group (reorder, disable a plugin, add a new plugin610/// before / after another plugin), call [`build()`](super::PluginGroup::build) on the group,611/// which will convert it to a [`PluginGroupBuilder`](crate::PluginGroupBuilder).612///613/// You can also specify a group of [`Plugin`]s by using a tuple over [`Plugin`]s and614/// [`PluginGroup`]s. See [`Plugins`] for more details.615///616/// ## Examples617/// ```618/// # use bevy_app::{prelude::*, PluginGroupBuilder, NoopPluginGroup as MinimalPlugins};619/// #620/// # // Dummies created to avoid using `bevy_log`,621/// # // which pulls in too many dependencies and breaks rust-analyzer622/// # pub struct LogPlugin;623/// # impl Plugin for LogPlugin {624/// # fn build(&self, app: &mut App) {}625/// # }626/// App::new()627/// .add_plugins(MinimalPlugins);628/// App::new()629/// .add_plugins((MinimalPlugins, LogPlugin));630/// ```631///632/// # Panics633///634/// Panics if one of the plugins had already been added to the application.635///636/// [`PluginGroup`]:super::PluginGroup637#[track_caller]638pub fn add_plugins<M>(&mut self, plugins: impl Plugins<M>) -> &mut Self {639if matches!(640self.plugins_state(),641PluginsState::Cleaned | PluginsState::Finished642) {643panic!(644"Plugins cannot be added after App::cleanup() or App::finish() has been called."645);646}647plugins.add_to_app(self);648self649}650651/// Registers the type `T` in the [`AppTypeRegistry`] resource,652/// adding reflect data as specified in the [`Reflect`](bevy_reflect::Reflect) derive:653/// ```ignore (No serde "derive" feature)654/// #[derive(Component, Serialize, Deserialize, Reflect)]655/// #[reflect(Component, Serialize, Deserialize)] // will register ReflectComponent, ReflectSerialize, ReflectDeserialize656/// ```657///658/// See [`bevy_reflect::TypeRegistry::register`] for more information.659#[cfg(feature = "bevy_reflect")]660pub fn register_type<T: bevy_reflect::GetTypeRegistration>(&mut self) -> &mut Self {661self.main_mut().register_type::<T>();662self663}664665/// Associates type data `D` with type `T` in the [`AppTypeRegistry`] resource.666///667/// Most of the time [`register_type`](Self::register_type) can be used instead to register a668/// type you derived [`Reflect`](bevy_reflect::Reflect) for. However, in cases where you want to669/// add a piece of type data that was not included in the list of `#[reflect(...)]` type data in670/// the derive, or where the type is generic and cannot register e.g. `ReflectSerialize`671/// unconditionally without knowing the specific type parameters, this method can be used to672/// insert additional type data.673///674/// # Example675/// ```676/// use bevy_app::App;677/// use bevy_reflect::{ReflectSerialize, ReflectDeserialize};678///679/// App::new()680/// .register_type::<Option<String>>()681/// .register_type_data::<Option<String>, ReflectSerialize>()682/// .register_type_data::<Option<String>, ReflectDeserialize>();683/// ```684///685/// See [`bevy_reflect::TypeRegistry::register_type_data`].686#[cfg(feature = "bevy_reflect")]687pub fn register_type_data<688T: bevy_reflect::Reflect + bevy_reflect::TypePath,689D: bevy_reflect::TypeData + bevy_reflect::FromType<T>,690>(691&mut self,692) -> &mut Self {693self.main_mut().register_type_data::<T, D>();694self695}696697/// Registers the given function into the [`AppFunctionRegistry`] resource.698///699/// The given function will internally be stored as a [`DynamicFunction`]700/// and mapped according to its [name].701///702/// Because the function must have a name,703/// anonymous functions (e.g. `|a: i32, b: i32| { a + b }`) and closures must instead704/// be registered using [`register_function_with_name`] or converted to a [`DynamicFunction`]705/// and named using [`DynamicFunction::with_name`].706/// Failure to do so will result in a panic.707///708/// Only types that implement [`IntoFunction`] may be registered via this method.709///710/// See [`FunctionRegistry::register`] for more information.711///712/// # Panics713///714/// Panics if a function has already been registered with the given name715/// or if the function is missing a name (such as when it is an anonymous function).716///717/// # Examples718///719/// ```720/// use bevy_app::App;721///722/// fn add(a: i32, b: i32) -> i32 {723/// a + b724/// }725///726/// App::new().register_function(add);727/// ```728///729/// Functions cannot be registered more than once.730///731/// ```should_panic732/// use bevy_app::App;733///734/// fn add(a: i32, b: i32) -> i32 {735/// a + b736/// }737///738/// App::new()739/// .register_function(add)740/// // Panic! A function has already been registered with the name "my_function"741/// .register_function(add);742/// ```743///744/// Anonymous functions and closures should be registered using [`register_function_with_name`] or given a name using [`DynamicFunction::with_name`].745///746/// ```should_panic747/// use bevy_app::App;748///749/// // Panic! Anonymous functions cannot be registered using `register_function`750/// App::new().register_function(|a: i32, b: i32| a + b);751/// ```752///753/// [`register_function_with_name`]: Self::register_function_with_name754/// [`DynamicFunction`]: bevy_reflect::func::DynamicFunction755/// [name]: bevy_reflect::func::FunctionInfo::name756/// [`DynamicFunction::with_name`]: bevy_reflect::func::DynamicFunction::with_name757/// [`IntoFunction`]: bevy_reflect::func::IntoFunction758/// [`FunctionRegistry::register`]: bevy_reflect::func::FunctionRegistry::register759#[cfg(feature = "reflect_functions")]760pub fn register_function<F, Marker>(&mut self, function: F) -> &mut Self761where762F: bevy_reflect::func::IntoFunction<'static, Marker> + 'static,763{764self.main_mut().register_function(function);765self766}767768/// Registers the given function or closure into the [`AppFunctionRegistry`] resource using the given name.769///770/// To avoid conflicts, it's recommended to use a unique name for the function.771/// This can be achieved by "namespacing" the function with a unique identifier,772/// such as the name of your crate.773///774/// For example, to register a function, `add`, from a crate, `my_crate`,775/// you could use the name, `"my_crate::add"`.776///777/// Another approach could be to use the [type name] of the function,778/// however, it should be noted that anonymous functions do _not_ have unique type names.779///780/// For named functions (e.g. `fn add(a: i32, b: i32) -> i32 { a + b }`) where a custom name is not needed,781/// it's recommended to use [`register_function`] instead as the generated name is guaranteed to be unique.782///783/// Only types that implement [`IntoFunction`] may be registered via this method.784///785/// See [`FunctionRegistry::register_with_name`] for more information.786///787/// # Panics788///789/// Panics if a function has already been registered with the given name.790///791/// # Examples792///793/// ```794/// use bevy_app::App;795///796/// fn mul(a: i32, b: i32) -> i32 {797/// a * b798/// }799///800/// let div = |a: i32, b: i32| a / b;801///802/// App::new()803/// // Registering an anonymous function with a unique name804/// .register_function_with_name("my_crate::add", |a: i32, b: i32| {805/// a + b806/// })807/// // Registering an existing function with its type name808/// .register_function_with_name(std::any::type_name_of_val(&mul), mul)809/// // Registering an existing function with a custom name810/// .register_function_with_name("my_crate::mul", mul)811/// // Be careful not to register anonymous functions with their type name.812/// // This code works but registers the function with a non-unique name like `foo::bar::{{closure}}`813/// .register_function_with_name(std::any::type_name_of_val(&div), div);814/// ```815///816/// Names must be unique.817///818/// ```should_panic819/// use bevy_app::App;820///821/// fn one() {}822/// fn two() {}823///824/// App::new()825/// .register_function_with_name("my_function", one)826/// // Panic! A function has already been registered with the name "my_function"827/// .register_function_with_name("my_function", two);828/// ```829///830/// [type name]: std::any::type_name831/// [`register_function`]: Self::register_function832/// [`IntoFunction`]: bevy_reflect::func::IntoFunction833/// [`FunctionRegistry::register_with_name`]: bevy_reflect::func::FunctionRegistry::register_with_name834#[cfg(feature = "reflect_functions")]835pub fn register_function_with_name<F, Marker>(836&mut self,837name: impl Into<alloc::borrow::Cow<'static, str>>,838function: F,839) -> &mut Self840where841F: bevy_reflect::func::IntoFunction<'static, Marker> + 'static,842{843self.main_mut().register_function_with_name(name, function);844self845}846847/// Registers the given component `R` as a [required component] for `T`.848///849/// When `T` is added to an entity, `R` and its own required components will also be added850/// if `R` was not already provided. The [`Default`] `constructor` will be used for the creation of `R`.851/// If a custom constructor is desired, use [`App::register_required_components_with`] instead.852///853/// For the non-panicking version, see [`App::try_register_required_components`].854///855/// Note that requirements must currently be registered before `T` is inserted into the world856/// for the first time. Commonly, this is done in plugins. This limitation may be fixed in the future.857///858/// [required component]: Component#required-components859///860/// # Panics861///862/// Panics if `R` is already a directly required component for `T`, or if `T` has ever been added863/// on an entity before the registration.864///865/// Indirect requirements through other components are allowed. In those cases, any existing requirements866/// will only be overwritten if the new requirement is more specific.867///868/// # Example869///870/// ```871/// # use bevy_app::{App, NoopPluginGroup as MinimalPlugins, Startup};872/// # use bevy_ecs::prelude::*;873/// #[derive(Component)]874/// struct A;875///876/// #[derive(Component, Default, PartialEq, Eq, Debug)]877/// struct B(usize);878///879/// #[derive(Component, Default, PartialEq, Eq, Debug)]880/// struct C(u32);881///882/// # let mut app = App::new();883/// # app.add_plugins(MinimalPlugins).add_systems(Startup, setup);884/// // Register B as required by A and C as required by B.885/// app.register_required_components::<A, B>();886/// app.register_required_components::<B, C>();887///888/// fn setup(mut commands: Commands) {889/// // This will implicitly also insert B and C with their Default constructors.890/// commands.spawn(A);891/// }892///893/// fn validate(query: Option<Single<(&A, &B, &C)>>) {894/// let (a, b, c) = query.unwrap().into_inner();895/// assert_eq!(b, &B(0));896/// assert_eq!(c, &C(0));897/// }898/// # app.update();899/// ```900pub fn register_required_components<T: Component, R: Component + Default>(901&mut self,902) -> &mut Self {903self.world_mut().register_required_components::<T, R>();904self905}906907/// Registers the given component `R` as a [required component] for `T`.908///909/// When `T` is added to an entity, `R` and its own required components will also be added910/// if `R` was not already provided. The given `constructor` will be used for the creation of `R`.911/// If a [`Default`] constructor is desired, use [`App::register_required_components`] instead.912///913/// For the non-panicking version, see [`App::try_register_required_components_with`].914///915/// Note that requirements must currently be registered before `T` is inserted into the world916/// for the first time. Commonly, this is done in plugins. This limitation may be fixed in the future.917///918/// [required component]: Component#required-components919///920/// # Panics921///922/// Panics if `R` is already a directly required component for `T`, or if `T` has ever been added923/// on an entity before the registration.924///925/// Indirect requirements through other components are allowed. In those cases, any existing requirements926/// will only be overwritten if the new requirement is more specific.927///928/// # Example929///930/// ```931/// # use bevy_app::{App, NoopPluginGroup as MinimalPlugins, Startup};932/// # use bevy_ecs::prelude::*;933/// #[derive(Component)]934/// struct A;935///936/// #[derive(Component, Default, PartialEq, Eq, Debug)]937/// struct B(usize);938///939/// #[derive(Component, Default, PartialEq, Eq, Debug)]940/// struct C(u32);941///942/// # let mut app = App::new();943/// # app.add_plugins(MinimalPlugins).add_systems(Startup, setup);944/// // Register B and C as required by A and C as required by B.945/// // A requiring C directly will overwrite the indirect requirement through B.946/// app.register_required_components::<A, B>();947/// app.register_required_components_with::<B, C>(|| C(1));948/// app.register_required_components_with::<A, C>(|| C(2));949///950/// fn setup(mut commands: Commands) {951/// // This will implicitly also insert B with its Default constructor and C952/// // with the custom constructor defined by A.953/// commands.spawn(A);954/// }955///956/// fn validate(query: Option<Single<(&A, &B, &C)>>) {957/// let (a, b, c) = query.unwrap().into_inner();958/// assert_eq!(b, &B(0));959/// assert_eq!(c, &C(2));960/// }961/// # app.update();962/// ```963pub fn register_required_components_with<T: Component, R: Component>(964&mut self,965constructor: fn() -> R,966) -> &mut Self {967self.world_mut()968.register_required_components_with::<T, R>(constructor);969self970}971972/// Tries to register the given component `R` as a [required component] for `T`.973///974/// When `T` is added to an entity, `R` and its own required components will also be added975/// if `R` was not already provided. The [`Default`] `constructor` will be used for the creation of `R`.976/// If a custom constructor is desired, use [`App::register_required_components_with`] instead.977///978/// For the panicking version, see [`App::register_required_components`].979///980/// Note that requirements must currently be registered before `T` is inserted into the world981/// for the first time. Commonly, this is done in plugins. This limitation may be fixed in the future.982///983/// [required component]: Component#required-components984///985/// # Errors986///987/// Returns a [`RequiredComponentsError`] if `R` is already a directly required component for `T`, or if `T` has ever been added988/// on an entity before the registration.989///990/// Indirect requirements through other components are allowed. In those cases, any existing requirements991/// will only be overwritten if the new requirement is more specific.992///993/// # Example994///995/// ```996/// # use bevy_app::{App, NoopPluginGroup as MinimalPlugins, Startup};997/// # use bevy_ecs::prelude::*;998/// #[derive(Component)]999/// struct A;1000///1001/// #[derive(Component, Default, PartialEq, Eq, Debug)]1002/// struct B(usize);1003///1004/// #[derive(Component, Default, PartialEq, Eq, Debug)]1005/// struct C(u32);1006///1007/// # let mut app = App::new();1008/// # app.add_plugins(MinimalPlugins).add_systems(Startup, setup);1009/// // Register B as required by A and C as required by B.1010/// app.register_required_components::<A, B>();1011/// app.register_required_components::<B, C>();1012///1013/// // Duplicate registration! This will fail.1014/// assert!(app.try_register_required_components::<A, B>().is_err());1015///1016/// fn setup(mut commands: Commands) {1017/// // This will implicitly also insert B and C with their Default constructors.1018/// commands.spawn(A);1019/// }1020///1021/// fn validate(query: Option<Single<(&A, &B, &C)>>) {1022/// let (a, b, c) = query.unwrap().into_inner();1023/// assert_eq!(b, &B(0));1024/// assert_eq!(c, &C(0));1025/// }1026/// # app.update();1027/// ```1028pub fn try_register_required_components<T: Component, R: Component + Default>(1029&mut self,1030) -> Result<(), RequiredComponentsError> {1031self.world_mut().try_register_required_components::<T, R>()1032}10331034/// Tries to register the given component `R` as a [required component] for `T`.1035///1036/// When `T` is added to an entity, `R` and its own required components will also be added1037/// if `R` was not already provided. The given `constructor` will be used for the creation of `R`.1038/// If a [`Default`] constructor is desired, use [`App::register_required_components`] instead.1039///1040/// For the panicking version, see [`App::register_required_components_with`].1041///1042/// Note that requirements must currently be registered before `T` is inserted into the world1043/// for the first time. Commonly, this is done in plugins. This limitation may be fixed in the future.1044///1045/// [required component]: Component#required-components1046///1047/// # Errors1048///1049/// Returns a [`RequiredComponentsError`] if `R` is already a directly required component for `T`, or if `T` has ever been added1050/// on an entity before the registration.1051///1052/// Indirect requirements through other components are allowed. In those cases, any existing requirements1053/// will only be overwritten if the new requirement is more specific.1054///1055/// # Example1056///1057/// ```1058/// # use bevy_app::{App, NoopPluginGroup as MinimalPlugins, Startup};1059/// # use bevy_ecs::prelude::*;1060/// #[derive(Component)]1061/// struct A;1062///1063/// #[derive(Component, Default, PartialEq, Eq, Debug)]1064/// struct B(usize);1065///1066/// #[derive(Component, Default, PartialEq, Eq, Debug)]1067/// struct C(u32);1068///1069/// # let mut app = App::new();1070/// # app.add_plugins(MinimalPlugins).add_systems(Startup, setup);1071/// // Register B and C as required by A and C as required by B.1072/// // A requiring C directly will overwrite the indirect requirement through B.1073/// app.register_required_components::<A, B>();1074/// app.register_required_components_with::<B, C>(|| C(1));1075/// app.register_required_components_with::<A, C>(|| C(2));1076///1077/// // Duplicate registration! Even if the constructors were different, this would fail.1078/// assert!(app.try_register_required_components_with::<B, C>(|| C(1)).is_err());1079///1080/// fn setup(mut commands: Commands) {1081/// // This will implicitly also insert B with its Default constructor and C1082/// // with the custom constructor defined by A.1083/// commands.spawn(A);1084/// }1085///1086/// fn validate(query: Option<Single<(&A, &B, &C)>>) {1087/// let (a, b, c) = query.unwrap().into_inner();1088/// assert_eq!(b, &B(0));1089/// assert_eq!(c, &C(2));1090/// }1091/// # app.update();1092/// ```1093pub fn try_register_required_components_with<T: Component, R: Component>(1094&mut self,1095constructor: fn() -> R,1096) -> Result<(), RequiredComponentsError> {1097self.world_mut()1098.try_register_required_components_with::<T, R>(constructor)1099}11001101/// Registers a component type as "disabling",1102/// using [default query filters](bevy_ecs::entity_disabling::DefaultQueryFilters) to exclude entities with the component from queries.1103///1104/// # Warning1105///1106/// As discussed in the [module docs](bevy_ecs::entity_disabling), this can have performance implications,1107/// as well as create interoperability issues, and should be used with caution.1108pub fn register_disabling_component<C: Component>(&mut self) {1109self.world_mut().register_disabling_component::<C>();1110}11111112/// Returns a reference to the main [`SubApp`]'s [`World`]. This is the same as calling1113/// [`app.main().world()`].1114///1115/// [`app.main().world()`]: SubApp::world1116pub fn world(&self) -> &World {1117self.main().world()1118}11191120/// Returns a mutable reference to the main [`SubApp`]'s [`World`]. This is the same as calling1121/// [`app.main_mut().world_mut()`].1122///1123/// [`app.main_mut().world_mut()`]: SubApp::world_mut1124pub fn world_mut(&mut self) -> &mut World {1125self.main_mut().world_mut()1126}11271128/// Returns a reference to the main [`SubApp`].1129pub fn main(&self) -> &SubApp {1130&self.sub_apps.main1131}11321133/// Returns a mutable reference to the main [`SubApp`].1134pub fn main_mut(&mut self) -> &mut SubApp {1135&mut self.sub_apps.main1136}11371138/// Returns a reference to the [`SubApps`] collection.1139pub fn sub_apps(&self) -> &SubApps {1140&self.sub_apps1141}11421143/// Returns a mutable reference to the [`SubApps`] collection.1144pub fn sub_apps_mut(&mut self) -> &mut SubApps {1145&mut self.sub_apps1146}11471148/// Returns a reference to the [`SubApp`] with the given label.1149///1150/// # Panics1151///1152/// Panics if the [`SubApp`] doesn't exist.1153pub fn sub_app(&self, label: impl AppLabel) -> &SubApp {1154let str = label.intern();1155self.get_sub_app(label).unwrap_or_else(|| {1156panic!("No sub-app with label '{:?}' exists.", str);1157})1158}11591160/// Returns a reference to the [`SubApp`] with the given label.1161///1162/// # Panics1163///1164/// Panics if the [`SubApp`] doesn't exist.1165pub fn sub_app_mut(&mut self, label: impl AppLabel) -> &mut SubApp {1166let str = label.intern();1167self.get_sub_app_mut(label).unwrap_or_else(|| {1168panic!("No sub-app with label '{:?}' exists.", str);1169})1170}11711172/// Returns a reference to the [`SubApp`] with the given label, if it exists.1173pub fn get_sub_app(&self, label: impl AppLabel) -> Option<&SubApp> {1174self.sub_apps.sub_apps.get(&label.intern())1175}11761177/// Returns a mutable reference to the [`SubApp`] with the given label, if it exists.1178pub fn get_sub_app_mut(&mut self, label: impl AppLabel) -> Option<&mut SubApp> {1179self.sub_apps.sub_apps.get_mut(&label.intern())1180}11811182/// Inserts a [`SubApp`] with the given label.1183pub fn insert_sub_app(&mut self, label: impl AppLabel, mut sub_app: SubApp) {1184if let Some(handler) = self.default_error_handler {1185sub_app1186.world_mut()1187.get_resource_or_insert_with(|| DefaultErrorHandler(handler));1188}1189self.sub_apps.sub_apps.insert(label.intern(), sub_app);1190}11911192/// Removes the [`SubApp`] with the given label, if it exists.1193pub fn remove_sub_app(&mut self, label: impl AppLabel) -> Option<SubApp> {1194self.sub_apps.sub_apps.remove(&label.intern())1195}11961197/// Extract data from the main world into the [`SubApp`] with the given label and perform an update if it exists.1198pub fn update_sub_app_by_label(&mut self, label: impl AppLabel) {1199self.sub_apps.update_subapp_by_label(label);1200}12011202/// Inserts a new `schedule` under the provided `label`, overwriting any existing1203/// schedule with the same label.1204pub fn add_schedule(&mut self, schedule: Schedule) -> &mut Self {1205self.main_mut().add_schedule(schedule);1206self1207}12081209/// Initializes an empty `schedule` under the provided `label`, if it does not exist.1210///1211/// See [`add_schedule`](Self::add_schedule) to insert an existing schedule.1212pub fn init_schedule(&mut self, label: impl ScheduleLabel) -> &mut Self {1213self.main_mut().init_schedule(label);1214self1215}12161217/// Returns a reference to the [`Schedule`] with the provided `label` if it exists.1218pub fn get_schedule(&self, label: impl ScheduleLabel) -> Option<&Schedule> {1219self.main().get_schedule(label)1220}12211222/// Returns a mutable reference to the [`Schedule`] with the provided `label` if it exists.1223pub fn get_schedule_mut(&mut self, label: impl ScheduleLabel) -> Option<&mut Schedule> {1224self.main_mut().get_schedule_mut(label)1225}12261227/// Runs function `f` with the [`Schedule`] associated with `label`.1228///1229/// **Note:** This will create the schedule if it does not already exist.1230pub fn edit_schedule(1231&mut self,1232label: impl ScheduleLabel,1233f: impl FnMut(&mut Schedule),1234) -> &mut Self {1235self.main_mut().edit_schedule(label, f);1236self1237}12381239/// Applies the provided [`ScheduleBuildSettings`] to all schedules.1240///1241/// This mutates all currently present schedules, but does not apply to any custom schedules1242/// that might be added in the future.1243pub fn configure_schedules(1244&mut self,1245schedule_build_settings: ScheduleBuildSettings,1246) -> &mut Self {1247self.main_mut().configure_schedules(schedule_build_settings);1248self1249}12501251/// When doing [ambiguity checking](ScheduleBuildSettings) this1252/// ignores systems that are ambiguous on [`Component`] T.1253///1254/// This settings only applies to the main world. To apply this to other worlds call the1255/// [corresponding method](World::allow_ambiguous_component) on World1256///1257/// ## Example1258///1259/// ```1260/// # use bevy_app::prelude::*;1261/// # use bevy_ecs::prelude::*;1262/// # use bevy_ecs::schedule::{LogLevel, ScheduleBuildSettings};1263/// # use bevy_utils::default;1264///1265/// #[derive(Component)]1266/// struct A;1267///1268/// // these systems are ambiguous on A1269/// fn system_1(_: Query<&mut A>) {}1270/// fn system_2(_: Query<&A>) {}1271///1272/// let mut app = App::new();1273/// app.configure_schedules(ScheduleBuildSettings {1274/// ambiguity_detection: LogLevel::Error,1275/// ..default()1276/// });1277///1278/// app.add_systems(Update, ( system_1, system_2 ));1279/// app.allow_ambiguous_component::<A>();1280///1281/// // running the app does not error.1282/// app.update();1283/// ```1284pub fn allow_ambiguous_component<T: Component>(&mut self) -> &mut Self {1285self.main_mut().allow_ambiguous_component::<T>();1286self1287}12881289/// When doing [ambiguity checking](ScheduleBuildSettings) this1290/// ignores systems that are ambiguous on [`Resource`] T.1291///1292/// This settings only applies to the main world. To apply this to other worlds call the1293/// [corresponding method](World::allow_ambiguous_resource) on World1294///1295/// ## Example1296///1297/// ```1298/// # use bevy_app::prelude::*;1299/// # use bevy_ecs::prelude::*;1300/// # use bevy_ecs::schedule::{LogLevel, ScheduleBuildSettings};1301/// # use bevy_utils::default;1302///1303/// #[derive(Resource)]1304/// struct R;1305///1306/// // these systems are ambiguous on R1307/// fn system_1(_: ResMut<R>) {}1308/// fn system_2(_: Res<R>) {}1309///1310/// let mut app = App::new();1311/// app.configure_schedules(ScheduleBuildSettings {1312/// ambiguity_detection: LogLevel::Error,1313/// ..default()1314/// });1315/// app.insert_resource(R);1316///1317/// app.add_systems(Update, ( system_1, system_2 ));1318/// app.allow_ambiguous_resource::<R>();1319///1320/// // running the app does not error.1321/// app.update();1322/// ```1323pub fn allow_ambiguous_resource<T: Resource>(&mut self) -> &mut Self {1324self.main_mut().allow_ambiguous_resource::<T>();1325self1326}13271328/// Suppress warnings and errors that would result from systems in these sets having ambiguities1329/// (conflicting access but indeterminate order) with systems in `set`.1330///1331/// When possible, do this directly in the `.add_systems(Update, a.ambiguous_with(b))` call.1332/// However, sometimes two independent plugins `A` and `B` are reported as ambiguous, which you1333/// can only suppress as the consumer of both.1334#[track_caller]1335pub fn ignore_ambiguity<M1, M2, S1, S2>(1336&mut self,1337schedule: impl ScheduleLabel,1338a: S1,1339b: S2,1340) -> &mut Self1341where1342S1: IntoSystemSet<M1>,1343S2: IntoSystemSet<M2>,1344{1345self.main_mut().ignore_ambiguity(schedule, a, b);1346self1347}13481349/// Attempts to determine if an [`AppExit`] was raised since the last update.1350///1351/// Will attempt to return the first [`Error`](AppExit::Error) it encounters.1352/// This should be called after every [`update()`](App::update) otherwise you risk1353/// dropping possible [`AppExit`] events.1354pub fn should_exit(&self) -> Option<AppExit> {1355let mut reader = MessageCursor::default();13561357let messages = self.world().get_resource::<Messages<AppExit>>()?;1358let mut messages = reader.read(messages);13591360if messages.len() != 0 {1361return Some(1362messages1363.find(|exit| exit.is_error())1364.cloned()1365.unwrap_or(AppExit::Success),1366);1367}13681369None1370}13711372/// Spawns an [`Observer`] entity, which will watch for and respond to the given event.1373///1374/// `observer` can be any system whose first parameter is [`On`].1375///1376/// # Examples1377///1378/// ```rust1379/// # use bevy_app::prelude::*;1380/// # use bevy_ecs::prelude::*;1381/// # use bevy_utils::default;1382/// #1383/// # let mut app = App::new();1384/// #1385/// # #[derive(Event)]1386/// # struct Party {1387/// # friends_allowed: bool,1388/// # };1389/// #1390/// # #[derive(EntityEvent)]1391/// # struct Invite {1392/// # entity: Entity,1393/// # }1394/// #1395/// # #[derive(Component)]1396/// # struct Friend;1397/// #1398///1399/// app.add_observer(|event: On<Party>, friends: Query<Entity, With<Friend>>, mut commands: Commands| {1400/// if event.friends_allowed {1401/// for entity in friends.iter() {1402/// commands.trigger(Invite { entity } );1403/// }1404/// }1405/// });1406/// ```1407pub fn add_observer<M>(&mut self, observer: impl IntoObserver<M>) -> &mut Self {1408self.world_mut().add_observer(observer);1409self1410}14111412/// Gets the error handler to set for new supapps.1413///1414/// Note that the error handler of existing subapps may differ.1415pub fn get_error_handler(&self) -> Option<ErrorHandler> {1416self.default_error_handler1417}14181419/// Set the [default error handler] for the all subapps (including the main one and future ones)1420/// that do not have one.1421///1422/// May only be called once and should be set by the application, not by libraries.1423///1424/// The handler will be called when an error is produced and not otherwise handled.1425///1426/// # Panics1427/// Panics if called multiple times.1428///1429/// # Example1430/// ```1431/// # use bevy_app::*;1432/// # use bevy_ecs::error::warn;1433/// # fn MyPlugins(_: &mut App) {}1434/// App::new()1435/// .set_error_handler(warn)1436/// .add_plugins(MyPlugins)1437/// .run();1438/// ```1439///1440/// [default error handler]: bevy_ecs::error::DefaultErrorHandler1441pub fn set_error_handler(&mut self, handler: ErrorHandler) -> &mut Self {1442assert!(1443self.default_error_handler.is_none(),1444"`set_error_handler` called multiple times on same `App`"1445);1446self.default_error_handler = Some(handler);1447for sub_app in self.sub_apps.iter_mut() {1448sub_app1449.world_mut()1450.get_resource_or_insert_with(|| DefaultErrorHandler(handler));1451}1452self1453}1454}14551456// Used for doing hokey pokey in finish and cleanup1457pub(crate) struct HokeyPokey;1458impl Plugin for HokeyPokey {1459fn build(&self, _: &mut App) {}1460}14611462type RunnerFn = Box<dyn FnOnce(App) -> AppExit>;14631464fn run_once(mut app: App) -> AppExit {1465while app.plugins_state() == PluginsState::Adding {1466#[cfg(not(all(target_arch = "wasm32", feature = "web")))]1467bevy_tasks::tick_global_task_pools_on_main_thread();1468}1469app.finish();1470app.cleanup();14711472app.update();14731474app.should_exit().unwrap_or(AppExit::Success)1475}14761477/// A [`Message`] that indicates the [`App`] should exit. If one or more of these are present at the end of an update,1478/// the [runner](App::set_runner) will end and ([maybe](App::run)) return control to the caller.1479///1480/// This message can be used to detect when an exit is requested. Make sure that systems listening1481/// for this message run before the current update ends.1482///1483/// # Portability1484/// This type is roughly meant to map to a standard definition of a process exit code (0 means success, not 0 means error). Due to portability concerns1485/// (see [`ExitCode`](https://doc.rust-lang.org/std/process/struct.ExitCode.html) and [`process::exit`](https://doc.rust-lang.org/std/process/fn.exit.html#))1486/// we only allow error codes between 1 and [255](u8::MAX).1487#[derive(Message, Debug, Clone, Default, PartialEq, Eq)]1488pub enum AppExit {1489/// [`App`] exited without any problems.1490#[default]1491Success,1492/// The [`App`] experienced an unhandleable error.1493/// Holds the exit code we expect our app to return.1494Error(NonZero<u8>),1495}14961497impl AppExit {1498/// Creates a [`AppExit::Error`] with an error code of 1.1499#[must_use]1500pub const fn error() -> Self {1501Self::Error(NonZero::<u8>::MIN)1502}15031504/// Returns `true` if `self` is a [`AppExit::Success`].1505#[must_use]1506pub const fn is_success(&self) -> bool {1507matches!(self, AppExit::Success)1508}15091510/// Returns `true` if `self` is a [`AppExit::Error`].1511#[must_use]1512pub const fn is_error(&self) -> bool {1513matches!(self, AppExit::Error(_))1514}15151516/// Creates a [`AppExit`] from a code.1517///1518/// When `code` is 0 a [`AppExit::Success`] is constructed otherwise a1519/// [`AppExit::Error`] is constructed.1520#[must_use]1521pub const fn from_code(code: u8) -> Self {1522match NonZero::<u8>::new(code) {1523Some(code) => Self::Error(code),1524None => Self::Success,1525}1526}1527}15281529impl From<u8> for AppExit {1530fn from(value: u8) -> Self {1531Self::from_code(value)1532}1533}15341535#[cfg(feature = "std")]1536impl Termination for AppExit {1537fn report(self) -> ExitCode {1538match self {1539AppExit::Success => ExitCode::SUCCESS,1540// We leave logging an error to our users1541AppExit::Error(value) => ExitCode::from(value.get()),1542}1543}1544}15451546#[cfg(test)]1547mod tests {1548use core::marker::PhantomData;1549use std::sync::Mutex;15501551use bevy_ecs::{1552change_detection::{DetectChanges, ResMut},1553component::Component,1554entity::Entity,1555lifecycle::RemovedComponents,1556message::{Message, MessageWriter, Messages},1557query::With,1558resource::Resource,1559schedule::{IntoScheduleConfigs, ScheduleLabel},1560system::{Commands, Query},1561world::{FromWorld, World},1562};15631564use crate::{App, AppExit, Plugin, SubApp, Update};15651566struct PluginA;1567impl Plugin for PluginA {1568fn build(&self, _app: &mut App) {}1569}1570struct PluginB;1571impl Plugin for PluginB {1572fn build(&self, _app: &mut App) {}1573}1574struct PluginC<T>(T);1575impl<T: Send + Sync + 'static> Plugin for PluginC<T> {1576fn build(&self, _app: &mut App) {}1577}1578struct PluginD;1579impl Plugin for PluginD {1580fn build(&self, _app: &mut App) {}1581fn is_unique(&self) -> bool {1582false1583}1584}15851586struct PluginE;15871588impl Plugin for PluginE {1589fn build(&self, _app: &mut App) {}15901591fn finish(&self, app: &mut App) {1592if app.is_plugin_added::<PluginA>() {1593panic!("cannot run if PluginA is already registered");1594}1595}1596}15971598struct PluginF;15991600impl Plugin for PluginF {1601fn build(&self, _app: &mut App) {}16021603fn finish(&self, app: &mut App) {1604// Ensure other plugins are available during finish1605assert_eq!(1606app.is_plugin_added::<PluginA>(),1607!app.get_added_plugins::<PluginA>().is_empty(),1608);1609}16101611fn cleanup(&self, app: &mut App) {1612// Ensure other plugins are available during finish1613assert_eq!(1614app.is_plugin_added::<PluginA>(),1615!app.get_added_plugins::<PluginA>().is_empty(),1616);1617}1618}16191620struct PluginG;16211622impl Plugin for PluginG {1623fn build(&self, _app: &mut App) {}16241625fn finish(&self, app: &mut App) {1626app.add_plugins(PluginB);1627}1628}16291630#[test]1631fn can_add_two_plugins() {1632App::new().add_plugins((PluginA, PluginB));1633}16341635#[test]1636#[should_panic]1637fn cant_add_twice_the_same_plugin() {1638App::new().add_plugins((PluginA, PluginA));1639}16401641#[test]1642fn can_add_twice_the_same_plugin_with_different_type_param() {1643App::new().add_plugins((PluginC(0), PluginC(true)));1644}16451646#[test]1647fn can_add_twice_the_same_plugin_not_unique() {1648App::new().add_plugins((PluginD, PluginD));1649}16501651#[test]1652#[should_panic]1653fn cant_call_app_run_from_plugin_build() {1654struct PluginRun;1655struct InnerPlugin;1656impl Plugin for InnerPlugin {1657fn build(&self, _: &mut App) {}1658}1659impl Plugin for PluginRun {1660fn build(&self, app: &mut App) {1661app.add_plugins(InnerPlugin).run();1662}1663}1664App::new().add_plugins(PluginRun);1665}16661667#[derive(ScheduleLabel, Hash, Clone, PartialEq, Eq, Debug)]1668struct EnterMainMenu;16691670#[derive(Component)]1671struct A;16721673fn bar(mut commands: Commands) {1674commands.spawn(A);1675}16761677fn foo(mut commands: Commands) {1678commands.spawn(A);1679}16801681#[test]1682fn add_systems_should_create_schedule_if_it_does_not_exist() {1683let mut app = App::new();1684app.add_systems(EnterMainMenu, (foo, bar));16851686app.world_mut().run_schedule(EnterMainMenu);1687assert_eq!(app.world_mut().query::<&A>().query(app.world()).count(), 2);1688}16891690#[test]1691#[should_panic]1692fn test_is_plugin_added_works_during_finish() {1693let mut app = App::new();1694app.add_plugins(PluginA);1695app.add_plugins(PluginE);1696app.finish();1697}16981699#[test]1700fn test_get_added_plugins_works_during_finish_and_cleanup() {1701let mut app = App::new();1702app.add_plugins(PluginA);1703app.add_plugins(PluginF);1704app.finish();1705}17061707#[test]1708fn test_adding_plugin_works_during_finish() {1709let mut app = App::new();1710app.add_plugins(PluginA);1711app.add_plugins(PluginG);1712app.finish();1713assert_eq!(1714app.main().plugin_registry[0].name(),1715"bevy_app::main_schedule::MainSchedulePlugin"1716);1717assert_eq!(1718app.main().plugin_registry[1].name(),1719"bevy_app::app::tests::PluginA"1720);1721assert_eq!(1722app.main().plugin_registry[2].name(),1723"bevy_app::app::tests::PluginG"1724);1725// PluginG adds PluginB during finish1726assert_eq!(1727app.main().plugin_registry[3].name(),1728"bevy_app::app::tests::PluginB"1729);1730}17311732#[test]1733fn test_derive_app_label() {1734use super::AppLabel;17351736#[derive(AppLabel, Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]1737struct UnitLabel;17381739#[derive(AppLabel, Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]1740struct TupleLabel(u32, u32);17411742#[derive(AppLabel, Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]1743struct StructLabel {1744a: u32,1745b: u32,1746}17471748#[expect(1749dead_code,1750reason = "This struct is used as a compilation test to test the derive macros, and as such is intentionally never constructed."1751)]1752#[derive(AppLabel, Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]1753struct EmptyTupleLabel();17541755#[expect(1756dead_code,1757reason = "This struct is used as a compilation test to test the derive macros, and as such is intentionally never constructed."1758)]1759#[derive(AppLabel, Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]1760struct EmptyStructLabel {}17611762#[derive(AppLabel, Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]1763enum EnumLabel {1764#[default]1765Unit,1766Tuple(u32, u32),1767Struct {1768a: u32,1769b: u32,1770},1771}17721773#[derive(AppLabel, Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]1774struct GenericLabel<T>(PhantomData<T>);17751776assert_eq!(UnitLabel.intern(), UnitLabel.intern());1777assert_eq!(EnumLabel::Unit.intern(), EnumLabel::Unit.intern());1778assert_ne!(UnitLabel.intern(), EnumLabel::Unit.intern());1779assert_ne!(UnitLabel.intern(), TupleLabel(0, 0).intern());1780assert_ne!(EnumLabel::Unit.intern(), EnumLabel::Tuple(0, 0).intern());17811782assert_eq!(TupleLabel(0, 0).intern(), TupleLabel(0, 0).intern());1783assert_eq!(1784EnumLabel::Tuple(0, 0).intern(),1785EnumLabel::Tuple(0, 0).intern()1786);1787assert_ne!(TupleLabel(0, 0).intern(), TupleLabel(0, 1).intern());1788assert_ne!(1789EnumLabel::Tuple(0, 0).intern(),1790EnumLabel::Tuple(0, 1).intern()1791);1792assert_ne!(TupleLabel(0, 0).intern(), EnumLabel::Tuple(0, 0).intern());1793assert_ne!(1794TupleLabel(0, 0).intern(),1795StructLabel { a: 0, b: 0 }.intern()1796);1797assert_ne!(1798EnumLabel::Tuple(0, 0).intern(),1799EnumLabel::Struct { a: 0, b: 0 }.intern()1800);18011802assert_eq!(1803StructLabel { a: 0, b: 0 }.intern(),1804StructLabel { a: 0, b: 0 }.intern()1805);1806assert_eq!(1807EnumLabel::Struct { a: 0, b: 0 }.intern(),1808EnumLabel::Struct { a: 0, b: 0 }.intern()1809);1810assert_ne!(1811StructLabel { a: 0, b: 0 }.intern(),1812StructLabel { a: 0, b: 1 }.intern()1813);1814assert_ne!(1815EnumLabel::Struct { a: 0, b: 0 }.intern(),1816EnumLabel::Struct { a: 0, b: 1 }.intern()1817);1818assert_ne!(1819StructLabel { a: 0, b: 0 }.intern(),1820EnumLabel::Struct { a: 0, b: 0 }.intern()1821);1822assert_ne!(1823StructLabel { a: 0, b: 0 }.intern(),1824EnumLabel::Struct { a: 0, b: 0 }.intern()1825);1826assert_ne!(StructLabel { a: 0, b: 0 }.intern(), UnitLabel.intern(),);1827assert_ne!(1828EnumLabel::Struct { a: 0, b: 0 }.intern(),1829EnumLabel::Unit.intern()1830);18311832assert_eq!(1833GenericLabel::<u32>(PhantomData).intern(),1834GenericLabel::<u32>(PhantomData).intern()1835);1836assert_ne!(1837GenericLabel::<u32>(PhantomData).intern(),1838GenericLabel::<u64>(PhantomData).intern()1839);1840}18411842#[test]1843fn test_update_clears_trackers_once() {1844#[derive(Component, Copy, Clone)]1845struct Foo;18461847let mut app = App::new();1848app.world_mut().spawn_batch(core::iter::repeat_n(Foo, 5));18491850fn despawn_one_foo(mut commands: Commands, foos: Query<Entity, With<Foo>>) {1851if let Some(e) = foos.iter().next() {1852commands.entity(e).despawn();1853};1854}1855fn check_despawns(mut removed_foos: RemovedComponents<Foo>) {1856let mut despawn_count = 0;1857for _ in removed_foos.read() {1858despawn_count += 1;1859}18601861assert_eq!(despawn_count, 2);1862}18631864app.add_systems(Update, despawn_one_foo);1865app.update(); // Frame 01866app.update(); // Frame 11867app.add_systems(Update, check_despawns.after(despawn_one_foo));1868app.update(); // Should see despawns from frames 1 & 2, but not frame 01869}18701871#[test]1872fn test_extract_sees_changes() {1873use super::AppLabel;18741875#[derive(AppLabel, Clone, Copy, Hash, PartialEq, Eq, Debug)]1876struct MySubApp;18771878#[derive(Resource)]1879struct Foo(usize);18801881let mut app = App::new();1882app.world_mut().insert_resource(Foo(0));1883app.add_systems(Update, |mut foo: ResMut<Foo>| {1884foo.0 += 1;1885});18861887let mut sub_app = SubApp::new();1888sub_app.set_extract(|main_world, _sub_world| {1889assert!(main_world.get_resource_ref::<Foo>().unwrap().is_changed());1890});18911892app.insert_sub_app(MySubApp, sub_app);18931894app.update();1895}18961897#[test]1898fn runner_returns_correct_exit_code() {1899fn raise_exits(mut exits: MessageWriter<AppExit>) {1900// Exit codes chosen by a fair dice roll.1901// Unlikely to overlap with default values.1902exits.write(AppExit::Success);1903exits.write(AppExit::from_code(4));1904exits.write(AppExit::from_code(73));1905}19061907let exit = App::new().add_systems(Update, raise_exits).run();19081909assert_eq!(exit, AppExit::from_code(4));1910}19111912/// Custom runners should be in charge of when `app::update` gets called as they may need to1913/// coordinate some state.1914/// bug: <https://github.com/bevyengine/bevy/issues/10385>1915/// fix: <https://github.com/bevyengine/bevy/pull/10389>1916#[test]1917fn regression_test_10385() {1918use super::{Res, Resource};1919use crate::PreUpdate;19201921#[derive(Resource)]1922struct MyState {}19231924fn my_runner(mut app: App) -> AppExit {1925let my_state = MyState {};1926app.world_mut().insert_resource(my_state);19271928for _ in 0..5 {1929app.update();1930}19311932AppExit::Success1933}19341935fn my_system(_: Res<MyState>) {1936// access state during app update1937}19381939// Should not panic due to missing resource1940App::new()1941.set_runner(my_runner)1942.add_systems(PreUpdate, my_system)1943.run();1944}19451946#[test]1947fn app_exit_size() {1948// There wont be many of them so the size isn't an issue but1949// it's nice they're so small let's keep it that way.1950assert_eq!(size_of::<AppExit>(), size_of::<u8>());1951}19521953#[test]1954fn initializing_resources_from_world() {1955#[derive(Resource)]1956struct TestResource;1957impl FromWorld for TestResource {1958fn from_world(_world: &mut World) -> Self {1959TestResource1960}1961}19621963#[derive(Resource)]1964struct NonSendTestResource {1965_marker: PhantomData<Mutex<()>>,1966}1967impl FromWorld for NonSendTestResource {1968fn from_world(_world: &mut World) -> Self {1969NonSendTestResource {1970_marker: PhantomData,1971}1972}1973}19741975App::new()1976.init_non_send::<NonSendTestResource>()1977.init_resource::<TestResource>();1978}19791980#[test]1981/// Plugin should not be considered inserted while it's being built1982///1983/// bug: <https://github.com/bevyengine/bevy/issues/13815>1984fn plugin_should_not_be_added_during_build_time() {1985pub struct Foo;19861987impl Plugin for Foo {1988fn build(&self, app: &mut App) {1989assert!(!app.is_plugin_added::<Self>());1990}1991}19921993App::new().add_plugins(Foo);1994}1995#[test]1996fn events_should_be_updated_once_per_update() {1997#[derive(Message, Clone)]1998struct TestMessage;19992000let mut app = App::new();2001app.add_message::<TestMessage>();20022003// Starts empty2004let test_messages = app.world().resource::<Messages<TestMessage>>();2005assert_eq!(test_messages.len(), 0);2006assert_eq!(test_messages.iter_current_update_messages().count(), 0);2007app.update();20082009// Sending one event2010app.world_mut().write_message(TestMessage);20112012let test_events = app.world().resource::<Messages<TestMessage>>();2013assert_eq!(test_events.len(), 1);2014assert_eq!(test_events.iter_current_update_messages().count(), 1);2015app.update();20162017// Sending two events on the next frame2018app.world_mut().write_message(TestMessage);2019app.world_mut().write_message(TestMessage);20202021let test_events = app.world().resource::<Messages<TestMessage>>();2022assert_eq!(test_events.len(), 3); // Events are double-buffered, so we see 1 + 2 = 32023assert_eq!(test_events.iter_current_update_messages().count(), 2);2024app.update();20252026// Sending zero events2027let test_events = app.world().resource::<Messages<TestMessage>>();2028assert_eq!(test_events.len(), 2); // Events are double-buffered, so we see 2 + 0 = 22029assert_eq!(test_events.iter_current_update_messages().count(), 0);2030}2031}203220332034