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::{CreateTypeData, Reflect, 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 uniquely identify an [`App`].
40    /// An [`AppLabel`] should not be an enum.
41    #[diagnostic::on_unimplemented(
42        note = "consider annotating `{Self}` with `#[derive(AppLabel)]`"
43    )]
44    AppLabel,
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) data into the app, overwriting any existing data
491    /// of the same type.
492    ///
493    /// There is also an [`init_non_send`](Self::init_non_send) for [`!Send`](Send) data
494    /// that implement [`Default`]
495    ///
496    /// # Examples
497    ///
498    /// ```
499    /// # use bevy_app::prelude::*;
500    /// # use bevy_ecs::prelude::*;
501    /// #
502    /// struct MyCounter {
503    ///     counter: usize,
504    /// }
505    ///
506    /// App::new()
507    ///     .insert_non_send(MyCounter { counter: 0 });
508    /// ```
509    pub fn insert_non_send<R: 'static>(&mut self, resource: R) -> &mut Self {
510        self.world_mut().insert_non_send(resource);
511        self
512    }
513
514    /// Inserts the [`!Send`](Send) data into the app if there is no existing instance of `R`.
515    ///
516    /// `R` must implement [`FromWorld`].
517    /// If `R` implements [`Default`], [`FromWorld`] will be automatically implemented and
518    /// initialize the [`Resource`] with [`Default::default`].
519    pub fn init_non_send<R: 'static + FromWorld>(&mut self) -> &mut Self {
520        self.world_mut().init_non_send::<R>();
521        self
522    }
523
524    pub(crate) fn add_boxed_plugin(
525        &mut self,
526        plugin: Box<dyn Plugin>,
527    ) -> Result<&mut Self, AppError> {
528        debug!("added plugin: {}", plugin.name());
529        if plugin.is_unique() && self.main_mut().plugin_names.contains(plugin.name()) {
530            Err(AppError::DuplicatePlugin {
531                plugin_name: plugin.name().to_string(),
532            })?;
533        }
534
535        // Reserve position in the plugin registry. If the plugin adds more plugins,
536        // they'll all end up in insertion order.
537        let index = self.main().plugin_registry.len();
538        self.main_mut()
539            .plugin_registry
540            .push(Box::new(PlaceholderPlugin));
541
542        self.main_mut().plugin_build_depth += 1;
543
544        #[cfg(feature = "trace")]
545        let _plugin_build_span = info_span!("plugin build", plugin = plugin.name()).entered();
546
547        let f = AssertUnwindSafe(|| plugin.build(self));
548
549        #[cfg(feature = "std")]
550        let result = catch_unwind(f);
551
552        #[cfg(not(feature = "std"))]
553        f();
554
555        self.main_mut()
556            .plugin_names
557            .insert(plugin.name().to_string());
558        self.main_mut().plugin_build_depth -= 1;
559
560        #[cfg(feature = "std")]
561        if let Err(payload) = result {
562            resume_unwind(payload);
563        }
564
565        self.main_mut().plugin_registry[index] = plugin;
566        Ok(self)
567    }
568
569    /// Returns `true` if the [`Plugin`] has already been added.
570    pub fn is_plugin_added<T>(&self) -> bool
571    where
572        T: Plugin,
573    {
574        self.main().is_plugin_added::<T>()
575    }
576
577    /// Returns a vector of references to all plugins of type `T` that have been added.
578    ///
579    /// This can be used to read the settings of any existing plugins.
580    /// This vector will be empty if no plugins of that type have been added.
581    /// If multiple copies of the same plugin are added to the [`App`], they will be listed in insertion order in this vector.
582    ///
583    /// ```
584    /// # use bevy_app::prelude::*;
585    /// # #[derive(Default)]
586    /// # struct ImagePlugin {
587    /// #    default_sampler: bool,
588    /// # }
589    /// # impl Plugin for ImagePlugin {
590    /// #    fn build(&self, app: &mut App) {}
591    /// # }
592    /// # let mut app = App::new();
593    /// # app.add_plugins(ImagePlugin::default());
594    /// let default_sampler = app.get_added_plugins::<ImagePlugin>()[0].default_sampler;
595    /// ```
596    pub fn get_added_plugins<T>(&self) -> Vec<&T>
597    where
598        T: Plugin,
599    {
600        self.main().get_added_plugins::<T>()
601    }
602
603    /// Installs a [`Plugin`] collection.
604    ///
605    /// Bevy prioritizes modularity as a core principle. **All** engine features are implemented
606    /// as plugins, even the complex ones like rendering.
607    ///
608    /// [`Plugin`]s can be grouped into a set by using a [`PluginGroup`].
609    ///
610    /// There are built-in [`PluginGroup`]s that provide core engine functionality.
611    /// The [`PluginGroup`]s available by default are `DefaultPlugins` and `MinimalPlugins`.
612    ///
613    /// To customize the plugins in the group (reorder, disable a plugin, add a new plugin
614    /// before / after another plugin), call [`build()`](super::PluginGroup::build) on the group,
615    /// which will convert it to a [`PluginGroupBuilder`](crate::PluginGroupBuilder).
616    ///
617    /// You can also specify a group of [`Plugin`]s by using a tuple over [`Plugin`]s and
618    /// [`PluginGroup`]s. See [`Plugins`] for more details.
619    ///
620    /// ## Examples
621    /// ```
622    /// # use bevy_app::{prelude::*, PluginGroupBuilder, NoopPluginGroup as MinimalPlugins};
623    /// #
624    /// # // Dummies created to avoid using `bevy_log`,
625    /// # // which pulls in too many dependencies and breaks rust-analyzer
626    /// # pub struct LogPlugin;
627    /// # impl Plugin for LogPlugin {
628    /// #     fn build(&self, app: &mut App) {}
629    /// # }
630    /// App::new()
631    ///     .add_plugins(MinimalPlugins);
632    /// App::new()
633    ///     .add_plugins((MinimalPlugins, LogPlugin));
634    /// ```
635    ///
636    /// # Panics
637    ///
638    /// Panics if one of the plugins had already been added to the application.
639    ///
640    /// [`PluginGroup`]:super::PluginGroup
641    #[track_caller]
642    pub fn add_plugins<M>(&mut self, plugins: impl Plugins<M>) -> &mut Self {
643        if matches!(
644            self.plugins_state(),
645            PluginsState::Cleaned | PluginsState::Finished
646        ) {
647            panic!(
648                "Plugins cannot be added after App::cleanup() or App::finish() has been called."
649            );
650        }
651        plugins.add_to_app(self);
652        self
653    }
654
655    /// Registers the type `T` in the [`AppTypeRegistry`] resource,
656    /// adding reflect data as specified in the [`Reflect`] derive:
657    /// ```ignore (No serde "derive" feature)
658    /// #[derive(Component, Serialize, Deserialize, Reflect)]
659    /// #[reflect(Component, Serialize, Deserialize)] // will register ReflectComponent, ReflectSerialize, ReflectDeserialize
660    /// ```
661    ///
662    /// See [`bevy_reflect::TypeRegistry::register`] for more information.
663    #[cfg(feature = "bevy_reflect")]
664    pub fn register_type<T: bevy_reflect::GetTypeRegistration>(&mut self) -> &mut Self {
665        self.main_mut().register_type::<T>();
666        self
667    }
668
669    /// Associates type data `D` with type `T` in the [`AppTypeRegistry`] resource.
670    ///
671    /// Most of the time [`register_type`](Self::register_type) can be used instead to register a
672    /// type you derived [`Reflect`] for. However, in cases where you want to
673    /// add a piece of type data that was not included in the list of `#[reflect(...)]` type data in
674    /// the derive, or where the type is generic and cannot register e.g. `ReflectSerialize`
675    /// unconditionally without knowing the specific type parameters, this method can be used to
676    /// insert additional type data.
677    ///
678    /// # Example
679    /// ```
680    /// use bevy_app::App;
681    /// use bevy_reflect::{ReflectSerialize, ReflectDeserialize};
682    ///
683    /// App::new()
684    ///     .register_type::<Option<String>>()
685    ///     .register_type_data::<Option<String>, ReflectSerialize>()
686    ///     .register_type_data::<Option<String>, ReflectDeserialize>();
687    /// ```
688    ///
689    /// See [`bevy_reflect::TypeRegistry::register_type_data`].
690    #[cfg(feature = "bevy_reflect")]
691    pub fn register_type_data<T: Reflect + TypePath, D: CreateTypeData<T>>(&mut self) -> &mut Self {
692        self.main_mut().register_type_data::<T, D>();
693        self
694    }
695
696    /// Registers a fallible conversion from type T to U with the reflection
697    /// system.
698    ///
699    /// The supplied closure is expected to produce a value of type U, given an
700    /// instance of type T. If the conversion fails, the closure should return
701    /// the input value, wrapped in an `Err` variant.
702    ///
703    /// # Example
704    /// ```
705    /// use bevy_app::App;
706    ///
707    /// App::new()
708    ///     .register_type::<i32>()
709    ///     .register_type::<String>()
710    ///     .register_type_conversion::<i32, String, _>(|n| Ok(n.to_string()));
711    /// ```
712    ///
713    /// See [`bevy_reflect::TypeRegistry::register_type_conversion`].
714    #[cfg(feature = "bevy_reflect")]
715    pub fn register_type_conversion<T, U, F>(&mut self, function: F) -> &mut Self
716    where
717        T: Reflect + TypePath,
718        U: Reflect + TypePath,
719        F: Fn(T) -> Result<U, T> + Clone + Send + Sync + 'static,
720    {
721        self.main_mut().register_type_conversion(function);
722        self
723    }
724
725    /// Given types T and U, where `U: From<T>`, registers that conversion with
726    /// the reflection system.
727    ///
728    /// # Example
729    /// ```
730    /// use bevy_app::App;
731    ///
732    /// App::new()
733    ///     .register_type::<u8>()
734    ///     .register_type::<u32>()
735    ///     .register_into_type_conversion::<u8, u32>();
736    /// ```
737    ///
738    /// See [`bevy_reflect::TypeRegistry::register_into_type_conversion`].
739    #[cfg(feature = "bevy_reflect")]
740    pub fn register_into_type_conversion<T, U>(&mut self) -> &mut Self
741    where
742        T: Reflect + TypePath,
743        U: Reflect + TypePath + From<T>,
744    {
745        self.main_mut().register_into_type_conversion::<T, U>();
746        self
747    }
748
749    /// Registers the given function into the [`AppFunctionRegistry`] resource.
750    ///
751    /// The given function will internally be stored as a [`DynamicFunction`]
752    /// and mapped according to its [name].
753    ///
754    /// Because the function must have a name,
755    /// anonymous functions (e.g. `|a: i32, b: i32| { a + b }`) and closures must instead
756    /// be registered using [`register_function_with_name`] or converted to a [`DynamicFunction`]
757    /// and named using [`DynamicFunction::with_name`].
758    /// Failure to do so will result in a panic.
759    ///
760    /// Only types that implement [`IntoFunction`] may be registered via this method.
761    ///
762    /// See [`FunctionRegistry::register`] for more information.
763    ///
764    /// # Panics
765    ///
766    /// Panics if a function has already been registered with the given name
767    /// or if the function is missing a name (such as when it is an anonymous function).
768    ///
769    /// # Examples
770    ///
771    /// ```
772    /// use bevy_app::App;
773    ///
774    /// fn add(a: i32, b: i32) -> i32 {
775    ///     a + b
776    /// }
777    ///
778    /// App::new().register_function(add);
779    /// ```
780    ///
781    /// Functions cannot be registered more than once.
782    ///
783    /// ```should_panic
784    /// use bevy_app::App;
785    ///
786    /// fn add(a: i32, b: i32) -> i32 {
787    ///     a + b
788    /// }
789    ///
790    /// App::new()
791    ///     .register_function(add)
792    ///     // Panic! A function has already been registered with the name "my_function"
793    ///     .register_function(add);
794    /// ```
795    ///
796    /// Anonymous functions and closures should be registered using [`register_function_with_name`] or given a name using [`DynamicFunction::with_name`].
797    ///
798    /// ```should_panic
799    /// use bevy_app::App;
800    ///
801    /// // Panic! Anonymous functions cannot be registered using `register_function`
802    /// App::new().register_function(|a: i32, b: i32| a + b);
803    /// ```
804    ///
805    /// [`register_function_with_name`]: Self::register_function_with_name
806    /// [`DynamicFunction`]: bevy_reflect::func::DynamicFunction
807    /// [name]: bevy_reflect::func::FunctionInfo::name
808    /// [`DynamicFunction::with_name`]: bevy_reflect::func::DynamicFunction::with_name
809    /// [`IntoFunction`]: bevy_reflect::func::IntoFunction
810    /// [`FunctionRegistry::register`]: bevy_reflect::func::FunctionRegistry::register
811    #[cfg(feature = "reflect_functions")]
812    pub fn register_function<F, Marker>(&mut self, function: F) -> &mut Self
813    where
814        F: bevy_reflect::func::IntoFunction<'static, Marker> + 'static,
815    {
816        self.main_mut().register_function(function);
817        self
818    }
819
820    /// Registers the given function or closure into the [`AppFunctionRegistry`] resource using the given name.
821    ///
822    /// To avoid conflicts, it's recommended to use a unique name for the function.
823    /// This can be achieved by "namespacing" the function with a unique identifier,
824    /// such as the name of your crate.
825    ///
826    /// For example, to register a function, `add`, from a crate, `my_crate`,
827    /// you could use the name, `"my_crate::add"`.
828    ///
829    /// Another approach could be to use the [type name] of the function,
830    /// however, it should be noted that anonymous functions do _not_ have unique type names.
831    ///
832    /// For named functions (e.g. `fn add(a: i32, b: i32) -> i32 { a + b }`) where a custom name is not needed,
833    /// it's recommended to use [`register_function`] instead as the generated name is guaranteed to be unique.
834    ///
835    /// Only types that implement [`IntoFunction`] may be registered via this method.
836    ///
837    /// See [`FunctionRegistry::register_with_name`] for more information.
838    ///
839    /// # Panics
840    ///
841    /// Panics if a function has already been registered with the given name.
842    ///
843    /// # Examples
844    ///
845    /// ```
846    /// use bevy_app::App;
847    ///
848    /// fn mul(a: i32, b: i32) -> i32 {
849    ///     a * b
850    /// }
851    ///
852    /// let div = |a: i32, b: i32| a / b;
853    ///
854    /// App::new()
855    ///     // Registering an anonymous function with a unique name
856    ///     .register_function_with_name("my_crate::add", |a: i32, b: i32| {
857    ///         a + b
858    ///     })
859    ///     // Registering an existing function with its type name
860    ///     .register_function_with_name(std::any::type_name_of_val(&mul), mul)
861    ///     // Registering an existing function with a custom name
862    ///     .register_function_with_name("my_crate::mul", mul)
863    ///     // Be careful not to register anonymous functions with their type name.
864    ///     // This code works but registers the function with a non-unique name like `foo::bar::{{closure}}`
865    ///     .register_function_with_name(std::any::type_name_of_val(&div), div);
866    /// ```
867    ///
868    /// Names must be unique.
869    ///
870    /// ```should_panic
871    /// use bevy_app::App;
872    ///
873    /// fn one() {}
874    /// fn two() {}
875    ///
876    /// App::new()
877    ///     .register_function_with_name("my_function", one)
878    ///     // Panic! A function has already been registered with the name "my_function"
879    ///     .register_function_with_name("my_function", two);
880    /// ```
881    ///
882    /// [type name]: std::any::type_name
883    /// [`register_function`]: Self::register_function
884    /// [`IntoFunction`]: bevy_reflect::func::IntoFunction
885    /// [`FunctionRegistry::register_with_name`]: bevy_reflect::func::FunctionRegistry::register_with_name
886    #[cfg(feature = "reflect_functions")]
887    pub fn register_function_with_name<F, Marker>(
888        &mut self,
889        name: impl Into<alloc::borrow::Cow<'static, str>>,
890        function: F,
891    ) -> &mut Self
892    where
893        F: bevy_reflect::func::IntoFunction<'static, Marker> + 'static,
894    {
895        self.main_mut().register_function_with_name(name, function);
896        self
897    }
898
899    /// Registers the given component `R` as a [required component] for `T`.
900    ///
901    /// When `T` is added to an entity, `R` and its own required components will also be added
902    /// if `R` was not already provided. The [`Default`] `constructor` will be used for the creation of `R`.
903    /// If a custom constructor is desired, use [`App::register_required_components_with`] instead.
904    ///
905    /// For the non-panicking version, see [`App::try_register_required_components`].
906    ///
907    /// Note that requirements must currently be registered before `T` is inserted into the world
908    /// for the first time. Commonly, this is done in plugins. This limitation may be fixed in the future.
909    ///
910    /// [required component]: Component#required-components
911    ///
912    /// # Panics
913    ///
914    /// Panics if `R` is already a directly required component for `T`, or if `T` has ever been added
915    /// on an entity before the registration.
916    ///
917    /// Indirect requirements through other components are allowed. In those cases, any existing requirements
918    /// will only be overwritten if the new requirement is more specific.
919    ///
920    /// # Example
921    ///
922    /// ```
923    /// # use bevy_app::{App, NoopPluginGroup as MinimalPlugins, Startup};
924    /// # use bevy_ecs::prelude::*;
925    /// #[derive(Component)]
926    /// struct A;
927    ///
928    /// #[derive(Component, Default, PartialEq, Eq, Debug)]
929    /// struct B(usize);
930    ///
931    /// #[derive(Component, Default, PartialEq, Eq, Debug)]
932    /// struct C(u32);
933    ///
934    /// # let mut app = App::new();
935    /// # app.add_plugins(MinimalPlugins).add_systems(Startup, setup);
936    /// // Register B as required by A and C as required by B.
937    /// app.register_required_components::<A, B>();
938    /// app.register_required_components::<B, C>();
939    ///
940    /// fn setup(mut commands: Commands) {
941    ///     // This will implicitly also insert B and C with their Default constructors.
942    ///     commands.spawn(A);
943    /// }
944    ///
945    /// fn validate(query: Option<Single<(&A, &B, &C)>>) {
946    ///     let (a, b, c) = query.unwrap().into_inner();
947    ///     assert_eq!(b, &B(0));
948    ///     assert_eq!(c, &C(0));
949    /// }
950    /// # app.update();
951    /// ```
952    pub fn register_required_components<T: Component, R: Component + Default>(
953        &mut self,
954    ) -> &mut Self {
955        self.world_mut().register_required_components::<T, R>();
956        self
957    }
958
959    /// Registers the given component `R` as a [required component] for `T`.
960    ///
961    /// When `T` is added to an entity, `R` and its own required components will also be added
962    /// if `R` was not already provided. The given `constructor` will be used for the creation of `R`.
963    /// If a [`Default`] constructor is desired, use [`App::register_required_components`] instead.
964    ///
965    /// For the non-panicking version, see [`App::try_register_required_components_with`].
966    ///
967    /// Note that requirements must currently be registered before `T` is inserted into the world
968    /// for the first time. Commonly, this is done in plugins. This limitation may be fixed in the future.
969    ///
970    /// [required component]: Component#required-components
971    ///
972    /// # Panics
973    ///
974    /// Panics if `R` is already a directly required component for `T`, or if `T` has ever been added
975    /// on an entity before the registration.
976    ///
977    /// Indirect requirements through other components are allowed. In those cases, any existing requirements
978    /// will only be overwritten if the new requirement is more specific.
979    ///
980    /// # Example
981    ///
982    /// ```
983    /// # use bevy_app::{App, NoopPluginGroup as MinimalPlugins, Startup};
984    /// # use bevy_ecs::prelude::*;
985    /// #[derive(Component)]
986    /// struct A;
987    ///
988    /// #[derive(Component, Default, PartialEq, Eq, Debug)]
989    /// struct B(usize);
990    ///
991    /// #[derive(Component, Default, PartialEq, Eq, Debug)]
992    /// struct C(u32);
993    ///
994    /// # let mut app = App::new();
995    /// # app.add_plugins(MinimalPlugins).add_systems(Startup, setup);
996    /// // Register B and C as required by A and C as required by B.
997    /// // A requiring C directly will overwrite the indirect requirement through B.
998    /// app.register_required_components::<A, B>();
999    /// app.register_required_components_with::<B, C>(|| C(1));
1000    /// app.register_required_components_with::<A, C>(|| C(2));
1001    ///
1002    /// fn setup(mut commands: Commands) {
1003    ///     // This will implicitly also insert B with its Default constructor and C
1004    ///     // with the custom constructor defined by A.
1005    ///     commands.spawn(A);
1006    /// }
1007    ///
1008    /// fn validate(query: Option<Single<(&A, &B, &C)>>) {
1009    ///     let (a, b, c) = query.unwrap().into_inner();
1010    ///     assert_eq!(b, &B(0));
1011    ///     assert_eq!(c, &C(2));
1012    /// }
1013    /// # app.update();
1014    /// ```
1015    pub fn register_required_components_with<T: Component, R: Component>(
1016        &mut self,
1017        constructor: impl Fn() -> R + 'static,
1018    ) -> &mut Self {
1019        self.world_mut()
1020            .register_required_components_with::<T, R>(constructor);
1021        self
1022    }
1023
1024    /// Tries to register the given component `R` as a [required component] for `T`.
1025    ///
1026    /// When `T` is added to an entity, `R` and its own required components will also be added
1027    /// if `R` was not already provided. The [`Default`] `constructor` will be used for the creation of `R`.
1028    /// If a custom constructor is desired, use [`App::register_required_components_with`] instead.
1029    ///
1030    /// For the panicking version, see [`App::register_required_components`].
1031    ///
1032    /// Note that requirements must currently be registered before `T` is inserted into the world
1033    /// for the first time. Commonly, this is done in plugins. This limitation may be fixed in the future.
1034    ///
1035    /// [required component]: Component#required-components
1036    ///
1037    /// # Errors
1038    ///
1039    /// Returns a [`RequiredComponentsError`] if `R` is already a directly required component for `T`, or if `T` has ever been added
1040    /// on an entity before the registration.
1041    ///
1042    /// Indirect requirements through other components are allowed. In those cases, any existing requirements
1043    /// will only be overwritten if the new requirement is more specific.
1044    ///
1045    /// # Example
1046    ///
1047    /// ```
1048    /// # use bevy_app::{App, NoopPluginGroup as MinimalPlugins, Startup};
1049    /// # use bevy_ecs::prelude::*;
1050    /// #[derive(Component)]
1051    /// struct A;
1052    ///
1053    /// #[derive(Component, Default, PartialEq, Eq, Debug)]
1054    /// struct B(usize);
1055    ///
1056    /// #[derive(Component, Default, PartialEq, Eq, Debug)]
1057    /// struct C(u32);
1058    ///
1059    /// # let mut app = App::new();
1060    /// # app.add_plugins(MinimalPlugins).add_systems(Startup, setup);
1061    /// // Register B as required by A and C as required by B.
1062    /// app.register_required_components::<A, B>();
1063    /// app.register_required_components::<B, C>();
1064    ///
1065    /// // Duplicate registration! This will fail.
1066    /// assert!(app.try_register_required_components::<A, B>().is_err());
1067    ///
1068    /// fn setup(mut commands: Commands) {
1069    ///     // This will implicitly also insert B and C with their Default constructors.
1070    ///     commands.spawn(A);
1071    /// }
1072    ///
1073    /// fn validate(query: Option<Single<(&A, &B, &C)>>) {
1074    ///     let (a, b, c) = query.unwrap().into_inner();
1075    ///     assert_eq!(b, &B(0));
1076    ///     assert_eq!(c, &C(0));
1077    /// }
1078    /// # app.update();
1079    /// ```
1080    pub fn try_register_required_components<T: Component, R: Component + Default>(
1081        &mut self,
1082    ) -> Result<(), RequiredComponentsError> {
1083        self.world_mut().try_register_required_components::<T, R>()
1084    }
1085
1086    /// Tries to register the given component `R` as a [required component] for `T`.
1087    ///
1088    /// When `T` is added to an entity, `R` and its own required components will also be added
1089    /// if `R` was not already provided. The given `constructor` will be used for the creation of `R`.
1090    /// If a [`Default`] constructor is desired, use [`App::register_required_components`] instead.
1091    ///
1092    /// For the panicking version, see [`App::register_required_components_with`].
1093    ///
1094    /// Note that requirements must currently be registered before `T` is inserted into the world
1095    /// for the first time. Commonly, this is done in plugins. This limitation may be fixed in the future.
1096    ///
1097    /// [required component]: Component#required-components
1098    ///
1099    /// # Errors
1100    ///
1101    /// Returns a [`RequiredComponentsError`] if `R` is already a directly required component for `T`, or if `T` has ever been added
1102    /// on an entity before the registration.
1103    ///
1104    /// Indirect requirements through other components are allowed. In those cases, any existing requirements
1105    /// will only be overwritten if the new requirement is more specific.
1106    ///
1107    /// # Example
1108    ///
1109    /// ```
1110    /// # use bevy_app::{App, NoopPluginGroup as MinimalPlugins, Startup};
1111    /// # use bevy_ecs::prelude::*;
1112    /// #[derive(Component)]
1113    /// struct A;
1114    ///
1115    /// #[derive(Component, Default, PartialEq, Eq, Debug)]
1116    /// struct B(usize);
1117    ///
1118    /// #[derive(Component, Default, PartialEq, Eq, Debug)]
1119    /// struct C(u32);
1120    ///
1121    /// # let mut app = App::new();
1122    /// # app.add_plugins(MinimalPlugins).add_systems(Startup, setup);
1123    /// // Register B and C as required by A and C as required by B.
1124    /// // A requiring C directly will overwrite the indirect requirement through B.
1125    /// app.register_required_components::<A, B>();
1126    /// app.register_required_components_with::<B, C>(|| C(1));
1127    /// app.register_required_components_with::<A, C>(|| C(2));
1128    ///
1129    /// // Duplicate registration! Even if the constructors were different, this would fail.
1130    /// assert!(app.try_register_required_components_with::<B, C>(|| C(1)).is_err());
1131    ///
1132    /// fn setup(mut commands: Commands) {
1133    ///     // This will implicitly also insert B with its Default constructor and C
1134    ///     // with the custom constructor defined by A.
1135    ///     commands.spawn(A);
1136    /// }
1137    ///
1138    /// fn validate(query: Option<Single<(&A, &B, &C)>>) {
1139    ///     let (a, b, c) = query.unwrap().into_inner();
1140    ///     assert_eq!(b, &B(0));
1141    ///     assert_eq!(c, &C(2));
1142    /// }
1143    /// # app.update();
1144    /// ```
1145    pub fn try_register_required_components_with<T: Component, R: Component>(
1146        &mut self,
1147        constructor: impl Fn() -> R + 'static,
1148    ) -> Result<(), RequiredComponentsError> {
1149        self.world_mut()
1150            .try_register_required_components_with::<T, R>(constructor)
1151    }
1152
1153    /// Registers a component type as "disabling",
1154    /// using [default query filters](bevy_ecs::entity_disabling::DefaultQueryFilters) to exclude entities with the component from queries.
1155    ///
1156    /// # Warning
1157    ///
1158    /// As discussed in the [module docs](bevy_ecs::entity_disabling), this can have performance implications,
1159    /// as well as create interoperability issues, and should be used with caution.
1160    pub fn register_disabling_component<C: Component>(&mut self) {
1161        self.world_mut().register_disabling_component::<C>();
1162    }
1163
1164    /// Returns a reference to the main [`SubApp`]'s [`World`]. This is the same as calling
1165    /// [`app.main().world()`].
1166    ///
1167    /// [`app.main().world()`]: SubApp::world
1168    pub fn world(&self) -> &World {
1169        self.main().world()
1170    }
1171
1172    /// Returns a mutable reference to the main [`SubApp`]'s [`World`]. This is the same as calling
1173    /// [`app.main_mut().world_mut()`].
1174    ///
1175    /// [`app.main_mut().world_mut()`]: SubApp::world_mut
1176    pub fn world_mut(&mut self) -> &mut World {
1177        self.main_mut().world_mut()
1178    }
1179
1180    /// Returns a reference to the main [`SubApp`].
1181    pub fn main(&self) -> &SubApp {
1182        &self.sub_apps.main
1183    }
1184
1185    /// Returns a mutable reference to the main [`SubApp`].
1186    pub fn main_mut(&mut self) -> &mut SubApp {
1187        &mut self.sub_apps.main
1188    }
1189
1190    /// Returns a reference to the [`SubApps`] collection.
1191    pub fn sub_apps(&self) -> &SubApps {
1192        &self.sub_apps
1193    }
1194
1195    /// Returns a mutable reference to the [`SubApps`] collection.
1196    pub fn sub_apps_mut(&mut self) -> &mut SubApps {
1197        &mut self.sub_apps
1198    }
1199
1200    /// Returns a reference to the [`SubApp`] with the given label.
1201    ///
1202    /// # Panics
1203    ///
1204    /// Panics if the [`SubApp`] doesn't exist.
1205    pub fn sub_app(&self, label: impl AppLabel) -> &SubApp {
1206        let str = label.intern();
1207        self.get_sub_app(label).unwrap_or_else(|| {
1208            panic!("No sub-app with label '{:?}' exists.", str);
1209        })
1210    }
1211
1212    /// Returns a reference to the [`SubApp`] with the given label.
1213    ///
1214    /// # Panics
1215    ///
1216    /// Panics if the [`SubApp`] doesn't exist.
1217    pub fn sub_app_mut(&mut self, label: impl AppLabel) -> &mut SubApp {
1218        let str = label.intern();
1219        self.get_sub_app_mut(label).unwrap_or_else(|| {
1220            panic!("No sub-app with label '{:?}' exists.", str);
1221        })
1222    }
1223
1224    /// Returns a reference to the [`SubApp`] with the given label, if it exists.
1225    pub fn get_sub_app(&self, label: impl AppLabel) -> Option<&SubApp> {
1226        self.sub_apps.sub_apps.get(&label.intern())
1227    }
1228
1229    /// Returns a mutable reference to the [`SubApp`] with the given label, if it exists.
1230    pub fn get_sub_app_mut(&mut self, label: impl AppLabel) -> Option<&mut SubApp> {
1231        self.sub_apps.sub_apps.get_mut(&label.intern())
1232    }
1233
1234    /// Inserts a [`SubApp`] with the given label.
1235    pub fn insert_sub_app(&mut self, label: impl AppLabel, mut sub_app: SubApp) {
1236        if let Some(handler) = self.fallback_error_handler {
1237            sub_app
1238                .world_mut()
1239                .get_resource_or_insert_with(|| FallbackErrorHandler(handler));
1240        }
1241        self.sub_apps.sub_apps.insert(label.intern(), sub_app);
1242    }
1243
1244    /// Removes the [`SubApp`] with the given label, if it exists.
1245    pub fn remove_sub_app(&mut self, label: impl AppLabel) -> Option<SubApp> {
1246        self.sub_apps.sub_apps.remove(&label.intern())
1247    }
1248
1249    /// Extract data from the main world into the [`SubApp`] with the given label and perform an update if it exists.
1250    pub fn update_sub_app_by_label(&mut self, label: impl AppLabel) {
1251        self.sub_apps.update_subapp_by_label(label);
1252    }
1253
1254    /// Inserts a new `schedule` under the provided `label`, overwriting any existing
1255    /// schedule with the same label.
1256    pub fn add_schedule(&mut self, schedule: Schedule) -> &mut Self {
1257        self.main_mut().add_schedule(schedule);
1258        self
1259    }
1260
1261    /// Initializes an empty `schedule` under the provided `label`, if it does not exist.
1262    ///
1263    /// See [`add_schedule`](Self::add_schedule) to insert an existing schedule.
1264    pub fn init_schedule(&mut self, label: impl ScheduleLabel) -> &mut Self {
1265        self.main_mut().init_schedule(label);
1266        self
1267    }
1268
1269    /// Returns a reference to the [`Schedule`] with the provided `label` if it exists.
1270    pub fn get_schedule(&self, label: impl ScheduleLabel) -> Option<&Schedule> {
1271        self.main().get_schedule(label)
1272    }
1273
1274    /// Returns a mutable reference to the [`Schedule`] with the provided `label` if it exists.
1275    pub fn get_schedule_mut(&mut self, label: impl ScheduleLabel) -> Option<&mut Schedule> {
1276        self.main_mut().get_schedule_mut(label)
1277    }
1278
1279    /// Runs function `f` with the [`Schedule`] associated with `label`.
1280    ///
1281    /// **Note:** This will create the schedule if it does not already exist.
1282    pub fn edit_schedule(
1283        &mut self,
1284        label: impl ScheduleLabel,
1285        f: impl FnMut(&mut Schedule),
1286    ) -> &mut Self {
1287        self.main_mut().edit_schedule(label, f);
1288        self
1289    }
1290
1291    /// Applies the provided [`ScheduleBuildSettings`] to all schedules.
1292    ///
1293    /// This mutates all currently present schedules, but does not apply to any custom schedules
1294    /// that might be added in the future.
1295    pub fn configure_schedules(
1296        &mut self,
1297        schedule_build_settings: ScheduleBuildSettings,
1298    ) -> &mut Self {
1299        self.main_mut().configure_schedules(schedule_build_settings);
1300        self
1301    }
1302
1303    /// When doing [ambiguity checking](ScheduleBuildSettings) this
1304    /// ignores systems that are ambiguous on [`Component`] T.
1305    ///
1306    /// This settings only applies to the main world. To apply this to other worlds call the
1307    /// [corresponding method](World::allow_ambiguous_component) on World
1308    ///
1309    /// ## Example
1310    ///
1311    /// ```
1312    /// # use bevy_app::prelude::*;
1313    /// # use bevy_ecs::prelude::*;
1314    /// # use bevy_ecs::schedule::{LogLevel, ScheduleBuildSettings};
1315    /// # use bevy_utils::default;
1316    ///
1317    /// #[derive(Component)]
1318    /// struct A;
1319    ///
1320    /// // these systems are ambiguous on A
1321    /// fn system_1(_: Query<&mut A>) {}
1322    /// fn system_2(_: Query<&A>) {}
1323    ///
1324    /// let mut app = App::new();
1325    /// app.configure_schedules(ScheduleBuildSettings {
1326    ///   ambiguity_detection: LogLevel::Error,
1327    ///   ..default()
1328    /// });
1329    ///
1330    /// app.add_systems(Update, ( system_1, system_2 ));
1331    /// app.allow_ambiguous_component::<A>();
1332    ///
1333    /// // running the app does not error.
1334    /// app.update();
1335    /// ```
1336    pub fn allow_ambiguous_component<T: Component>(&mut self) -> &mut Self {
1337        self.main_mut().allow_ambiguous_component::<T>();
1338        self
1339    }
1340
1341    /// When doing [ambiguity checking](ScheduleBuildSettings) this
1342    /// ignores systems that are ambiguous on [`Resource`] T.
1343    ///
1344    /// This settings only applies to the main world. To apply this to other worlds call the
1345    /// [corresponding method](World::allow_ambiguous_resource) on World
1346    ///
1347    /// ## Example
1348    ///
1349    /// ```
1350    /// # use bevy_app::prelude::*;
1351    /// # use bevy_ecs::prelude::*;
1352    /// # use bevy_ecs::schedule::{LogLevel, ScheduleBuildSettings};
1353    /// # use bevy_utils::default;
1354    ///
1355    /// #[derive(Resource)]
1356    /// struct R;
1357    ///
1358    /// // these systems are ambiguous on R
1359    /// fn system_1(_: ResMut<R>) {}
1360    /// fn system_2(_: Res<R>) {}
1361    ///
1362    /// let mut app = App::new();
1363    /// app.configure_schedules(ScheduleBuildSettings {
1364    ///   ambiguity_detection: LogLevel::Error,
1365    ///   ..default()
1366    /// });
1367    /// app.insert_resource(R);
1368    ///
1369    /// app.add_systems(Update, ( system_1, system_2 ));
1370    /// app.allow_ambiguous_resource::<R>();
1371    ///
1372    /// // running the app does not error.
1373    /// app.update();
1374    /// ```
1375    pub fn allow_ambiguous_resource<T: Resource>(&mut self) -> &mut Self {
1376        self.main_mut().allow_ambiguous_resource::<T>();
1377        self
1378    }
1379
1380    /// Suppress warnings and errors that would result from systems in these sets having ambiguities
1381    /// (conflicting access but indeterminate order) with systems in `set`.
1382    ///
1383    /// When possible, do this directly in the `.add_systems(Update, a.ambiguous_with(b))` call.
1384    /// However, sometimes two independent plugins `A` and `B` are reported as ambiguous, which you
1385    /// can only suppress as the consumer of both.
1386    #[track_caller]
1387    pub fn ignore_ambiguity<M1, M2, S1, S2>(
1388        &mut self,
1389        schedule: impl ScheduleLabel,
1390        a: S1,
1391        b: S2,
1392    ) -> &mut Self
1393    where
1394        S1: IntoSystemSet<M1>,
1395        S2: IntoSystemSet<M2>,
1396    {
1397        self.main_mut().ignore_ambiguity(schedule, a, b);
1398        self
1399    }
1400
1401    /// Attempts to determine if an [`AppExit`] was raised since the last update.
1402    ///
1403    /// Will attempt to return the first [`Error`](AppExit::Error) it encounters.
1404    /// This should be called after every [`update()`](App::update) otherwise you risk
1405    /// dropping possible [`AppExit`] events.
1406    pub fn should_exit(&self) -> Option<AppExit> {
1407        let mut reader = MessageCursor::default();
1408
1409        let messages = self.world().get_resource::<Messages<AppExit>>()?;
1410        let mut messages = reader.read(messages);
1411
1412        if messages.len() != 0 {
1413            return Some(
1414                messages
1415                    .find(|exit| exit.is_error())
1416                    .cloned()
1417                    .unwrap_or(AppExit::Success),
1418            );
1419        }
1420
1421        None
1422    }
1423
1424    /// Spawns an [`Observer`] entity, which will watch for and respond to the given event.
1425    ///
1426    /// `observer` can be any system whose first parameter is [`On`].
1427    ///
1428    /// # Examples
1429    ///
1430    /// ```rust
1431    /// # use bevy_app::prelude::*;
1432    /// # use bevy_ecs::prelude::*;
1433    /// # use bevy_utils::default;
1434    /// #
1435    /// # let mut app = App::new();
1436    /// #
1437    /// # #[derive(Event)]
1438    /// # struct Party {
1439    /// #   friends_allowed: bool,
1440    /// # };
1441    /// #
1442    /// # #[derive(EntityEvent)]
1443    /// # struct Invite {
1444    /// #    entity: Entity,
1445    /// # }
1446    /// #
1447    /// # #[derive(Component)]
1448    /// # struct Friend;
1449    /// #
1450    ///
1451    /// app.add_observer(|event: On<Party>, friends: Query<Entity, With<Friend>>, mut commands: Commands| {
1452    ///     if event.friends_allowed {
1453    ///         for entity in friends.iter() {
1454    ///             commands.trigger(Invite { entity } );
1455    ///         }
1456    ///     }
1457    /// });
1458    /// ```
1459    pub fn add_observer<M>(&mut self, observer: impl IntoObserver<M>) -> &mut Self {
1460        self.world_mut().add_observer(observer);
1461        self
1462    }
1463
1464    /// Gets the error handler to set for new supapps.
1465    ///
1466    /// Note that the error handler of existing subapps may differ.
1467    pub fn get_error_handler(&self) -> Option<ErrorHandler> {
1468        self.fallback_error_handler
1469    }
1470
1471    /// Set the [fallback error handler] for the all subapps (including the main one and future ones)
1472    /// that do not have one.
1473    ///
1474    /// May only be called once and should be set by the application, not by libraries.
1475    ///
1476    /// The handler will be called when an error is produced and not otherwise handled.
1477    ///
1478    /// # Panics
1479    /// Panics if called multiple times.
1480    ///
1481    /// # Example
1482    /// ```
1483    /// # use bevy_app::*;
1484    /// # use bevy_ecs::error::warn;
1485    /// # fn MyPlugins(_: &mut App) {}
1486    /// App::new()
1487    ///     .set_error_handler(warn)
1488    ///     .add_plugins(MyPlugins)
1489    ///     .run();
1490    /// ```
1491    ///
1492    /// [fallback error handler]: bevy_ecs::error::FallbackErrorHandler
1493    pub fn set_error_handler(&mut self, handler: ErrorHandler) -> &mut Self {
1494        assert!(
1495            self.fallback_error_handler.is_none(),
1496            "`set_error_handler` called multiple times on same `App`"
1497        );
1498        self.fallback_error_handler = Some(handler);
1499        for sub_app in self.sub_apps.iter_mut() {
1500            sub_app
1501                .world_mut()
1502                .get_resource_or_insert_with(|| FallbackErrorHandler(handler));
1503        }
1504        self
1505    }
1506}
1507
1508// Used for doing hokey pokey in finish and cleanup
1509pub(crate) struct HokeyPokey;
1510impl Plugin for HokeyPokey {
1511    fn build(&self, _: &mut App) {}
1512}
1513
1514type RunnerFn = Box<dyn FnOnce(App) -> AppExit>;
1515
1516fn run_once(mut app: App) -> AppExit {
1517    while app.plugins_state() == PluginsState::Adding {
1518        #[cfg(not(all(target_arch = "wasm32", feature = "web")))]
1519        bevy_tasks::tick_global_task_pools_on_main_thread();
1520    }
1521    app.finish();
1522    app.cleanup();
1523
1524    app.update();
1525
1526    app.should_exit().unwrap_or(AppExit::Success)
1527}
1528
1529/// A [`SystemSet`] for systems that should run before app exit (but
1530/// after an [`AppExit`] message has been sent).
1531#[derive(SystemSet, Debug, Clone, PartialEq, Eq, Hash)]
1532pub struct OnAppExitSystems;
1533
1534/// A [`Message`] that indicates the [`App`] should exit. If one or more of these are present at the end of an update,
1535/// the [runner](App::set_runner) will end and ([maybe](App::run)) return control to the caller.
1536///
1537/// This message can be used to detect when an exit is requested. Make sure that systems listening
1538/// for this message run before the current update ends.
1539///
1540/// # Portability
1541/// 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
1542/// (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#))
1543/// we only allow error codes between 1 and [255](u8::MAX).
1544#[derive(Message, Debug, Clone, Default, PartialEq, Eq)]
1545#[cfg_attr(
1546    feature = "bevy_reflect",
1547    derive(Reflect),
1548    reflect(Debug, PartialEq, Clone, Message)
1549)]
1550pub enum AppExit {
1551    /// [`App`] exited without any problems.
1552    #[default]
1553    Success,
1554    /// The [`App`] experienced an unhandleable error.
1555    /// Holds the exit code we expect our app to return.
1556    Error(NonZero<u8>),
1557}
1558
1559impl AppExit {
1560    /// Creates a [`AppExit::Error`] with an error code of 1.
1561    #[must_use]
1562    pub const fn error() -> Self {
1563        Self::Error(NonZero::<u8>::MIN)
1564    }
1565
1566    /// Returns `true` if `self` is a [`AppExit::Success`].
1567    #[must_use]
1568    pub const fn is_success(&self) -> bool {
1569        matches!(self, AppExit::Success)
1570    }
1571
1572    /// Returns `true` if `self` is a [`AppExit::Error`].
1573    #[must_use]
1574    pub const fn is_error(&self) -> bool {
1575        matches!(self, AppExit::Error(_))
1576    }
1577
1578    /// Creates a [`AppExit`] from a code.
1579    ///
1580    /// When `code` is 0 a [`AppExit::Success`] is constructed otherwise a
1581    /// [`AppExit::Error`] is constructed.
1582    #[must_use]
1583    pub const fn from_code(code: u8) -> Self {
1584        match NonZero::<u8>::new(code) {
1585            Some(code) => Self::Error(code),
1586            None => Self::Success,
1587        }
1588    }
1589}
1590
1591impl From<u8> for AppExit {
1592    fn from(value: u8) -> Self {
1593        Self::from_code(value)
1594    }
1595}
1596
1597#[cfg(feature = "std")]
1598impl Termination for AppExit {
1599    fn report(self) -> ExitCode {
1600        match self {
1601            AppExit::Success => ExitCode::SUCCESS,
1602            // We leave logging an error to our users
1603            AppExit::Error(value) => ExitCode::from(value.get()),
1604        }
1605    }
1606}
1607
1608#[cfg(test)]
1609mod tests {
1610    use core::marker::PhantomData;
1611    use std::sync::Mutex;
1612
1613    use bevy_ecs::{
1614        change_detection::{DetectChanges, ResMut},
1615        component::Component,
1616        entity::Entity,
1617        lifecycle::RemovedComponents,
1618        message::{Message, MessageWriter, Messages},
1619        query::With,
1620        resource::Resource,
1621        schedule::{IntoScheduleConfigs, ScheduleLabel},
1622        system::{Commands, Query},
1623        world::{FromWorld, World},
1624    };
1625
1626    use crate::{App, AppExit, Plugin, SubApp, Update};
1627
1628    struct PluginA;
1629    impl Plugin for PluginA {
1630        fn build(&self, _app: &mut App) {}
1631    }
1632    struct PluginB;
1633    impl Plugin for PluginB {
1634        fn build(&self, _app: &mut App) {}
1635    }
1636    struct PluginC<T>(T);
1637    impl<T: Send + Sync + 'static> Plugin for PluginC<T> {
1638        fn build(&self, _app: &mut App) {}
1639    }
1640    struct PluginD;
1641    impl Plugin for PluginD {
1642        fn build(&self, _app: &mut App) {}
1643        fn is_unique(&self) -> bool {
1644            false
1645        }
1646    }
1647
1648    struct PluginE;
1649
1650    impl Plugin for PluginE {
1651        fn build(&self, _app: &mut App) {}
1652
1653        fn finish(&self, app: &mut App) {
1654            if app.is_plugin_added::<PluginA>() {
1655                panic!("cannot run if PluginA is already registered");
1656            }
1657        }
1658    }
1659
1660    struct PluginF;
1661
1662    impl Plugin for PluginF {
1663        fn build(&self, _app: &mut App) {}
1664
1665        fn finish(&self, app: &mut App) {
1666            // Ensure other plugins are available during finish
1667            assert_eq!(
1668                app.is_plugin_added::<PluginA>(),
1669                !app.get_added_plugins::<PluginA>().is_empty(),
1670            );
1671        }
1672
1673        fn cleanup(&self, app: &mut App) {
1674            // Ensure other plugins are available during finish
1675            assert_eq!(
1676                app.is_plugin_added::<PluginA>(),
1677                !app.get_added_plugins::<PluginA>().is_empty(),
1678            );
1679        }
1680    }
1681
1682    struct PluginG;
1683
1684    impl Plugin for PluginG {
1685        fn build(&self, _app: &mut App) {}
1686
1687        fn finish(&self, app: &mut App) {
1688            app.add_plugins(PluginB);
1689        }
1690    }
1691
1692    #[test]
1693    fn can_add_two_plugins() {
1694        App::new().add_plugins((PluginA, PluginB));
1695    }
1696
1697    #[test]
1698    #[should_panic]
1699    fn cant_add_twice_the_same_plugin() {
1700        App::new().add_plugins((PluginA, PluginA));
1701    }
1702
1703    #[test]
1704    fn can_add_twice_the_same_plugin_with_different_type_param() {
1705        App::new().add_plugins((PluginC(0), PluginC(true)));
1706    }
1707
1708    #[test]
1709    fn can_add_twice_the_same_plugin_not_unique() {
1710        App::new().add_plugins((PluginD, PluginD));
1711    }
1712
1713    #[test]
1714    #[should_panic]
1715    fn cant_call_app_run_from_plugin_build() {
1716        struct PluginRun;
1717        struct InnerPlugin;
1718        impl Plugin for InnerPlugin {
1719            fn build(&self, _: &mut App) {}
1720        }
1721        impl Plugin for PluginRun {
1722            fn build(&self, app: &mut App) {
1723                app.add_plugins(InnerPlugin).run();
1724            }
1725        }
1726        App::new().add_plugins(PluginRun);
1727    }
1728
1729    #[derive(ScheduleLabel, Hash, Clone, PartialEq, Eq, Debug)]
1730    struct EnterMainMenu;
1731
1732    #[derive(Component)]
1733    struct A;
1734
1735    fn bar(mut commands: Commands) {
1736        commands.spawn(A);
1737    }
1738
1739    fn foo(mut commands: Commands) {
1740        commands.spawn(A);
1741    }
1742
1743    #[test]
1744    fn add_systems_should_create_schedule_if_it_does_not_exist() {
1745        let mut app = App::new();
1746        app.add_systems(EnterMainMenu, (foo, bar));
1747
1748        app.world_mut().run_schedule(EnterMainMenu);
1749        assert_eq!(app.world_mut().query::<&A>().query(app.world()).count(), 2);
1750    }
1751
1752    #[test]
1753    #[should_panic]
1754    fn test_is_plugin_added_works_during_finish() {
1755        let mut app = App::new();
1756        app.add_plugins(PluginA);
1757        app.add_plugins(PluginE);
1758        app.finish();
1759    }
1760
1761    #[test]
1762    fn test_get_added_plugins_works_during_finish_and_cleanup() {
1763        let mut app = App::new();
1764        app.add_plugins(PluginA);
1765        app.add_plugins(PluginF);
1766        app.finish();
1767    }
1768
1769    #[test]
1770    fn test_adding_plugin_works_during_finish() {
1771        let mut app = App::new();
1772        app.add_plugins(PluginA);
1773        app.add_plugins(PluginG);
1774        app.finish();
1775        assert_eq!(
1776            app.main().plugin_registry[0].name(),
1777            "bevy_app::main_schedule::MainSchedulePlugin"
1778        );
1779        assert_eq!(
1780            app.main().plugin_registry[1].name(),
1781            "bevy_app::app::tests::PluginA"
1782        );
1783        assert_eq!(
1784            app.main().plugin_registry[2].name(),
1785            "bevy_app::app::tests::PluginG"
1786        );
1787        // PluginG adds PluginB during finish
1788        assert_eq!(
1789            app.main().plugin_registry[3].name(),
1790            "bevy_app::app::tests::PluginB"
1791        );
1792    }
1793
1794    #[test]
1795    fn test_derive_app_label() {
1796        use super::AppLabel;
1797
1798        #[derive(AppLabel, Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
1799        struct UnitLabel;
1800
1801        #[derive(AppLabel, Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
1802        struct TupleLabel(u32, u32);
1803
1804        #[derive(AppLabel, Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
1805        struct StructLabel {
1806            a: u32,
1807            b: u32,
1808        }
1809
1810        #[expect(
1811            dead_code,
1812            reason = "This struct is used as a compilation test to test the derive macros, and as such is intentionally never constructed."
1813        )]
1814        #[derive(AppLabel, Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
1815        struct EmptyTupleLabel();
1816
1817        #[expect(
1818            dead_code,
1819            reason = "This struct is used as a compilation test to test the derive macros, and as such is intentionally never constructed."
1820        )]
1821        #[derive(AppLabel, Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
1822        struct EmptyStructLabel {}
1823
1824        #[derive(AppLabel, Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
1825        enum EnumLabel {
1826            #[default]
1827            Unit,
1828            Tuple(u32, u32),
1829            Struct {
1830                a: u32,
1831                b: u32,
1832            },
1833        }
1834
1835        #[derive(AppLabel, Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
1836        struct GenericLabel<T>(PhantomData<T>);
1837
1838        assert_eq!(UnitLabel.intern(), UnitLabel.intern());
1839        assert_eq!(EnumLabel::Unit.intern(), EnumLabel::Unit.intern());
1840        assert_ne!(UnitLabel.intern(), EnumLabel::Unit.intern());
1841        assert_ne!(UnitLabel.intern(), TupleLabel(0, 0).intern());
1842        assert_ne!(EnumLabel::Unit.intern(), EnumLabel::Tuple(0, 0).intern());
1843
1844        assert_eq!(TupleLabel(0, 0).intern(), TupleLabel(0, 0).intern());
1845        assert_eq!(
1846            EnumLabel::Tuple(0, 0).intern(),
1847            EnumLabel::Tuple(0, 0).intern()
1848        );
1849        assert_ne!(TupleLabel(0, 0).intern(), TupleLabel(0, 1).intern());
1850        assert_ne!(
1851            EnumLabel::Tuple(0, 0).intern(),
1852            EnumLabel::Tuple(0, 1).intern()
1853        );
1854        assert_ne!(TupleLabel(0, 0).intern(), EnumLabel::Tuple(0, 0).intern());
1855        assert_ne!(
1856            TupleLabel(0, 0).intern(),
1857            StructLabel { a: 0, b: 0 }.intern()
1858        );
1859        assert_ne!(
1860            EnumLabel::Tuple(0, 0).intern(),
1861            EnumLabel::Struct { a: 0, b: 0 }.intern()
1862        );
1863
1864        assert_eq!(
1865            StructLabel { a: 0, b: 0 }.intern(),
1866            StructLabel { a: 0, b: 0 }.intern()
1867        );
1868        assert_eq!(
1869            EnumLabel::Struct { a: 0, b: 0 }.intern(),
1870            EnumLabel::Struct { a: 0, b: 0 }.intern()
1871        );
1872        assert_ne!(
1873            StructLabel { a: 0, b: 0 }.intern(),
1874            StructLabel { a: 0, b: 1 }.intern()
1875        );
1876        assert_ne!(
1877            EnumLabel::Struct { a: 0, b: 0 }.intern(),
1878            EnumLabel::Struct { a: 0, b: 1 }.intern()
1879        );
1880        assert_ne!(
1881            StructLabel { a: 0, b: 0 }.intern(),
1882            EnumLabel::Struct { a: 0, b: 0 }.intern()
1883        );
1884        assert_ne!(
1885            StructLabel { a: 0, b: 0 }.intern(),
1886            EnumLabel::Struct { a: 0, b: 0 }.intern()
1887        );
1888        assert_ne!(StructLabel { a: 0, b: 0 }.intern(), UnitLabel.intern(),);
1889        assert_ne!(
1890            EnumLabel::Struct { a: 0, b: 0 }.intern(),
1891            EnumLabel::Unit.intern()
1892        );
1893
1894        assert_eq!(
1895            GenericLabel::<u32>(PhantomData).intern(),
1896            GenericLabel::<u32>(PhantomData).intern()
1897        );
1898        assert_ne!(
1899            GenericLabel::<u32>(PhantomData).intern(),
1900            GenericLabel::<u64>(PhantomData).intern()
1901        );
1902    }
1903
1904    #[test]
1905    fn test_update_clears_trackers_once() {
1906        #[derive(Component, Copy, Clone)]
1907        struct Foo;
1908
1909        let mut app = App::new();
1910        app.world_mut().spawn_batch(core::iter::repeat_n(Foo, 5));
1911
1912        fn despawn_one_foo(mut commands: Commands, foos: Query<Entity, With<Foo>>) {
1913            if let Some(e) = foos.iter().next() {
1914                commands.entity(e).despawn();
1915            };
1916        }
1917        fn check_despawns(mut removed_foos: RemovedComponents<Foo>) {
1918            let mut despawn_count = 0;
1919            for _ in removed_foos.read() {
1920                despawn_count += 1;
1921            }
1922
1923            assert_eq!(despawn_count, 2);
1924        }
1925
1926        app.add_systems(Update, despawn_one_foo);
1927        app.update(); // Frame 0
1928        app.update(); // Frame 1
1929        app.add_systems(Update, check_despawns.after(despawn_one_foo));
1930        app.update(); // Should see despawns from frames 1 & 2, but not frame 0
1931    }
1932
1933    #[test]
1934    fn test_extract_sees_changes() {
1935        use super::AppLabel;
1936
1937        #[derive(AppLabel, Clone, Copy, Hash, PartialEq, Eq, Debug, Default)]
1938        struct MySubApp;
1939
1940        #[derive(Resource)]
1941        struct Foo(usize);
1942
1943        let mut app = App::new();
1944        app.world_mut().insert_resource(Foo(0));
1945        app.add_systems(Update, |mut foo: ResMut<Foo>| {
1946            foo.0 += 1;
1947        });
1948
1949        let mut sub_app = SubApp::new();
1950        sub_app.set_extract(|main_world, _sub_world| {
1951            assert!(main_world.get_resource_ref::<Foo>().unwrap().is_changed());
1952        });
1953
1954        app.insert_sub_app(MySubApp, sub_app);
1955
1956        app.update();
1957    }
1958
1959    #[test]
1960    fn runner_returns_correct_exit_code() {
1961        fn raise_exits(mut exits: MessageWriter<AppExit>) {
1962            // Exit codes chosen by a fair dice roll.
1963            // Unlikely to overlap with default values.
1964            exits.write(AppExit::Success);
1965            exits.write(AppExit::from_code(4));
1966            exits.write(AppExit::from_code(73));
1967        }
1968
1969        let exit = App::new().add_systems(Update, raise_exits).run();
1970
1971        assert_eq!(exit, AppExit::from_code(4));
1972    }
1973
1974    /// Custom runners should be in charge of when `app::update` gets called as they may need to
1975    /// coordinate some state.
1976    /// bug: <https://github.com/bevyengine/bevy/issues/10385>
1977    /// fix: <https://github.com/bevyengine/bevy/pull/10389>
1978    #[test]
1979    fn regression_test_10385() {
1980        use super::{Res, Resource};
1981        use crate::PreUpdate;
1982
1983        #[derive(Resource)]
1984        struct MyState {}
1985
1986        fn my_runner(mut app: App) -> AppExit {
1987            let my_state = MyState {};
1988            app.world_mut().insert_resource(my_state);
1989
1990            for _ in 0..5 {
1991                app.update();
1992            }
1993
1994            AppExit::Success
1995        }
1996
1997        fn my_system(_: Res<MyState>) {
1998            // access state during app update
1999        }
2000
2001        // Should not panic due to missing resource
2002        App::new()
2003            .set_runner(my_runner)
2004            .add_systems(PreUpdate, my_system)
2005            .run();
2006    }
2007
2008    #[test]
2009    fn app_exit_size() {
2010        // There wont be many of them so the size isn't an issue but
2011        // it's nice they're so small let's keep it that way.
2012        assert_eq!(size_of::<AppExit>(), size_of::<u8>());
2013    }
2014
2015    #[test]
2016    fn initializing_resources_from_world() {
2017        #[derive(Resource)]
2018        struct TestResource;
2019        impl FromWorld for TestResource {
2020            fn from_world(_world: &mut World) -> Self {
2021                TestResource
2022            }
2023        }
2024
2025        #[derive(Resource)]
2026        struct NonSendTestResource {
2027            _marker: PhantomData<Mutex<()>>,
2028        }
2029        impl FromWorld for NonSendTestResource {
2030            fn from_world(_world: &mut World) -> Self {
2031                NonSendTestResource {
2032                    _marker: PhantomData,
2033                }
2034            }
2035        }
2036
2037        App::new()
2038            .init_non_send::<NonSendTestResource>()
2039            .init_resource::<TestResource>();
2040    }
2041
2042    #[test]
2043    /// Plugin should not be considered inserted while it's being built
2044    ///
2045    /// bug: <https://github.com/bevyengine/bevy/issues/13815>
2046    fn plugin_should_not_be_added_during_build_time() {
2047        pub struct Foo;
2048
2049        impl Plugin for Foo {
2050            fn build(&self, app: &mut App) {
2051                assert!(!app.is_plugin_added::<Self>());
2052            }
2053        }
2054
2055        App::new().add_plugins(Foo);
2056    }
2057    #[test]
2058    fn events_should_be_updated_once_per_update() {
2059        #[derive(Message, Clone)]
2060        struct TestMessage;
2061
2062        let mut app = App::new();
2063        app.add_message::<TestMessage>();
2064
2065        // Starts empty
2066        let test_messages = app.world().resource::<Messages<TestMessage>>();
2067        assert_eq!(test_messages.len(), 0);
2068        assert_eq!(test_messages.iter_current_update_messages().count(), 0);
2069        app.update();
2070
2071        // Sending one event
2072        app.world_mut().write_message(TestMessage);
2073
2074        let test_events = app.world().resource::<Messages<TestMessage>>();
2075        assert_eq!(test_events.len(), 1);
2076        assert_eq!(test_events.iter_current_update_messages().count(), 1);
2077        app.update();
2078
2079        // Sending two events on the next frame
2080        app.world_mut().write_message(TestMessage);
2081        app.world_mut().write_message(TestMessage);
2082
2083        let test_events = app.world().resource::<Messages<TestMessage>>();
2084        assert_eq!(test_events.len(), 3); // Events are double-buffered, so we see 1 + 2 = 3
2085        assert_eq!(test_events.iter_current_update_messages().count(), 2);
2086        app.update();
2087
2088        // Sending zero events
2089        let test_events = app.world().resource::<Messages<TestMessage>>();
2090        assert_eq!(test_events.len(), 2); // Events are double-buffered, so we see 2 + 0 = 2
2091        assert_eq!(test_events.iter_current_update_messages().count(), 0);
2092    }
2093
2094    #[test]
2095    fn auto_despawn_unused_registered_systems() {
2096        let mut app = App::new();
2097
2098        fn my_system() {}
2099
2100        let handle = app.register_tracked_system(my_system);
2101        let entity = handle.entity();
2102
2103        app.update();
2104        assert!(app.world().get_entity(entity).is_ok());
2105
2106        drop(handle);
2107        app.update();
2108        assert!(app.world().get_entity(entity).is_err());
2109    }
2110}