bevy_app/
app.rs

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