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