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