Skip to main content

bevy_app/
app.rs

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