bevy_app/
app.rs

1use crate::{
2    First, Main, MainSchedulePlugin, PlaceholderPlugin, Plugin, Plugins, PluginsState, SubApp,
3    SubApps,
4};
5pub use bevy_derive::AppLabel;
6use bevy_ecs::{
7    component::RequiredComponentsError,
8    event::{event_update_system, EventCursor},
9    intern::Interned,
10    prelude::*,
11    schedule::{ScheduleBuildSettings, ScheduleLabel},
12    system::{IntoObserverSystem, SystemId, SystemInput},
13};
14#[cfg(feature = "trace")]
15use bevy_utils::tracing::info_span;
16use bevy_utils::{tracing::debug, HashMap};
17use core::{fmt::Debug, num::NonZero, panic::AssertUnwindSafe};
18use derive_more::derive::{Display, Error};
19use std::{
20    panic::{catch_unwind, resume_unwind},
21    process::{ExitCode, Termination},
22};
23
24bevy_ecs::define_label!(
25    /// A strongly-typed class of labels used to identify an [`App`].
26    AppLabel,
27    APP_LABEL_INTERNER
28);
29
30pub use bevy_ecs::label::DynEq;
31
32/// A shorthand for `Interned<dyn AppLabel>`.
33pub type InternedAppLabel = Interned<dyn AppLabel>;
34
35#[derive(Debug, Error, Display)]
36pub(crate) enum AppError {
37    #[display("duplicate plugin {plugin_name:?}")]
38    DuplicatePlugin { plugin_name: String },
39}
40
41/// [`App`] is the primary API for writing user applications. It automates the setup of a
42/// [standard lifecycle](Main) and provides interface glue for [plugins](`Plugin`).
43///
44/// A single [`App`] can contain multiple [`SubApp`] instances, but [`App`] methods only affect
45/// the "main" one. To access a particular [`SubApp`], use [`get_sub_app`](App::get_sub_app)
46/// or [`get_sub_app_mut`](App::get_sub_app_mut).
47///
48///
49/// # Examples
50///
51/// Here is a simple "Hello World" Bevy app:
52///
53/// ```
54/// # use bevy_app::prelude::*;
55/// # use bevy_ecs::prelude::*;
56/// #
57/// fn main() {
58///    App::new()
59///        .add_systems(Update, hello_world_system)
60///        .run();
61/// }
62///
63/// fn hello_world_system() {
64///    println!("hello world");
65/// }
66/// ```
67pub struct App {
68    pub(crate) sub_apps: SubApps,
69    /// The function that will manage the app's lifecycle.
70    ///
71    /// Bevy provides the [`WinitPlugin`] and [`ScheduleRunnerPlugin`] for windowed and headless
72    /// applications, respectively.
73    ///
74    /// [`WinitPlugin`]: https://docs.rs/bevy/latest/bevy/winit/struct.WinitPlugin.html
75    /// [`ScheduleRunnerPlugin`]: https://docs.rs/bevy/latest/bevy/app/struct.ScheduleRunnerPlugin.html
76    pub(crate) runner: RunnerFn,
77}
78
79impl Debug for App {
80    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
81        write!(f, "App {{ sub_apps: ")?;
82        f.debug_map()
83            .entries(self.sub_apps.sub_apps.iter())
84            .finish()?;
85        write!(f, "}}")
86    }
87}
88
89impl Default for App {
90    fn default() -> Self {
91        let mut app = App::empty();
92        app.sub_apps.main.update_schedule = Some(Main.intern());
93
94        #[cfg(feature = "bevy_reflect")]
95        app.init_resource::<AppTypeRegistry>();
96
97        #[cfg(feature = "reflect_functions")]
98        app.init_resource::<AppFunctionRegistry>();
99
100        app.add_plugins(MainSchedulePlugin);
101        app.add_systems(
102            First,
103            event_update_system
104                .in_set(bevy_ecs::event::EventUpdates)
105                .run_if(bevy_ecs::event::event_update_condition),
106        );
107        app.add_event::<AppExit>();
108
109        app
110    }
111}
112
113impl App {
114    /// Creates a new [`App`] with some default structure to enable core engine features.
115    /// This is the preferred constructor for most use cases.
116    pub fn new() -> App {
117        App::default()
118    }
119
120    /// Creates a new empty [`App`] with minimal default configuration.
121    ///
122    /// Use this constructor if you want to customize scheduling, exit handling, cleanup, etc.
123    pub fn empty() -> App {
124        Self {
125            sub_apps: SubApps {
126                main: SubApp::new(),
127                sub_apps: HashMap::new(),
128            },
129            runner: Box::new(run_once),
130        }
131    }
132
133    /// Runs the default schedules of all sub-apps (starting with the "main" app) once.
134    pub fn update(&mut self) {
135        if self.is_building_plugins() {
136            panic!("App::update() was called while a plugin was building.");
137        }
138
139        self.sub_apps.update();
140    }
141
142    /// Runs the [`App`] by calling its [runner](Self::set_runner).
143    ///
144    /// This will (re)build the [`App`] first. For general usage, see the example on the item
145    /// level documentation.
146    ///
147    /// # Caveats
148    ///
149    /// Calls to [`App::run()`] will never return on iOS and Web.
150    ///
151    /// Headless apps can generally expect this method to return control to the caller when
152    /// it completes, but that is not the case for windowed apps. Windowed apps are typically
153    /// driven by an event loop and some platforms expect the program to terminate when the
154    /// event loop ends.
155    ///
156    /// By default, *Bevy* uses the `winit` crate for window creation.
157    ///
158    /// # Panics
159    ///
160    /// Panics if not all plugins have been built.
161    pub fn run(&mut self) -> AppExit {
162        #[cfg(feature = "trace")]
163        let _bevy_app_run_span = info_span!("bevy_app").entered();
164        if self.is_building_plugins() {
165            panic!("App::run() was called while a plugin was building.");
166        }
167
168        let runner = core::mem::replace(&mut self.runner, Box::new(run_once));
169        let app = core::mem::replace(self, App::empty());
170        (runner)(app)
171    }
172
173    /// Sets the function that will be called when the app is run.
174    ///
175    /// The runner function `f` is called only once by [`App::run`]. If the
176    /// presence of a main loop in the app is desired, it is the responsibility of the runner
177    /// function to provide it.
178    ///
179    /// The runner function is usually not set manually, but by Bevy integrated plugins
180    /// (e.g. `WinitPlugin`).
181    ///
182    /// # Examples
183    ///
184    /// ```
185    /// # use bevy_app::prelude::*;
186    /// #
187    /// fn my_runner(mut app: App) -> AppExit {
188    ///     loop {
189    ///         println!("In main loop");
190    ///         app.update();
191    ///         if let Some(exit) = app.should_exit() {
192    ///             return exit;
193    ///         }
194    ///     }
195    /// }
196    ///
197    /// App::new()
198    ///     .set_runner(my_runner);
199    /// ```
200    pub fn set_runner(&mut self, f: impl FnOnce(App) -> AppExit + 'static) -> &mut Self {
201        self.runner = Box::new(f);
202        self
203    }
204
205    /// Returns the state of all plugins. This is usually called by the event loop, but can be
206    /// useful for situations where you want to use [`App::update`].
207    // TODO: &mut self -> &self
208    #[inline]
209    pub fn plugins_state(&mut self) -> PluginsState {
210        let mut overall_plugins_state = match self.main_mut().plugins_state {
211            PluginsState::Adding => {
212                let mut state = PluginsState::Ready;
213                let plugins = core::mem::take(&mut self.main_mut().plugin_registry);
214                for plugin in &plugins {
215                    // plugins installed to main need to see all sub-apps
216                    if !plugin.ready(self) {
217                        state = PluginsState::Adding;
218                        break;
219                    }
220                }
221                self.main_mut().plugin_registry = plugins;
222                state
223            }
224            state => state,
225        };
226
227        // overall state is the earliest state of any sub-app
228        self.sub_apps.iter_mut().skip(1).for_each(|s| {
229            overall_plugins_state = overall_plugins_state.min(s.plugins_state());
230        });
231
232        overall_plugins_state
233    }
234
235    /// Runs [`Plugin::finish`] for each plugin. This is usually called by the event loop once all
236    /// plugins are ready, but can be useful for situations where you want to use [`App::update`].
237    pub fn finish(&mut self) {
238        // plugins installed to main should see all sub-apps
239        let plugins = core::mem::take(&mut self.main_mut().plugin_registry);
240        for plugin in &plugins {
241            plugin.finish(self);
242        }
243        let main = self.main_mut();
244        main.plugin_registry = plugins;
245        main.plugins_state = PluginsState::Finished;
246        self.sub_apps.iter_mut().skip(1).for_each(SubApp::finish);
247    }
248
249    /// Runs [`Plugin::cleanup`] for each plugin. This is usually called by the event loop after
250    /// [`App::finish`], but can be useful for situations where you want to use [`App::update`].
251    pub fn cleanup(&mut self) {
252        // plugins installed to main should see all sub-apps
253        let plugins = core::mem::take(&mut self.main_mut().plugin_registry);
254        for plugin in &plugins {
255            plugin.cleanup(self);
256        }
257        let main = self.main_mut();
258        main.plugin_registry = plugins;
259        main.plugins_state = PluginsState::Cleaned;
260        self.sub_apps.iter_mut().skip(1).for_each(SubApp::cleanup);
261    }
262
263    /// Returns `true` if any of the sub-apps are building plugins.
264    pub(crate) fn is_building_plugins(&self) -> bool {
265        self.sub_apps.iter().any(SubApp::is_building_plugins)
266    }
267
268    /// Adds one or more systems to the given schedule in this app's [`Schedules`].
269    ///
270    /// # Examples
271    ///
272    /// ```
273    /// # use bevy_app::prelude::*;
274    /// # use bevy_ecs::prelude::*;
275    /// #
276    /// # let mut app = App::new();
277    /// # fn system_a() {}
278    /// # fn system_b() {}
279    /// # fn system_c() {}
280    /// # fn should_run() -> bool { true }
281    /// #
282    /// app.add_systems(Update, (system_a, system_b, system_c));
283    /// app.add_systems(Update, (system_a, system_b).run_if(should_run));
284    /// ```
285    pub fn add_systems<M>(
286        &mut self,
287        schedule: impl ScheduleLabel,
288        systems: impl IntoSystemConfigs<M>,
289    ) -> &mut Self {
290        self.main_mut().add_systems(schedule, systems);
291        self
292    }
293
294    /// Registers a system and returns a [`SystemId`] so it can later be called by [`World::run_system`].
295    ///
296    /// It's possible to register the same systems more than once, they'll be stored separately.
297    ///
298    /// This is different from adding systems to a [`Schedule`] with [`App::add_systems`],
299    /// because the [`SystemId`] that is returned can be used anywhere in the [`World`] to run the associated system.
300    /// This allows for running systems in a push-based fashion.
301    /// Using a [`Schedule`] is still preferred for most cases
302    /// due to its better performance and ability to run non-conflicting systems simultaneously.
303    pub fn register_system<I, O, M>(
304        &mut self,
305        system: impl IntoSystem<I, O, M> + 'static,
306    ) -> SystemId<I, O>
307    where
308        I: SystemInput + 'static,
309        O: 'static,
310    {
311        self.main_mut().register_system(system)
312    }
313
314    /// Configures a collection of system sets in the provided schedule, adding any sets that do not exist.
315    #[track_caller]
316    pub fn configure_sets(
317        &mut self,
318        schedule: impl ScheduleLabel,
319        sets: impl IntoSystemSetConfigs,
320    ) -> &mut Self {
321        self.main_mut().configure_sets(schedule, sets);
322        self
323    }
324
325    /// Initializes `T` event handling by inserting an event queue resource ([`Events::<T>`])
326    /// and scheduling an [`event_update_system`] in [`First`].
327    ///
328    /// See [`Events`] for information on how to define events.
329    ///
330    /// # Examples
331    ///
332    /// ```
333    /// # use bevy_app::prelude::*;
334    /// # use bevy_ecs::prelude::*;
335    /// #
336    /// # #[derive(Event)]
337    /// # struct MyEvent;
338    /// # let mut app = App::new();
339    /// #
340    /// app.add_event::<MyEvent>();
341    /// ```
342    pub fn add_event<T>(&mut self) -> &mut Self
343    where
344        T: Event,
345    {
346        self.main_mut().add_event::<T>();
347        self
348    }
349
350    /// Inserts the [`Resource`] into the app, overwriting any existing resource of the same type.
351    ///
352    /// There is also an [`init_resource`](Self::init_resource) for resources that have
353    /// [`Default`] or [`FromWorld`] implementations.
354    ///
355    /// # Examples
356    ///
357    /// ```
358    /// # use bevy_app::prelude::*;
359    /// # use bevy_ecs::prelude::*;
360    /// #
361    /// #[derive(Resource)]
362    /// struct MyCounter {
363    ///     counter: usize,
364    /// }
365    ///
366    /// App::new()
367    ///    .insert_resource(MyCounter { counter: 0 });
368    /// ```
369    pub fn insert_resource<R: Resource>(&mut self, resource: R) -> &mut Self {
370        self.main_mut().insert_resource(resource);
371        self
372    }
373
374    /// Inserts the [`Resource`], initialized with its default value, into the app,
375    /// if there is no existing instance of `R`.
376    ///
377    /// `R` must implement [`FromWorld`].
378    /// If `R` implements [`Default`], [`FromWorld`] will be automatically implemented and
379    /// initialize the [`Resource`] with [`Default::default`].
380    ///
381    /// # Examples
382    ///
383    /// ```
384    /// # use bevy_app::prelude::*;
385    /// # use bevy_ecs::prelude::*;
386    /// #
387    /// #[derive(Resource)]
388    /// struct MyCounter {
389    ///     counter: usize,
390    /// }
391    ///
392    /// impl Default for MyCounter {
393    ///     fn default() -> MyCounter {
394    ///         MyCounter {
395    ///             counter: 100
396    ///         }
397    ///     }
398    /// }
399    ///
400    /// App::new()
401    ///     .init_resource::<MyCounter>();
402    /// ```
403    pub fn init_resource<R: Resource + FromWorld>(&mut self) -> &mut Self {
404        self.main_mut().init_resource::<R>();
405        self
406    }
407
408    /// Inserts the [`!Send`](Send) resource into the app, overwriting any existing resource
409    /// of the same type.
410    ///
411    /// There is also an [`init_non_send_resource`](Self::init_non_send_resource) for
412    /// resources that implement [`Default`]
413    ///
414    /// # Examples
415    ///
416    /// ```
417    /// # use bevy_app::prelude::*;
418    /// # use bevy_ecs::prelude::*;
419    /// #
420    /// struct MyCounter {
421    ///     counter: usize,
422    /// }
423    ///
424    /// App::new()
425    ///     .insert_non_send_resource(MyCounter { counter: 0 });
426    /// ```
427    pub fn insert_non_send_resource<R: 'static>(&mut self, resource: R) -> &mut Self {
428        self.world_mut().insert_non_send_resource(resource);
429        self
430    }
431
432    /// Inserts the [`!Send`](Send) resource into the app if there is no existing instance of `R`.
433    ///
434    /// `R` must implement [`FromWorld`].
435    /// If `R` implements [`Default`], [`FromWorld`] will be automatically implemented and
436    /// initialize the [`Resource`] with [`Default::default`].
437    pub fn init_non_send_resource<R: 'static + FromWorld>(&mut self) -> &mut Self {
438        self.world_mut().init_non_send_resource::<R>();
439        self
440    }
441
442    pub(crate) fn add_boxed_plugin(
443        &mut self,
444        plugin: Box<dyn Plugin>,
445    ) -> Result<&mut Self, AppError> {
446        debug!("added plugin: {}", plugin.name());
447        if plugin.is_unique() && self.main_mut().plugin_names.contains(plugin.name()) {
448            Err(AppError::DuplicatePlugin {
449                plugin_name: plugin.name().to_string(),
450            })?;
451        }
452
453        // Reserve position in the plugin registry. If the plugin adds more plugins,
454        // they'll all end up in insertion order.
455        let index = self.main().plugin_registry.len();
456        self.main_mut()
457            .plugin_registry
458            .push(Box::new(PlaceholderPlugin));
459
460        self.main_mut().plugin_build_depth += 1;
461        let result = catch_unwind(AssertUnwindSafe(|| plugin.build(self)));
462        self.main_mut()
463            .plugin_names
464            .insert(plugin.name().to_string());
465        self.main_mut().plugin_build_depth -= 1;
466
467        if let Err(payload) = result {
468            resume_unwind(payload);
469        }
470
471        self.main_mut().plugin_registry[index] = plugin;
472        Ok(self)
473    }
474
475    /// Returns `true` if the [`Plugin`] has already been added.
476    pub fn is_plugin_added<T>(&self) -> bool
477    where
478        T: Plugin,
479    {
480        self.main().is_plugin_added::<T>()
481    }
482
483    /// Returns a vector of references to all plugins of type `T` that have been added.
484    ///
485    /// This can be used to read the settings of any existing plugins.
486    /// This vector will be empty if no plugins of that type have been added.
487    /// If multiple copies of the same plugin are added to the [`App`], they will be listed in insertion order in this vector.
488    ///
489    /// ```
490    /// # use bevy_app::prelude::*;
491    /// # #[derive(Default)]
492    /// # struct ImagePlugin {
493    /// #    default_sampler: bool,
494    /// # }
495    /// # impl Plugin for ImagePlugin {
496    /// #    fn build(&self, app: &mut App) {}
497    /// # }
498    /// # let mut app = App::new();
499    /// # app.add_plugins(ImagePlugin::default());
500    /// let default_sampler = app.get_added_plugins::<ImagePlugin>()[0].default_sampler;
501    /// ```
502    pub fn get_added_plugins<T>(&self) -> Vec<&T>
503    where
504        T: Plugin,
505    {
506        self.main().get_added_plugins::<T>()
507    }
508
509    /// Installs a [`Plugin`] collection.
510    ///
511    /// Bevy prioritizes modularity as a core principle. **All** engine features are implemented
512    /// as plugins, even the complex ones like rendering.
513    ///
514    /// [`Plugin`]s can be grouped into a set by using a [`PluginGroup`].
515    ///
516    /// There are built-in [`PluginGroup`]s that provide core engine functionality.
517    /// The [`PluginGroup`]s available by default are `DefaultPlugins` and `MinimalPlugins`.
518    ///
519    /// To customize the plugins in the group (reorder, disable a plugin, add a new plugin
520    /// before / after another plugin), call [`build()`](super::PluginGroup::build) on the group,
521    /// which will convert it to a [`PluginGroupBuilder`](crate::PluginGroupBuilder).
522    ///
523    /// You can also specify a group of [`Plugin`]s by using a tuple over [`Plugin`]s and
524    /// [`PluginGroup`]s. See [`Plugins`] for more details.
525    ///
526    /// ## Examples
527    /// ```
528    /// # use bevy_app::{prelude::*, PluginGroupBuilder, NoopPluginGroup as MinimalPlugins};
529    /// #
530    /// # // Dummies created to avoid using `bevy_log`,
531    /// # // which pulls in too many dependencies and breaks rust-analyzer
532    /// # pub struct LogPlugin;
533    /// # impl Plugin for LogPlugin {
534    /// #     fn build(&self, app: &mut App) {}
535    /// # }
536    /// App::new()
537    ///     .add_plugins(MinimalPlugins);
538    /// App::new()
539    ///     .add_plugins((MinimalPlugins, LogPlugin));
540    /// ```
541    ///
542    /// # Panics
543    ///
544    /// Panics if one of the plugins had already been added to the application.
545    ///
546    /// [`PluginGroup`]:super::PluginGroup
547    #[track_caller]
548    pub fn add_plugins<M>(&mut self, plugins: impl Plugins<M>) -> &mut Self {
549        if matches!(
550            self.plugins_state(),
551            PluginsState::Cleaned | PluginsState::Finished
552        ) {
553            panic!(
554                "Plugins cannot be added after App::cleanup() or App::finish() has been called."
555            );
556        }
557        plugins.add_to_app(self);
558        self
559    }
560
561    /// Registers the type `T` in the [`AppTypeRegistry`] resource,
562    /// adding reflect data as specified in the [`Reflect`](bevy_reflect::Reflect) derive:
563    /// ```ignore (No serde "derive" feature)
564    /// #[derive(Component, Serialize, Deserialize, Reflect)]
565    /// #[reflect(Component, Serialize, Deserialize)] // will register ReflectComponent, ReflectSerialize, ReflectDeserialize
566    /// ```
567    ///
568    /// See [`bevy_reflect::TypeRegistry::register`] for more information.
569    #[cfg(feature = "bevy_reflect")]
570    pub fn register_type<T: bevy_reflect::GetTypeRegistration>(&mut self) -> &mut Self {
571        self.main_mut().register_type::<T>();
572        self
573    }
574
575    /// Associates type data `D` with type `T` in the [`AppTypeRegistry`] resource.
576    ///
577    /// Most of the time [`register_type`](Self::register_type) can be used instead to register a
578    /// type you derived [`Reflect`](bevy_reflect::Reflect) for. However, in cases where you want to
579    /// add a piece of type data that was not included in the list of `#[reflect(...)]` type data in
580    /// the derive, or where the type is generic and cannot register e.g. `ReflectSerialize`
581    /// unconditionally without knowing the specific type parameters, this method can be used to
582    /// insert additional type data.
583    ///
584    /// # Example
585    /// ```
586    /// use bevy_app::App;
587    /// use bevy_reflect::{ReflectSerialize, ReflectDeserialize};
588    ///
589    /// App::new()
590    ///     .register_type::<Option<String>>()
591    ///     .register_type_data::<Option<String>, ReflectSerialize>()
592    ///     .register_type_data::<Option<String>, ReflectDeserialize>();
593    /// ```
594    ///
595    /// See [`bevy_reflect::TypeRegistry::register_type_data`].
596    #[cfg(feature = "bevy_reflect")]
597    pub fn register_type_data<
598        T: bevy_reflect::Reflect + bevy_reflect::TypePath,
599        D: bevy_reflect::TypeData + bevy_reflect::FromType<T>,
600    >(
601        &mut self,
602    ) -> &mut Self {
603        self.main_mut().register_type_data::<T, D>();
604        self
605    }
606
607    /// Registers the given function into the [`AppFunctionRegistry`] resource.
608    ///
609    /// The given function will internally be stored as a [`DynamicFunction`]
610    /// and mapped according to its [name].
611    ///
612    /// Because the function must have a name,
613    /// anonymous functions (e.g. `|a: i32, b: i32| { a + b }`) and closures must instead
614    /// be registered using [`register_function_with_name`] or converted to a [`DynamicFunction`]
615    /// and named using [`DynamicFunction::with_name`].
616    /// Failure to do so will result in a panic.
617    ///
618    /// Only types that implement [`IntoFunction`] may be registered via this method.
619    ///
620    /// See [`FunctionRegistry::register`] for more information.
621    ///
622    /// # Panics
623    ///
624    /// Panics if a function has already been registered with the given name
625    /// or if the function is missing a name (such as when it is an anonymous function).
626    ///
627    /// # Examples
628    ///
629    /// ```
630    /// use bevy_app::App;
631    ///
632    /// fn add(a: i32, b: i32) -> i32 {
633    ///     a + b
634    /// }
635    ///
636    /// App::new().register_function(add);
637    /// ```
638    ///
639    /// Functions cannot be registered more than once.
640    ///
641    /// ```should_panic
642    /// use bevy_app::App;
643    ///
644    /// fn add(a: i32, b: i32) -> i32 {
645    ///     a + b
646    /// }
647    ///
648    /// App::new()
649    ///     .register_function(add)
650    ///     // Panic! A function has already been registered with the name "my_function"
651    ///     .register_function(add);
652    /// ```
653    ///
654    /// Anonymous functions and closures should be registered using [`register_function_with_name`] or given a name using [`DynamicFunction::with_name`].
655    ///
656    /// ```should_panic
657    /// use bevy_app::App;
658    ///
659    /// // Panic! Anonymous functions cannot be registered using `register_function`
660    /// App::new().register_function(|a: i32, b: i32| a + b);
661    /// ```
662    ///
663    /// [`register_function_with_name`]: Self::register_function_with_name
664    /// [`DynamicFunction`]: bevy_reflect::func::DynamicFunction
665    /// [name]: bevy_reflect::func::FunctionInfo::name
666    /// [`DynamicFunction::with_name`]: bevy_reflect::func::DynamicFunction::with_name
667    /// [`IntoFunction`]: bevy_reflect::func::IntoFunction
668    /// [`FunctionRegistry::register`]: bevy_reflect::func::FunctionRegistry::register
669    #[cfg(feature = "reflect_functions")]
670    pub fn register_function<F, Marker>(&mut self, function: F) -> &mut Self
671    where
672        F: bevy_reflect::func::IntoFunction<'static, Marker> + 'static,
673    {
674        self.main_mut().register_function(function);
675        self
676    }
677
678    /// Registers the given function or closure into the [`AppFunctionRegistry`] resource using the given name.
679    ///
680    /// To avoid conflicts, it's recommended to use a unique name for the function.
681    /// This can be achieved by "namespacing" the function with a unique identifier,
682    /// such as the name of your crate.
683    ///
684    /// For example, to register a function, `add`, from a crate, `my_crate`,
685    /// you could use the name, `"my_crate::add"`.
686    ///
687    /// Another approach could be to use the [type name] of the function,
688    /// however, it should be noted that anonymous functions do _not_ have unique type names.
689    ///
690    /// For named functions (e.g. `fn add(a: i32, b: i32) -> i32 { a + b }`) where a custom name is not needed,
691    /// it's recommended to use [`register_function`] instead as the generated name is guaranteed to be unique.
692    ///
693    /// Only types that implement [`IntoFunction`] may be registered via this method.
694    ///
695    /// See [`FunctionRegistry::register_with_name`] for more information.
696    ///
697    /// # Panics
698    ///
699    /// Panics if a function has already been registered with the given name.
700    ///
701    /// # Examples
702    ///
703    /// ```
704    /// use bevy_app::App;
705    ///
706    /// fn mul(a: i32, b: i32) -> i32 {
707    ///     a * b
708    /// }
709    ///
710    /// let div = |a: i32, b: i32| a / b;
711    ///
712    /// App::new()
713    ///     // Registering an anonymous function with a unique name
714    ///     .register_function_with_name("my_crate::add", |a: i32, b: i32| {
715    ///         a + b
716    ///     })
717    ///     // Registering an existing function with its type name
718    ///     .register_function_with_name(std::any::type_name_of_val(&mul), mul)
719    ///     // Registering an existing function with a custom name
720    ///     .register_function_with_name("my_crate::mul", mul)
721    ///     // Be careful not to register anonymous functions with their type name.
722    ///     // This code works but registers the function with a non-unique name like `foo::bar::{{closure}}`
723    ///     .register_function_with_name(std::any::type_name_of_val(&div), div);
724    /// ```
725    ///
726    /// Names must be unique.
727    ///
728    /// ```should_panic
729    /// use bevy_app::App;
730    ///
731    /// fn one() {}
732    /// fn two() {}
733    ///
734    /// App::new()
735    ///     .register_function_with_name("my_function", one)
736    ///     // Panic! A function has already been registered with the name "my_function"
737    ///     .register_function_with_name("my_function", two);
738    /// ```
739    ///
740    /// [type name]: std::any::type_name
741    /// [`register_function`]: Self::register_function
742    /// [`IntoFunction`]: bevy_reflect::func::IntoFunction
743    /// [`FunctionRegistry::register_with_name`]: bevy_reflect::func::FunctionRegistry::register_with_name
744    #[cfg(feature = "reflect_functions")]
745    pub fn register_function_with_name<F, Marker>(
746        &mut self,
747        name: impl Into<alloc::borrow::Cow<'static, str>>,
748        function: F,
749    ) -> &mut Self
750    where
751        F: bevy_reflect::func::IntoFunction<'static, Marker> + 'static,
752    {
753        self.main_mut().register_function_with_name(name, function);
754        self
755    }
756
757    /// Registers the given component `R` as a [required component] for `T`.
758    ///
759    /// When `T` is added to an entity, `R` and its own required components will also be added
760    /// if `R` was not already provided. The [`Default`] `constructor` will be used for the creation of `R`.
761    /// If a custom constructor is desired, use [`App::register_required_components_with`] instead.
762    ///
763    /// For the non-panicking version, see [`App::try_register_required_components`].
764    ///
765    /// Note that requirements must currently be registered before `T` is inserted into the world
766    /// for the first time. Commonly, this is done in plugins. This limitation may be fixed in the future.
767    ///
768    /// [required component]: Component#required-components
769    ///
770    /// # Panics
771    ///
772    /// Panics if `R` is already a directly required component for `T`, or if `T` has ever been added
773    /// on an entity before the registration.
774    ///
775    /// Indirect requirements through other components are allowed. In those cases, any existing requirements
776    /// will only be overwritten if the new requirement is more specific.
777    ///
778    /// # Example
779    ///
780    /// ```
781    /// # use bevy_app::{App, NoopPluginGroup as MinimalPlugins, Startup};
782    /// # use bevy_ecs::prelude::*;
783    /// #[derive(Component)]
784    /// struct A;
785    ///
786    /// #[derive(Component, Default, PartialEq, Eq, Debug)]
787    /// struct B(usize);
788    ///
789    /// #[derive(Component, Default, PartialEq, Eq, Debug)]
790    /// struct C(u32);
791    ///
792    /// # let mut app = App::new();
793    /// # app.add_plugins(MinimalPlugins).add_systems(Startup, setup);
794    /// // Register B as required by A and C as required by B.
795    /// app.register_required_components::<A, B>();
796    /// app.register_required_components::<B, C>();
797    ///
798    /// fn setup(mut commands: Commands) {
799    ///     // This will implicitly also insert B and C with their Default constructors.
800    ///     commands.spawn(A);
801    /// }
802    ///
803    /// fn validate(query: Option<Single<(&A, &B, &C)>>) {
804    ///     let (a, b, c) = query.unwrap().into_inner();
805    ///     assert_eq!(b, &B(0));
806    ///     assert_eq!(c, &C(0));
807    /// }
808    /// # app.update();
809    /// ```
810    pub fn register_required_components<T: Component, R: Component + Default>(
811        &mut self,
812    ) -> &mut Self {
813        self.world_mut().register_required_components::<T, R>();
814        self
815    }
816
817    /// Registers the given component `R` as a [required component] for `T`.
818    ///
819    /// When `T` is added to an entity, `R` and its own required components will also be added
820    /// if `R` was not already provided. The given `constructor` will be used for the creation of `R`.
821    /// If a [`Default`] constructor is desired, use [`App::register_required_components`] instead.
822    ///
823    /// For the non-panicking version, see [`App::try_register_required_components_with`].
824    ///
825    /// Note that requirements must currently be registered before `T` is inserted into the world
826    /// for the first time. Commonly, this is done in plugins. This limitation may be fixed in the future.
827    ///
828    /// [required component]: Component#required-components
829    ///
830    /// # Panics
831    ///
832    /// Panics if `R` is already a directly required component for `T`, or if `T` has ever been added
833    /// on an entity before the registration.
834    ///
835    /// Indirect requirements through other components are allowed. In those cases, any existing requirements
836    /// will only be overwritten if the new requirement is more specific.
837    ///
838    /// # Example
839    ///
840    /// ```
841    /// # use bevy_app::{App, NoopPluginGroup as MinimalPlugins, Startup};
842    /// # use bevy_ecs::prelude::*;
843    /// #[derive(Component)]
844    /// struct A;
845    ///
846    /// #[derive(Component, Default, PartialEq, Eq, Debug)]
847    /// struct B(usize);
848    ///
849    /// #[derive(Component, Default, PartialEq, Eq, Debug)]
850    /// struct C(u32);
851    ///
852    /// # let mut app = App::new();
853    /// # app.add_plugins(MinimalPlugins).add_systems(Startup, setup);
854    /// // Register B and C as required by A and C as required by B.
855    /// // A requiring C directly will overwrite the indirect requirement through B.
856    /// app.register_required_components::<A, B>();
857    /// app.register_required_components_with::<B, C>(|| C(1));
858    /// app.register_required_components_with::<A, C>(|| C(2));
859    ///
860    /// fn setup(mut commands: Commands) {
861    ///     // This will implicitly also insert B with its Default constructor and C
862    ///     // with the custom constructor defined by A.
863    ///     commands.spawn(A);
864    /// }
865    ///
866    /// fn validate(query: Option<Single<(&A, &B, &C)>>) {
867    ///     let (a, b, c) = query.unwrap().into_inner();
868    ///     assert_eq!(b, &B(0));
869    ///     assert_eq!(c, &C(2));
870    /// }
871    /// # app.update();
872    /// ```
873    pub fn register_required_components_with<T: Component, R: Component>(
874        &mut self,
875        constructor: fn() -> R,
876    ) -> &mut Self {
877        self.world_mut()
878            .register_required_components_with::<T, R>(constructor);
879        self
880    }
881
882    /// Tries to register the given component `R` as a [required component] for `T`.
883    ///
884    /// When `T` is added to an entity, `R` and its own required components will also be added
885    /// if `R` was not already provided. The [`Default`] `constructor` will be used for the creation of `R`.
886    /// If a custom constructor is desired, use [`App::register_required_components_with`] instead.
887    ///
888    /// For the panicking version, see [`App::register_required_components`].
889    ///
890    /// Note that requirements must currently be registered before `T` is inserted into the world
891    /// for the first time. Commonly, this is done in plugins. This limitation may be fixed in the future.
892    ///
893    /// [required component]: Component#required-components
894    ///
895    /// # Errors
896    ///
897    /// Returns a [`RequiredComponentsError`] if `R` is already a directly required component for `T`, or if `T` has ever been added
898    /// on an entity before the registration.
899    ///
900    /// Indirect requirements through other components are allowed. In those cases, any existing requirements
901    /// will only be overwritten if the new requirement is more specific.
902    ///
903    /// # Example
904    ///
905    /// ```
906    /// # use bevy_app::{App, NoopPluginGroup as MinimalPlugins, Startup};
907    /// # use bevy_ecs::prelude::*;
908    /// #[derive(Component)]
909    /// struct A;
910    ///
911    /// #[derive(Component, Default, PartialEq, Eq, Debug)]
912    /// struct B(usize);
913    ///
914    /// #[derive(Component, Default, PartialEq, Eq, Debug)]
915    /// struct C(u32);
916    ///
917    /// # let mut app = App::new();
918    /// # app.add_plugins(MinimalPlugins).add_systems(Startup, setup);
919    /// // Register B as required by A and C as required by B.
920    /// app.register_required_components::<A, B>();
921    /// app.register_required_components::<B, C>();
922    ///
923    /// // Duplicate registration! This will fail.
924    /// assert!(app.try_register_required_components::<A, B>().is_err());
925    ///
926    /// fn setup(mut commands: Commands) {
927    ///     // This will implicitly also insert B and C with their Default constructors.
928    ///     commands.spawn(A);
929    /// }
930    ///
931    /// fn validate(query: Option<Single<(&A, &B, &C)>>) {
932    ///     let (a, b, c) = query.unwrap().into_inner();
933    ///     assert_eq!(b, &B(0));
934    ///     assert_eq!(c, &C(0));
935    /// }
936    /// # app.update();
937    /// ```
938    pub fn try_register_required_components<T: Component, R: Component + Default>(
939        &mut self,
940    ) -> Result<(), RequiredComponentsError> {
941        self.world_mut().try_register_required_components::<T, R>()
942    }
943
944    /// Tries to register the given component `R` as a [required component] for `T`.
945    ///
946    /// When `T` is added to an entity, `R` and its own required components will also be added
947    /// if `R` was not already provided. The given `constructor` will be used for the creation of `R`.
948    /// If a [`Default`] constructor is desired, use [`App::register_required_components`] instead.
949    ///
950    /// For the panicking version, see [`App::register_required_components_with`].
951    ///
952    /// Note that requirements must currently be registered before `T` is inserted into the world
953    /// for the first time. Commonly, this is done in plugins. This limitation may be fixed in the future.
954    ///
955    /// [required component]: Component#required-components
956    ///
957    /// # Errors
958    ///
959    /// Returns a [`RequiredComponentsError`] if `R` is already a directly required component for `T`, or if `T` has ever been added
960    /// on an entity before the registration.
961    ///
962    /// Indirect requirements through other components are allowed. In those cases, any existing requirements
963    /// will only be overwritten if the new requirement is more specific.
964    ///
965    /// # Example
966    ///
967    /// ```
968    /// # use bevy_app::{App, NoopPluginGroup as MinimalPlugins, Startup};
969    /// # use bevy_ecs::prelude::*;
970    /// #[derive(Component)]
971    /// struct A;
972    ///
973    /// #[derive(Component, Default, PartialEq, Eq, Debug)]
974    /// struct B(usize);
975    ///
976    /// #[derive(Component, Default, PartialEq, Eq, Debug)]
977    /// struct C(u32);
978    ///
979    /// # let mut app = App::new();
980    /// # app.add_plugins(MinimalPlugins).add_systems(Startup, setup);
981    /// // Register B and C as required by A and C as required by B.
982    /// // A requiring C directly will overwrite the indirect requirement through B.
983    /// app.register_required_components::<A, B>();
984    /// app.register_required_components_with::<B, C>(|| C(1));
985    /// app.register_required_components_with::<A, C>(|| C(2));
986    ///
987    /// // Duplicate registration! Even if the constructors were different, this would fail.
988    /// assert!(app.try_register_required_components_with::<B, C>(|| C(1)).is_err());
989    ///
990    /// fn setup(mut commands: Commands) {
991    ///     // This will implicitly also insert B with its Default constructor and C
992    ///     // with the custom constructor defined by A.
993    ///     commands.spawn(A);
994    /// }
995    ///
996    /// fn validate(query: Option<Single<(&A, &B, &C)>>) {
997    ///     let (a, b, c) = query.unwrap().into_inner();
998    ///     assert_eq!(b, &B(0));
999    ///     assert_eq!(c, &C(2));
1000    /// }
1001    /// # app.update();
1002    /// ```
1003    pub fn try_register_required_components_with<T: Component, R: Component>(
1004        &mut self,
1005        constructor: fn() -> R,
1006    ) -> Result<(), RequiredComponentsError> {
1007        self.world_mut()
1008            .try_register_required_components_with::<T, R>(constructor)
1009    }
1010
1011    /// Returns a reference to the main [`SubApp`]'s [`World`]. This is the same as calling
1012    /// [`app.main().world()`].
1013    ///
1014    /// [`app.main().world()`]: SubApp::world
1015    pub fn world(&self) -> &World {
1016        self.main().world()
1017    }
1018
1019    /// Returns a mutable reference to the main [`SubApp`]'s [`World`]. This is the same as calling
1020    /// [`app.main_mut().world_mut()`].
1021    ///
1022    /// [`app.main_mut().world_mut()`]: SubApp::world_mut
1023    pub fn world_mut(&mut self) -> &mut World {
1024        self.main_mut().world_mut()
1025    }
1026
1027    /// Returns a reference to the main [`SubApp`].
1028    pub fn main(&self) -> &SubApp {
1029        &self.sub_apps.main
1030    }
1031
1032    /// Returns a mutable reference to the main [`SubApp`].
1033    pub fn main_mut(&mut self) -> &mut SubApp {
1034        &mut self.sub_apps.main
1035    }
1036
1037    /// Returns a reference to the [`SubApp`] with the given label.
1038    ///
1039    /// # Panics
1040    ///
1041    /// Panics if the [`SubApp`] doesn't exist.
1042    pub fn sub_app(&self, label: impl AppLabel) -> &SubApp {
1043        let str = label.intern();
1044        self.get_sub_app(label).unwrap_or_else(|| {
1045            panic!("No sub-app with label '{:?}' exists.", str);
1046        })
1047    }
1048
1049    /// Returns a reference to the [`SubApp`] with the given label.
1050    ///
1051    /// # Panics
1052    ///
1053    /// Panics if the [`SubApp`] doesn't exist.
1054    pub fn sub_app_mut(&mut self, label: impl AppLabel) -> &mut SubApp {
1055        let str = label.intern();
1056        self.get_sub_app_mut(label).unwrap_or_else(|| {
1057            panic!("No sub-app with label '{:?}' exists.", str);
1058        })
1059    }
1060
1061    /// Returns a reference to the [`SubApp`] with the given label, if it exists.
1062    pub fn get_sub_app(&self, label: impl AppLabel) -> Option<&SubApp> {
1063        self.sub_apps.sub_apps.get(&label.intern())
1064    }
1065
1066    /// Returns a mutable reference to the [`SubApp`] with the given label, if it exists.
1067    pub fn get_sub_app_mut(&mut self, label: impl AppLabel) -> Option<&mut SubApp> {
1068        self.sub_apps.sub_apps.get_mut(&label.intern())
1069    }
1070
1071    /// Inserts a [`SubApp`] with the given label.
1072    pub fn insert_sub_app(&mut self, label: impl AppLabel, sub_app: SubApp) {
1073        self.sub_apps.sub_apps.insert(label.intern(), sub_app);
1074    }
1075
1076    /// Removes the [`SubApp`] with the given label, if it exists.
1077    pub fn remove_sub_app(&mut self, label: impl AppLabel) -> Option<SubApp> {
1078        self.sub_apps.sub_apps.remove(&label.intern())
1079    }
1080
1081    /// Extract data from the main world into the [`SubApp`] with the given label and perform an update if it exists.
1082    pub fn update_sub_app_by_label(&mut self, label: impl AppLabel) {
1083        self.sub_apps.update_subapp_by_label(label);
1084    }
1085
1086    /// Inserts a new `schedule` under the provided `label`, overwriting any existing
1087    /// schedule with the same label.
1088    pub fn add_schedule(&mut self, schedule: Schedule) -> &mut Self {
1089        self.main_mut().add_schedule(schedule);
1090        self
1091    }
1092
1093    /// Initializes an empty `schedule` under the provided `label`, if it does not exist.
1094    ///
1095    /// See [`add_schedule`](Self::add_schedule) to insert an existing schedule.
1096    pub fn init_schedule(&mut self, label: impl ScheduleLabel) -> &mut Self {
1097        self.main_mut().init_schedule(label);
1098        self
1099    }
1100
1101    /// Returns a reference to the [`Schedule`] with the provided `label` if it exists.
1102    pub fn get_schedule(&self, label: impl ScheduleLabel) -> Option<&Schedule> {
1103        self.main().get_schedule(label)
1104    }
1105
1106    /// Returns a mutable reference to the [`Schedule`] with the provided `label` if it exists.
1107    pub fn get_schedule_mut(&mut self, label: impl ScheduleLabel) -> Option<&mut Schedule> {
1108        self.main_mut().get_schedule_mut(label)
1109    }
1110
1111    /// Runs function `f` with the [`Schedule`] associated with `label`.
1112    ///
1113    /// **Note:** This will create the schedule if it does not already exist.
1114    pub fn edit_schedule(
1115        &mut self,
1116        label: impl ScheduleLabel,
1117        f: impl FnMut(&mut Schedule),
1118    ) -> &mut Self {
1119        self.main_mut().edit_schedule(label, f);
1120        self
1121    }
1122
1123    /// Applies the provided [`ScheduleBuildSettings`] to all schedules.
1124    pub fn configure_schedules(
1125        &mut self,
1126        schedule_build_settings: ScheduleBuildSettings,
1127    ) -> &mut Self {
1128        self.main_mut().configure_schedules(schedule_build_settings);
1129        self
1130    }
1131
1132    /// When doing [ambiguity checking](ScheduleBuildSettings) this
1133    /// ignores systems that are ambiguous on [`Component`] T.
1134    ///
1135    /// This settings only applies to the main world. To apply this to other worlds call the
1136    /// [corresponding method](World::allow_ambiguous_component) on World
1137    ///
1138    /// ## Example
1139    ///
1140    /// ```
1141    /// # use bevy_app::prelude::*;
1142    /// # use bevy_ecs::prelude::*;
1143    /// # use bevy_ecs::schedule::{LogLevel, ScheduleBuildSettings};
1144    /// # use bevy_utils::default;
1145    ///
1146    /// #[derive(Component)]
1147    /// struct A;
1148    ///
1149    /// // these systems are ambiguous on A
1150    /// fn system_1(_: Query<&mut A>) {}
1151    /// fn system_2(_: Query<&A>) {}
1152    ///
1153    /// let mut app = App::new();
1154    /// app.configure_schedules(ScheduleBuildSettings {
1155    ///   ambiguity_detection: LogLevel::Error,
1156    ///   ..default()
1157    /// });
1158    ///
1159    /// app.add_systems(Update, ( system_1, system_2 ));
1160    /// app.allow_ambiguous_component::<A>();
1161    ///
1162    /// // running the app does not error.
1163    /// app.update();
1164    /// ```
1165    pub fn allow_ambiguous_component<T: Component>(&mut self) -> &mut Self {
1166        self.main_mut().allow_ambiguous_component::<T>();
1167        self
1168    }
1169
1170    /// When doing [ambiguity checking](ScheduleBuildSettings) this
1171    /// ignores systems that are ambiguous on [`Resource`] T.
1172    ///
1173    /// This settings only applies to the main world. To apply this to other worlds call the
1174    /// [corresponding method](World::allow_ambiguous_resource) on World
1175    ///
1176    /// ## Example
1177    ///
1178    /// ```
1179    /// # use bevy_app::prelude::*;
1180    /// # use bevy_ecs::prelude::*;
1181    /// # use bevy_ecs::schedule::{LogLevel, ScheduleBuildSettings};
1182    /// # use bevy_utils::default;
1183    ///
1184    /// #[derive(Resource)]
1185    /// struct R;
1186    ///
1187    /// // these systems are ambiguous on R
1188    /// fn system_1(_: ResMut<R>) {}
1189    /// fn system_2(_: Res<R>) {}
1190    ///
1191    /// let mut app = App::new();
1192    /// app.configure_schedules(ScheduleBuildSettings {
1193    ///   ambiguity_detection: LogLevel::Error,
1194    ///   ..default()
1195    /// });
1196    /// app.insert_resource(R);
1197    ///
1198    /// app.add_systems(Update, ( system_1, system_2 ));
1199    /// app.allow_ambiguous_resource::<R>();
1200    ///
1201    /// // running the app does not error.
1202    /// app.update();
1203    /// ```
1204    pub fn allow_ambiguous_resource<T: Resource>(&mut self) -> &mut Self {
1205        self.main_mut().allow_ambiguous_resource::<T>();
1206        self
1207    }
1208
1209    /// Suppress warnings and errors that would result from systems in these sets having ambiguities
1210    /// (conflicting access but indeterminate order) with systems in `set`.
1211    ///
1212    /// When possible, do this directly in the `.add_systems(Update, a.ambiguous_with(b))` call.
1213    /// However, sometimes two independent plugins `A` and `B` are reported as ambiguous, which you
1214    /// can only suppress as the consumer of both.
1215    #[track_caller]
1216    pub fn ignore_ambiguity<M1, M2, S1, S2>(
1217        &mut self,
1218        schedule: impl ScheduleLabel,
1219        a: S1,
1220        b: S2,
1221    ) -> &mut Self
1222    where
1223        S1: IntoSystemSet<M1>,
1224        S2: IntoSystemSet<M2>,
1225    {
1226        self.main_mut().ignore_ambiguity(schedule, a, b);
1227        self
1228    }
1229
1230    /// Attempts to determine if an [`AppExit`] was raised since the last update.
1231    ///
1232    /// Will attempt to return the first [`Error`](AppExit::Error) it encounters.
1233    /// This should be called after every [`update()`](App::update) otherwise you risk
1234    /// dropping possible [`AppExit`] events.
1235    pub fn should_exit(&self) -> Option<AppExit> {
1236        let mut reader = EventCursor::default();
1237
1238        let events = self.world().get_resource::<Events<AppExit>>()?;
1239        let mut events = reader.read(events);
1240
1241        if events.len() != 0 {
1242            return Some(
1243                events
1244                    .find(|exit| exit.is_error())
1245                    .cloned()
1246                    .unwrap_or(AppExit::Success),
1247            );
1248        }
1249
1250        None
1251    }
1252
1253    /// Spawns an [`Observer`] entity, which will watch for and respond to the given event.
1254    ///
1255    /// # Examples
1256    ///
1257    /// ```rust
1258    /// # use bevy_app::prelude::*;
1259    /// # use bevy_ecs::prelude::*;
1260    /// # use bevy_utils::default;
1261    /// #
1262    /// # let mut app = App::new();
1263    /// #
1264    /// # #[derive(Event)]
1265    /// # struct Party {
1266    /// #   friends_allowed: bool,
1267    /// # };
1268    /// #
1269    /// # #[derive(Event)]
1270    /// # struct Invite;
1271    /// #
1272    /// # #[derive(Component)]
1273    /// # struct Friend;
1274    /// #
1275    /// // An observer system can be any system where the first parameter is a trigger
1276    /// app.add_observer(|trigger: Trigger<Party>, friends: Query<Entity, With<Friend>>, mut commands: Commands| {
1277    ///     if trigger.event().friends_allowed {
1278    ///         for friend in friends.iter() {
1279    ///             commands.trigger_targets(Invite, friend);
1280    ///         }
1281    ///     }
1282    /// });
1283    /// ```
1284    pub fn add_observer<E: Event, B: Bundle, M>(
1285        &mut self,
1286        observer: impl IntoObserverSystem<E, B, M>,
1287    ) -> &mut Self {
1288        self.world_mut().add_observer(observer);
1289        self
1290    }
1291}
1292
1293type RunnerFn = Box<dyn FnOnce(App) -> AppExit>;
1294
1295fn run_once(mut app: App) -> AppExit {
1296    while app.plugins_state() == PluginsState::Adding {
1297        #[cfg(not(target_arch = "wasm32"))]
1298        bevy_tasks::tick_global_task_pools_on_main_thread();
1299    }
1300    app.finish();
1301    app.cleanup();
1302
1303    app.update();
1304
1305    app.should_exit().unwrap_or(AppExit::Success)
1306}
1307
1308/// An event that indicates the [`App`] should exit. If one or more of these are present at the end of an update,
1309/// the [runner](App::set_runner) will end and ([maybe](App::run)) return control to the caller.
1310///
1311/// This event can be used to detect when an exit is requested. Make sure that systems listening
1312/// for this event run before the current update ends.
1313///
1314/// # Portability
1315/// 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 concerns
1316/// (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#))
1317/// we only allow error codes between 1 and [255](u8::MAX).
1318#[derive(Event, Debug, Clone, Default, PartialEq, Eq)]
1319pub enum AppExit {
1320    /// [`App`] exited without any problems.
1321    #[default]
1322    Success,
1323    /// The [`App`] experienced an unhandleable error.
1324    /// Holds the exit code we expect our app to return.
1325    Error(NonZero<u8>),
1326}
1327
1328impl AppExit {
1329    /// Creates a [`AppExit::Error`] with a error code of 1.
1330    #[must_use]
1331    pub const fn error() -> Self {
1332        Self::Error(NonZero::<u8>::MIN)
1333    }
1334
1335    /// Returns `true` if `self` is a [`AppExit::Success`].
1336    #[must_use]
1337    pub const fn is_success(&self) -> bool {
1338        matches!(self, AppExit::Success)
1339    }
1340
1341    /// Returns `true` if `self` is a [`AppExit::Error`].
1342    #[must_use]
1343    pub const fn is_error(&self) -> bool {
1344        matches!(self, AppExit::Error(_))
1345    }
1346
1347    /// Creates a [`AppExit`] from a code.
1348    ///
1349    /// When `code` is 0 a [`AppExit::Success`] is constructed otherwise a
1350    /// [`AppExit::Error`] is constructed.
1351    #[must_use]
1352    pub const fn from_code(code: u8) -> Self {
1353        match NonZero::<u8>::new(code) {
1354            Some(code) => Self::Error(code),
1355            None => Self::Success,
1356        }
1357    }
1358}
1359
1360impl From<u8> for AppExit {
1361    #[must_use]
1362    fn from(value: u8) -> Self {
1363        Self::from_code(value)
1364    }
1365}
1366
1367impl Termination for AppExit {
1368    fn report(self) -> ExitCode {
1369        match self {
1370            AppExit::Success => ExitCode::SUCCESS,
1371            // We leave logging an error to our users
1372            AppExit::Error(value) => ExitCode::from(value.get()),
1373        }
1374    }
1375}
1376
1377#[cfg(test)]
1378mod tests {
1379    use core::{iter, marker::PhantomData};
1380    use std::sync::Mutex;
1381
1382    use bevy_ecs::{
1383        change_detection::{DetectChanges, ResMut},
1384        component::Component,
1385        entity::Entity,
1386        event::{Event, EventWriter, Events},
1387        query::With,
1388        removal_detection::RemovedComponents,
1389        schedule::{IntoSystemConfigs, ScheduleLabel},
1390        system::{Commands, Query, Resource},
1391        world::{FromWorld, World},
1392    };
1393
1394    use crate::{App, AppExit, Plugin, SubApp, Update};
1395
1396    struct PluginA;
1397    impl Plugin for PluginA {
1398        fn build(&self, _app: &mut App) {}
1399    }
1400    struct PluginB;
1401    impl Plugin for PluginB {
1402        fn build(&self, _app: &mut App) {}
1403    }
1404    struct PluginC<T>(T);
1405    impl<T: Send + Sync + 'static> Plugin for PluginC<T> {
1406        fn build(&self, _app: &mut App) {}
1407    }
1408    struct PluginD;
1409    impl Plugin for PluginD {
1410        fn build(&self, _app: &mut App) {}
1411        fn is_unique(&self) -> bool {
1412            false
1413        }
1414    }
1415
1416    struct PluginE;
1417
1418    impl Plugin for PluginE {
1419        fn build(&self, _app: &mut App) {}
1420
1421        fn finish(&self, app: &mut App) {
1422            if app.is_plugin_added::<PluginA>() {
1423                panic!("cannot run if PluginA is already registered");
1424            }
1425        }
1426    }
1427
1428    #[test]
1429    fn can_add_two_plugins() {
1430        App::new().add_plugins((PluginA, PluginB));
1431    }
1432
1433    #[test]
1434    #[should_panic]
1435    fn cant_add_twice_the_same_plugin() {
1436        App::new().add_plugins((PluginA, PluginA));
1437    }
1438
1439    #[test]
1440    fn can_add_twice_the_same_plugin_with_different_type_param() {
1441        App::new().add_plugins((PluginC(0), PluginC(true)));
1442    }
1443
1444    #[test]
1445    fn can_add_twice_the_same_plugin_not_unique() {
1446        App::new().add_plugins((PluginD, PluginD));
1447    }
1448
1449    #[test]
1450    #[should_panic]
1451    fn cant_call_app_run_from_plugin_build() {
1452        struct PluginRun;
1453        struct InnerPlugin;
1454        impl Plugin for InnerPlugin {
1455            fn build(&self, _: &mut App) {}
1456        }
1457        impl Plugin for PluginRun {
1458            fn build(&self, app: &mut App) {
1459                app.add_plugins(InnerPlugin).run();
1460            }
1461        }
1462        App::new().add_plugins(PluginRun);
1463    }
1464
1465    #[derive(ScheduleLabel, Hash, Clone, PartialEq, Eq, Debug)]
1466    struct EnterMainMenu;
1467
1468    fn bar(mut commands: Commands) {
1469        commands.spawn_empty();
1470    }
1471
1472    fn foo(mut commands: Commands) {
1473        commands.spawn_empty();
1474    }
1475
1476    #[test]
1477    fn add_systems_should_create_schedule_if_it_does_not_exist() {
1478        let mut app = App::new();
1479        app.add_systems(EnterMainMenu, (foo, bar));
1480
1481        app.world_mut().run_schedule(EnterMainMenu);
1482        assert_eq!(app.world().entities().len(), 2);
1483    }
1484
1485    #[test]
1486    #[should_panic]
1487    fn test_is_plugin_added_works_during_finish() {
1488        let mut app = App::new();
1489        app.add_plugins(PluginA);
1490        app.add_plugins(PluginE);
1491        app.finish();
1492    }
1493
1494    #[test]
1495    fn test_derive_app_label() {
1496        use super::AppLabel;
1497        use crate::{self as bevy_app};
1498
1499        #[derive(AppLabel, Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
1500        struct UnitLabel;
1501
1502        #[derive(AppLabel, Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
1503        struct TupleLabel(u32, u32);
1504
1505        #[derive(AppLabel, Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
1506        struct StructLabel {
1507            a: u32,
1508            b: u32,
1509        }
1510
1511        #[derive(AppLabel, Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
1512        struct EmptyTupleLabel();
1513
1514        #[derive(AppLabel, Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
1515        struct EmptyStructLabel {}
1516
1517        #[derive(AppLabel, Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
1518        enum EnumLabel {
1519            #[default]
1520            Unit,
1521            Tuple(u32, u32),
1522            Struct {
1523                a: u32,
1524                b: u32,
1525            },
1526        }
1527
1528        #[derive(AppLabel, Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
1529        struct GenericLabel<T>(PhantomData<T>);
1530
1531        assert_eq!(UnitLabel.intern(), UnitLabel.intern());
1532        assert_eq!(EnumLabel::Unit.intern(), EnumLabel::Unit.intern());
1533        assert_ne!(UnitLabel.intern(), EnumLabel::Unit.intern());
1534        assert_ne!(UnitLabel.intern(), TupleLabel(0, 0).intern());
1535        assert_ne!(EnumLabel::Unit.intern(), EnumLabel::Tuple(0, 0).intern());
1536
1537        assert_eq!(TupleLabel(0, 0).intern(), TupleLabel(0, 0).intern());
1538        assert_eq!(
1539            EnumLabel::Tuple(0, 0).intern(),
1540            EnumLabel::Tuple(0, 0).intern()
1541        );
1542        assert_ne!(TupleLabel(0, 0).intern(), TupleLabel(0, 1).intern());
1543        assert_ne!(
1544            EnumLabel::Tuple(0, 0).intern(),
1545            EnumLabel::Tuple(0, 1).intern()
1546        );
1547        assert_ne!(TupleLabel(0, 0).intern(), EnumLabel::Tuple(0, 0).intern());
1548        assert_ne!(
1549            TupleLabel(0, 0).intern(),
1550            StructLabel { a: 0, b: 0 }.intern()
1551        );
1552        assert_ne!(
1553            EnumLabel::Tuple(0, 0).intern(),
1554            EnumLabel::Struct { a: 0, b: 0 }.intern()
1555        );
1556
1557        assert_eq!(
1558            StructLabel { a: 0, b: 0 }.intern(),
1559            StructLabel { a: 0, b: 0 }.intern()
1560        );
1561        assert_eq!(
1562            EnumLabel::Struct { a: 0, b: 0 }.intern(),
1563            EnumLabel::Struct { a: 0, b: 0 }.intern()
1564        );
1565        assert_ne!(
1566            StructLabel { a: 0, b: 0 }.intern(),
1567            StructLabel { a: 0, b: 1 }.intern()
1568        );
1569        assert_ne!(
1570            EnumLabel::Struct { a: 0, b: 0 }.intern(),
1571            EnumLabel::Struct { a: 0, b: 1 }.intern()
1572        );
1573        assert_ne!(
1574            StructLabel { a: 0, b: 0 }.intern(),
1575            EnumLabel::Struct { a: 0, b: 0 }.intern()
1576        );
1577        assert_ne!(
1578            StructLabel { a: 0, b: 0 }.intern(),
1579            EnumLabel::Struct { a: 0, b: 0 }.intern()
1580        );
1581        assert_ne!(StructLabel { a: 0, b: 0 }.intern(), UnitLabel.intern(),);
1582        assert_ne!(
1583            EnumLabel::Struct { a: 0, b: 0 }.intern(),
1584            EnumLabel::Unit.intern()
1585        );
1586
1587        assert_eq!(
1588            GenericLabel::<u32>(PhantomData).intern(),
1589            GenericLabel::<u32>(PhantomData).intern()
1590        );
1591        assert_ne!(
1592            GenericLabel::<u32>(PhantomData).intern(),
1593            GenericLabel::<u64>(PhantomData).intern()
1594        );
1595    }
1596
1597    #[test]
1598    fn test_update_clears_trackers_once() {
1599        #[derive(Component, Copy, Clone)]
1600        struct Foo;
1601
1602        let mut app = App::new();
1603        app.world_mut().spawn_batch(iter::repeat(Foo).take(5));
1604
1605        fn despawn_one_foo(mut commands: Commands, foos: Query<Entity, With<Foo>>) {
1606            if let Some(e) = foos.iter().next() {
1607                commands.entity(e).despawn();
1608            };
1609        }
1610        fn check_despawns(mut removed_foos: RemovedComponents<Foo>) {
1611            let mut despawn_count = 0;
1612            for _ in removed_foos.read() {
1613                despawn_count += 1;
1614            }
1615
1616            assert_eq!(despawn_count, 2);
1617        }
1618
1619        app.add_systems(Update, despawn_one_foo);
1620        app.update(); // Frame 0
1621        app.update(); // Frame 1
1622        app.add_systems(Update, check_despawns.after(despawn_one_foo));
1623        app.update(); // Should see despawns from frames 1 & 2, but not frame 0
1624    }
1625
1626    #[test]
1627    fn test_extract_sees_changes() {
1628        use super::AppLabel;
1629        use crate::{self as bevy_app};
1630
1631        #[derive(AppLabel, Clone, Copy, Hash, PartialEq, Eq, Debug)]
1632        struct MySubApp;
1633
1634        #[derive(Resource)]
1635        struct Foo(usize);
1636
1637        let mut app = App::new();
1638        app.world_mut().insert_resource(Foo(0));
1639        app.add_systems(Update, |mut foo: ResMut<Foo>| {
1640            foo.0 += 1;
1641        });
1642
1643        let mut sub_app = SubApp::new();
1644        sub_app.set_extract(|main_world, _sub_world| {
1645            assert!(main_world.get_resource_ref::<Foo>().unwrap().is_changed());
1646        });
1647
1648        app.insert_sub_app(MySubApp, sub_app);
1649
1650        app.update();
1651    }
1652
1653    #[test]
1654    fn runner_returns_correct_exit_code() {
1655        fn raise_exits(mut exits: EventWriter<AppExit>) {
1656            // Exit codes chosen by a fair dice roll.
1657            // Unlikely to overlap with default values.
1658            exits.send(AppExit::Success);
1659            exits.send(AppExit::from_code(4));
1660            exits.send(AppExit::from_code(73));
1661        }
1662
1663        let exit = App::new().add_systems(Update, raise_exits).run();
1664
1665        assert_eq!(exit, AppExit::from_code(4));
1666    }
1667
1668    /// Custom runners should be in charge of when `app::update` gets called as they may need to
1669    /// coordinate some state.
1670    /// bug: <https://github.com/bevyengine/bevy/issues/10385>
1671    /// fix: <https://github.com/bevyengine/bevy/pull/10389>
1672    #[test]
1673    fn regression_test_10385() {
1674        use super::{Res, Resource};
1675        use crate::PreUpdate;
1676
1677        #[derive(Resource)]
1678        struct MyState {}
1679
1680        fn my_runner(mut app: App) -> AppExit {
1681            let my_state = MyState {};
1682            app.world_mut().insert_resource(my_state);
1683
1684            for _ in 0..5 {
1685                app.update();
1686            }
1687
1688            AppExit::Success
1689        }
1690
1691        fn my_system(_: Res<MyState>) {
1692            // access state during app update
1693        }
1694
1695        // Should not panic due to missing resource
1696        App::new()
1697            .set_runner(my_runner)
1698            .add_systems(PreUpdate, my_system)
1699            .run();
1700    }
1701
1702    #[test]
1703    fn app_exit_size() {
1704        // There wont be many of them so the size isn't a issue but
1705        // it's nice they're so small let's keep it that way.
1706        assert_eq!(size_of::<AppExit>(), size_of::<u8>());
1707    }
1708
1709    #[test]
1710    fn initializing_resources_from_world() {
1711        #[derive(Resource)]
1712        struct TestResource;
1713        impl FromWorld for TestResource {
1714            fn from_world(_world: &mut World) -> Self {
1715                TestResource
1716            }
1717        }
1718
1719        #[derive(Resource)]
1720        struct NonSendTestResource {
1721            _marker: PhantomData<Mutex<()>>,
1722        }
1723        impl FromWorld for NonSendTestResource {
1724            fn from_world(_world: &mut World) -> Self {
1725                NonSendTestResource {
1726                    _marker: PhantomData,
1727                }
1728            }
1729        }
1730
1731        App::new()
1732            .init_non_send_resource::<NonSendTestResource>()
1733            .init_resource::<TestResource>();
1734    }
1735
1736    #[test]
1737    /// Plugin should not be considered inserted while it's being built
1738    ///
1739    /// bug: <https://github.com/bevyengine/bevy/issues/13815>
1740    fn plugin_should_not_be_added_during_build_time() {
1741        pub struct Foo;
1742
1743        impl Plugin for Foo {
1744            fn build(&self, app: &mut App) {
1745                assert!(!app.is_plugin_added::<Self>());
1746            }
1747        }
1748
1749        App::new().add_plugins(Foo);
1750    }
1751    #[test]
1752    fn events_should_be_updated_once_per_update() {
1753        #[derive(Event, Clone)]
1754        struct TestEvent;
1755
1756        let mut app = App::new();
1757        app.add_event::<TestEvent>();
1758
1759        // Starts empty
1760        let test_events = app.world().resource::<Events<TestEvent>>();
1761        assert_eq!(test_events.len(), 0);
1762        assert_eq!(test_events.iter_current_update_events().count(), 0);
1763        app.update();
1764
1765        // Sending one event
1766        app.world_mut().send_event(TestEvent);
1767
1768        let test_events = app.world().resource::<Events<TestEvent>>();
1769        assert_eq!(test_events.len(), 1);
1770        assert_eq!(test_events.iter_current_update_events().count(), 1);
1771        app.update();
1772
1773        // Sending two events on the next frame
1774        app.world_mut().send_event(TestEvent);
1775        app.world_mut().send_event(TestEvent);
1776
1777        let test_events = app.world().resource::<Events<TestEvent>>();
1778        assert_eq!(test_events.len(), 3); // Events are double-buffered, so we see 1 + 2 = 3
1779        assert_eq!(test_events.iter_current_update_events().count(), 2);
1780        app.update();
1781
1782        // Sending zero events
1783        let test_events = app.world().resource::<Events<TestEvent>>();
1784        assert_eq!(test_events.len(), 2); // Events are double-buffered, so we see 2 + 0 = 2
1785        assert_eq!(test_events.iter_current_update_events().count(), 0);
1786    }
1787}