Skip to main content

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