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    pub fn configure_schedules(
1229        &mut self,
1230        schedule_build_settings: ScheduleBuildSettings,
1231    ) -> &mut Self {
1232        self.main_mut().configure_schedules(schedule_build_settings);
1233        self
1234    }
1235
1236    /// When doing [ambiguity checking](ScheduleBuildSettings) this
1237    /// ignores systems that are ambiguous on [`Component`] T.
1238    ///
1239    /// This settings only applies to the main world. To apply this to other worlds call the
1240    /// [corresponding method](World::allow_ambiguous_component) on World
1241    ///
1242    /// ## Example
1243    ///
1244    /// ```
1245    /// # use bevy_app::prelude::*;
1246    /// # use bevy_ecs::prelude::*;
1247    /// # use bevy_ecs::schedule::{LogLevel, ScheduleBuildSettings};
1248    /// # use bevy_utils::default;
1249    ///
1250    /// #[derive(Component)]
1251    /// struct A;
1252    ///
1253    /// // these systems are ambiguous on A
1254    /// fn system_1(_: Query<&mut A>) {}
1255    /// fn system_2(_: Query<&A>) {}
1256    ///
1257    /// let mut app = App::new();
1258    /// app.configure_schedules(ScheduleBuildSettings {
1259    ///   ambiguity_detection: LogLevel::Error,
1260    ///   ..default()
1261    /// });
1262    ///
1263    /// app.add_systems(Update, ( system_1, system_2 ));
1264    /// app.allow_ambiguous_component::<A>();
1265    ///
1266    /// // running the app does not error.
1267    /// app.update();
1268    /// ```
1269    pub fn allow_ambiguous_component<T: Component>(&mut self) -> &mut Self {
1270        self.main_mut().allow_ambiguous_component::<T>();
1271        self
1272    }
1273
1274    /// When doing [ambiguity checking](ScheduleBuildSettings) this
1275    /// ignores systems that are ambiguous on [`Resource`] T.
1276    ///
1277    /// This settings only applies to the main world. To apply this to other worlds call the
1278    /// [corresponding method](World::allow_ambiguous_resource) on World
1279    ///
1280    /// ## Example
1281    ///
1282    /// ```
1283    /// # use bevy_app::prelude::*;
1284    /// # use bevy_ecs::prelude::*;
1285    /// # use bevy_ecs::schedule::{LogLevel, ScheduleBuildSettings};
1286    /// # use bevy_utils::default;
1287    ///
1288    /// #[derive(Resource)]
1289    /// struct R;
1290    ///
1291    /// // these systems are ambiguous on R
1292    /// fn system_1(_: ResMut<R>) {}
1293    /// fn system_2(_: Res<R>) {}
1294    ///
1295    /// let mut app = App::new();
1296    /// app.configure_schedules(ScheduleBuildSettings {
1297    ///   ambiguity_detection: LogLevel::Error,
1298    ///   ..default()
1299    /// });
1300    /// app.insert_resource(R);
1301    ///
1302    /// app.add_systems(Update, ( system_1, system_2 ));
1303    /// app.allow_ambiguous_resource::<R>();
1304    ///
1305    /// // running the app does not error.
1306    /// app.update();
1307    /// ```
1308    pub fn allow_ambiguous_resource<T: Resource>(&mut self) -> &mut Self {
1309        self.main_mut().allow_ambiguous_resource::<T>();
1310        self
1311    }
1312
1313    /// Suppress warnings and errors that would result from systems in these sets having ambiguities
1314    /// (conflicting access but indeterminate order) with systems in `set`.
1315    ///
1316    /// When possible, do this directly in the `.add_systems(Update, a.ambiguous_with(b))` call.
1317    /// However, sometimes two independent plugins `A` and `B` are reported as ambiguous, which you
1318    /// can only suppress as the consumer of both.
1319    #[track_caller]
1320    pub fn ignore_ambiguity<M1, M2, S1, S2>(
1321        &mut self,
1322        schedule: impl ScheduleLabel,
1323        a: S1,
1324        b: S2,
1325    ) -> &mut Self
1326    where
1327        S1: IntoSystemSet<M1>,
1328        S2: IntoSystemSet<M2>,
1329    {
1330        self.main_mut().ignore_ambiguity(schedule, a, b);
1331        self
1332    }
1333
1334    /// Attempts to determine if an [`AppExit`] was raised since the last update.
1335    ///
1336    /// Will attempt to return the first [`Error`](AppExit::Error) it encounters.
1337    /// This should be called after every [`update()`](App::update) otherwise you risk
1338    /// dropping possible [`AppExit`] events.
1339    pub fn should_exit(&self) -> Option<AppExit> {
1340        let mut reader = MessageCursor::default();
1341
1342        let messages = self.world().get_resource::<Messages<AppExit>>()?;
1343        let mut messages = reader.read(messages);
1344
1345        if messages.len() != 0 {
1346            return Some(
1347                messages
1348                    .find(|exit| exit.is_error())
1349                    .cloned()
1350                    .unwrap_or(AppExit::Success),
1351            );
1352        }
1353
1354        None
1355    }
1356
1357    /// Spawns an [`Observer`] entity, which will watch for and respond to the given event.
1358    ///
1359    /// `observer` can be any system whose first parameter is [`On`].
1360    ///
1361    /// # Examples
1362    ///
1363    /// ```rust
1364    /// # use bevy_app::prelude::*;
1365    /// # use bevy_ecs::prelude::*;
1366    /// # use bevy_utils::default;
1367    /// #
1368    /// # let mut app = App::new();
1369    /// #
1370    /// # #[derive(Event)]
1371    /// # struct Party {
1372    /// #   friends_allowed: bool,
1373    /// # };
1374    /// #
1375    /// # #[derive(EntityEvent)]
1376    /// # struct Invite {
1377    /// #    entity: Entity,
1378    /// # }
1379    /// #
1380    /// # #[derive(Component)]
1381    /// # struct Friend;
1382    /// #
1383    ///
1384    /// app.add_observer(|event: On<Party>, friends: Query<Entity, With<Friend>>, mut commands: Commands| {
1385    ///     if event.friends_allowed {
1386    ///         for entity in friends.iter() {
1387    ///             commands.trigger(Invite { entity } );
1388    ///         }
1389    ///     }
1390    /// });
1391    /// ```
1392    pub fn add_observer<E: Event, B: Bundle, M>(
1393        &mut self,
1394        observer: impl IntoObserverSystem<E, B, M>,
1395    ) -> &mut Self {
1396        self.world_mut().add_observer(observer);
1397        self
1398    }
1399
1400    /// Gets the error handler to set for new supapps.
1401    ///
1402    /// Note that the error handler of existing subapps may differ.
1403    pub fn get_error_handler(&self) -> Option<ErrorHandler> {
1404        self.default_error_handler
1405    }
1406
1407    /// Set the [default error handler] for the all subapps (including the main one and future ones)
1408    /// that do not have one.
1409    ///
1410    /// May only be called once and should be set by the application, not by libraries.
1411    ///
1412    /// The handler will be called when an error is produced and not otherwise handled.
1413    ///
1414    /// # Panics
1415    /// Panics if called multiple times.
1416    ///
1417    /// # Example
1418    /// ```
1419    /// # use bevy_app::*;
1420    /// # use bevy_ecs::error::warn;
1421    /// # fn MyPlugins(_: &mut App) {}
1422    /// App::new()
1423    ///     .set_error_handler(warn)
1424    ///     .add_plugins(MyPlugins)
1425    ///     .run();
1426    /// ```
1427    ///
1428    /// [default error handler]: bevy_ecs::error::DefaultErrorHandler
1429    pub fn set_error_handler(&mut self, handler: ErrorHandler) -> &mut Self {
1430        assert!(
1431            self.default_error_handler.is_none(),
1432            "`set_error_handler` called multiple times on same `App`"
1433        );
1434        self.default_error_handler = Some(handler);
1435        for sub_app in self.sub_apps.iter_mut() {
1436            sub_app
1437                .world_mut()
1438                .get_resource_or_insert_with(|| DefaultErrorHandler(handler));
1439        }
1440        self
1441    }
1442}
1443
1444// Used for doing hokey pokey in finish and cleanup
1445pub(crate) struct HokeyPokey;
1446impl Plugin for HokeyPokey {
1447    fn build(&self, _: &mut App) {}
1448}
1449
1450type RunnerFn = Box<dyn FnOnce(App) -> AppExit>;
1451
1452fn run_once(mut app: App) -> AppExit {
1453    while app.plugins_state() == PluginsState::Adding {
1454        #[cfg(not(all(target_arch = "wasm32", feature = "web")))]
1455        bevy_tasks::tick_global_task_pools_on_main_thread();
1456    }
1457    app.finish();
1458    app.cleanup();
1459
1460    app.update();
1461
1462    app.should_exit().unwrap_or(AppExit::Success)
1463}
1464
1465/// A [`Message`] that indicates the [`App`] should exit. If one or more of these are present at the end of an update,
1466/// the [runner](App::set_runner) will end and ([maybe](App::run)) return control to the caller.
1467///
1468/// This message can be used to detect when an exit is requested. Make sure that systems listening
1469/// for this message run before the current update ends.
1470///
1471/// # Portability
1472/// 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
1473/// (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#))
1474/// we only allow error codes between 1 and [255](u8::MAX).
1475#[derive(Message, Debug, Clone, Default, PartialEq, Eq)]
1476pub enum AppExit {
1477    /// [`App`] exited without any problems.
1478    #[default]
1479    Success,
1480    /// The [`App`] experienced an unhandleable error.
1481    /// Holds the exit code we expect our app to return.
1482    Error(NonZero<u8>),
1483}
1484
1485impl AppExit {
1486    /// Creates a [`AppExit::Error`] with an error code of 1.
1487    #[must_use]
1488    pub const fn error() -> Self {
1489        Self::Error(NonZero::<u8>::MIN)
1490    }
1491
1492    /// Returns `true` if `self` is a [`AppExit::Success`].
1493    #[must_use]
1494    pub const fn is_success(&self) -> bool {
1495        matches!(self, AppExit::Success)
1496    }
1497
1498    /// Returns `true` if `self` is a [`AppExit::Error`].
1499    #[must_use]
1500    pub const fn is_error(&self) -> bool {
1501        matches!(self, AppExit::Error(_))
1502    }
1503
1504    /// Creates a [`AppExit`] from a code.
1505    ///
1506    /// When `code` is 0 a [`AppExit::Success`] is constructed otherwise a
1507    /// [`AppExit::Error`] is constructed.
1508    #[must_use]
1509    pub const fn from_code(code: u8) -> Self {
1510        match NonZero::<u8>::new(code) {
1511            Some(code) => Self::Error(code),
1512            None => Self::Success,
1513        }
1514    }
1515}
1516
1517impl From<u8> for AppExit {
1518    fn from(value: u8) -> Self {
1519        Self::from_code(value)
1520    }
1521}
1522
1523#[cfg(feature = "std")]
1524impl Termination for AppExit {
1525    fn report(self) -> ExitCode {
1526        match self {
1527            AppExit::Success => ExitCode::SUCCESS,
1528            // We leave logging an error to our users
1529            AppExit::Error(value) => ExitCode::from(value.get()),
1530        }
1531    }
1532}
1533
1534#[cfg(test)]
1535mod tests {
1536    use core::marker::PhantomData;
1537    use std::sync::Mutex;
1538
1539    use bevy_ecs::{
1540        change_detection::{DetectChanges, ResMut},
1541        component::Component,
1542        entity::Entity,
1543        lifecycle::RemovedComponents,
1544        message::{Message, MessageWriter, Messages},
1545        query::With,
1546        resource::Resource,
1547        schedule::{IntoScheduleConfigs, ScheduleLabel},
1548        system::{Commands, Query},
1549        world::{FromWorld, World},
1550    };
1551
1552    use crate::{App, AppExit, Plugin, SubApp, Update};
1553
1554    struct PluginA;
1555    impl Plugin for PluginA {
1556        fn build(&self, _app: &mut App) {}
1557    }
1558    struct PluginB;
1559    impl Plugin for PluginB {
1560        fn build(&self, _app: &mut App) {}
1561    }
1562    struct PluginC<T>(T);
1563    impl<T: Send + Sync + 'static> Plugin for PluginC<T> {
1564        fn build(&self, _app: &mut App) {}
1565    }
1566    struct PluginD;
1567    impl Plugin for PluginD {
1568        fn build(&self, _app: &mut App) {}
1569        fn is_unique(&self) -> bool {
1570            false
1571        }
1572    }
1573
1574    struct PluginE;
1575
1576    impl Plugin for PluginE {
1577        fn build(&self, _app: &mut App) {}
1578
1579        fn finish(&self, app: &mut App) {
1580            if app.is_plugin_added::<PluginA>() {
1581                panic!("cannot run if PluginA is already registered");
1582            }
1583        }
1584    }
1585
1586    struct PluginF;
1587
1588    impl Plugin for PluginF {
1589        fn build(&self, _app: &mut App) {}
1590
1591        fn finish(&self, app: &mut App) {
1592            // Ensure other plugins are available during finish
1593            assert_eq!(
1594                app.is_plugin_added::<PluginA>(),
1595                !app.get_added_plugins::<PluginA>().is_empty(),
1596            );
1597        }
1598
1599        fn cleanup(&self, app: &mut App) {
1600            // Ensure other plugins are available during finish
1601            assert_eq!(
1602                app.is_plugin_added::<PluginA>(),
1603                !app.get_added_plugins::<PluginA>().is_empty(),
1604            );
1605        }
1606    }
1607
1608    struct PluginG;
1609
1610    impl Plugin for PluginG {
1611        fn build(&self, _app: &mut App) {}
1612
1613        fn finish(&self, app: &mut App) {
1614            app.add_plugins(PluginB);
1615        }
1616    }
1617
1618    #[test]
1619    fn can_add_two_plugins() {
1620        App::new().add_plugins((PluginA, PluginB));
1621    }
1622
1623    #[test]
1624    #[should_panic]
1625    fn cant_add_twice_the_same_plugin() {
1626        App::new().add_plugins((PluginA, PluginA));
1627    }
1628
1629    #[test]
1630    fn can_add_twice_the_same_plugin_with_different_type_param() {
1631        App::new().add_plugins((PluginC(0), PluginC(true)));
1632    }
1633
1634    #[test]
1635    fn can_add_twice_the_same_plugin_not_unique() {
1636        App::new().add_plugins((PluginD, PluginD));
1637    }
1638
1639    #[test]
1640    #[should_panic]
1641    fn cant_call_app_run_from_plugin_build() {
1642        struct PluginRun;
1643        struct InnerPlugin;
1644        impl Plugin for InnerPlugin {
1645            fn build(&self, _: &mut App) {}
1646        }
1647        impl Plugin for PluginRun {
1648            fn build(&self, app: &mut App) {
1649                app.add_plugins(InnerPlugin).run();
1650            }
1651        }
1652        App::new().add_plugins(PluginRun);
1653    }
1654
1655    #[derive(ScheduleLabel, Hash, Clone, PartialEq, Eq, Debug)]
1656    struct EnterMainMenu;
1657
1658    #[derive(Component)]
1659    struct A;
1660
1661    fn bar(mut commands: Commands) {
1662        commands.spawn(A);
1663    }
1664
1665    fn foo(mut commands: Commands) {
1666        commands.spawn(A);
1667    }
1668
1669    #[test]
1670    fn add_systems_should_create_schedule_if_it_does_not_exist() {
1671        let mut app = App::new();
1672        app.add_systems(EnterMainMenu, (foo, bar));
1673
1674        app.world_mut().run_schedule(EnterMainMenu);
1675        assert_eq!(app.world_mut().query::<&A>().query(app.world()).count(), 2);
1676    }
1677
1678    #[test]
1679    #[should_panic]
1680    fn test_is_plugin_added_works_during_finish() {
1681        let mut app = App::new();
1682        app.add_plugins(PluginA);
1683        app.add_plugins(PluginE);
1684        app.finish();
1685    }
1686
1687    #[test]
1688    fn test_get_added_plugins_works_during_finish_and_cleanup() {
1689        let mut app = App::new();
1690        app.add_plugins(PluginA);
1691        app.add_plugins(PluginF);
1692        app.finish();
1693    }
1694
1695    #[test]
1696    fn test_adding_plugin_works_during_finish() {
1697        let mut app = App::new();
1698        app.add_plugins(PluginA);
1699        app.add_plugins(PluginG);
1700        app.finish();
1701        assert_eq!(
1702            app.main().plugin_registry[0].name(),
1703            "bevy_app::main_schedule::MainSchedulePlugin"
1704        );
1705        assert_eq!(
1706            app.main().plugin_registry[1].name(),
1707            "bevy_app::app::tests::PluginA"
1708        );
1709        assert_eq!(
1710            app.main().plugin_registry[2].name(),
1711            "bevy_app::app::tests::PluginG"
1712        );
1713        // PluginG adds PluginB during finish
1714        assert_eq!(
1715            app.main().plugin_registry[3].name(),
1716            "bevy_app::app::tests::PluginB"
1717        );
1718    }
1719
1720    #[test]
1721    fn test_derive_app_label() {
1722        use super::AppLabel;
1723
1724        #[derive(AppLabel, Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
1725        struct UnitLabel;
1726
1727        #[derive(AppLabel, Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
1728        struct TupleLabel(u32, u32);
1729
1730        #[derive(AppLabel, Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
1731        struct StructLabel {
1732            a: u32,
1733            b: u32,
1734        }
1735
1736        #[expect(
1737            dead_code,
1738            reason = "This struct is used as a compilation test to test the derive macros, and as such is intentionally never constructed."
1739        )]
1740        #[derive(AppLabel, Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
1741        struct EmptyTupleLabel();
1742
1743        #[expect(
1744            dead_code,
1745            reason = "This struct is used as a compilation test to test the derive macros, and as such is intentionally never constructed."
1746        )]
1747        #[derive(AppLabel, Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
1748        struct EmptyStructLabel {}
1749
1750        #[derive(AppLabel, Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
1751        enum EnumLabel {
1752            #[default]
1753            Unit,
1754            Tuple(u32, u32),
1755            Struct {
1756                a: u32,
1757                b: u32,
1758            },
1759        }
1760
1761        #[derive(AppLabel, Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
1762        struct GenericLabel<T>(PhantomData<T>);
1763
1764        assert_eq!(UnitLabel.intern(), UnitLabel.intern());
1765        assert_eq!(EnumLabel::Unit.intern(), EnumLabel::Unit.intern());
1766        assert_ne!(UnitLabel.intern(), EnumLabel::Unit.intern());
1767        assert_ne!(UnitLabel.intern(), TupleLabel(0, 0).intern());
1768        assert_ne!(EnumLabel::Unit.intern(), EnumLabel::Tuple(0, 0).intern());
1769
1770        assert_eq!(TupleLabel(0, 0).intern(), TupleLabel(0, 0).intern());
1771        assert_eq!(
1772            EnumLabel::Tuple(0, 0).intern(),
1773            EnumLabel::Tuple(0, 0).intern()
1774        );
1775        assert_ne!(TupleLabel(0, 0).intern(), TupleLabel(0, 1).intern());
1776        assert_ne!(
1777            EnumLabel::Tuple(0, 0).intern(),
1778            EnumLabel::Tuple(0, 1).intern()
1779        );
1780        assert_ne!(TupleLabel(0, 0).intern(), EnumLabel::Tuple(0, 0).intern());
1781        assert_ne!(
1782            TupleLabel(0, 0).intern(),
1783            StructLabel { a: 0, b: 0 }.intern()
1784        );
1785        assert_ne!(
1786            EnumLabel::Tuple(0, 0).intern(),
1787            EnumLabel::Struct { a: 0, b: 0 }.intern()
1788        );
1789
1790        assert_eq!(
1791            StructLabel { a: 0, b: 0 }.intern(),
1792            StructLabel { a: 0, b: 0 }.intern()
1793        );
1794        assert_eq!(
1795            EnumLabel::Struct { a: 0, b: 0 }.intern(),
1796            EnumLabel::Struct { a: 0, b: 0 }.intern()
1797        );
1798        assert_ne!(
1799            StructLabel { a: 0, b: 0 }.intern(),
1800            StructLabel { a: 0, b: 1 }.intern()
1801        );
1802        assert_ne!(
1803            EnumLabel::Struct { a: 0, b: 0 }.intern(),
1804            EnumLabel::Struct { a: 0, b: 1 }.intern()
1805        );
1806        assert_ne!(
1807            StructLabel { a: 0, b: 0 }.intern(),
1808            EnumLabel::Struct { a: 0, b: 0 }.intern()
1809        );
1810        assert_ne!(
1811            StructLabel { a: 0, b: 0 }.intern(),
1812            EnumLabel::Struct { a: 0, b: 0 }.intern()
1813        );
1814        assert_ne!(StructLabel { a: 0, b: 0 }.intern(), UnitLabel.intern(),);
1815        assert_ne!(
1816            EnumLabel::Struct { a: 0, b: 0 }.intern(),
1817            EnumLabel::Unit.intern()
1818        );
1819
1820        assert_eq!(
1821            GenericLabel::<u32>(PhantomData).intern(),
1822            GenericLabel::<u32>(PhantomData).intern()
1823        );
1824        assert_ne!(
1825            GenericLabel::<u32>(PhantomData).intern(),
1826            GenericLabel::<u64>(PhantomData).intern()
1827        );
1828    }
1829
1830    #[test]
1831    fn test_update_clears_trackers_once() {
1832        #[derive(Component, Copy, Clone)]
1833        struct Foo;
1834
1835        let mut app = App::new();
1836        app.world_mut().spawn_batch(core::iter::repeat_n(Foo, 5));
1837
1838        fn despawn_one_foo(mut commands: Commands, foos: Query<Entity, With<Foo>>) {
1839            if let Some(e) = foos.iter().next() {
1840                commands.entity(e).despawn();
1841            };
1842        }
1843        fn check_despawns(mut removed_foos: RemovedComponents<Foo>) {
1844            let mut despawn_count = 0;
1845            for _ in removed_foos.read() {
1846                despawn_count += 1;
1847            }
1848
1849            assert_eq!(despawn_count, 2);
1850        }
1851
1852        app.add_systems(Update, despawn_one_foo);
1853        app.update(); // Frame 0
1854        app.update(); // Frame 1
1855        app.add_systems(Update, check_despawns.after(despawn_one_foo));
1856        app.update(); // Should see despawns from frames 1 & 2, but not frame 0
1857    }
1858
1859    #[test]
1860    fn test_extract_sees_changes() {
1861        use super::AppLabel;
1862
1863        #[derive(AppLabel, Clone, Copy, Hash, PartialEq, Eq, Debug)]
1864        struct MySubApp;
1865
1866        #[derive(Resource)]
1867        struct Foo(usize);
1868
1869        let mut app = App::new();
1870        app.world_mut().insert_resource(Foo(0));
1871        app.add_systems(Update, |mut foo: ResMut<Foo>| {
1872            foo.0 += 1;
1873        });
1874
1875        let mut sub_app = SubApp::new();
1876        sub_app.set_extract(|main_world, _sub_world| {
1877            assert!(main_world.get_resource_ref::<Foo>().unwrap().is_changed());
1878        });
1879
1880        app.insert_sub_app(MySubApp, sub_app);
1881
1882        app.update();
1883    }
1884
1885    #[test]
1886    fn runner_returns_correct_exit_code() {
1887        fn raise_exits(mut exits: MessageWriter<AppExit>) {
1888            // Exit codes chosen by a fair dice roll.
1889            // Unlikely to overlap with default values.
1890            exits.write(AppExit::Success);
1891            exits.write(AppExit::from_code(4));
1892            exits.write(AppExit::from_code(73));
1893        }
1894
1895        let exit = App::new().add_systems(Update, raise_exits).run();
1896
1897        assert_eq!(exit, AppExit::from_code(4));
1898    }
1899
1900    /// Custom runners should be in charge of when `app::update` gets called as they may need to
1901    /// coordinate some state.
1902    /// bug: <https://github.com/bevyengine/bevy/issues/10385>
1903    /// fix: <https://github.com/bevyengine/bevy/pull/10389>
1904    #[test]
1905    fn regression_test_10385() {
1906        use super::{Res, Resource};
1907        use crate::PreUpdate;
1908
1909        #[derive(Resource)]
1910        struct MyState {}
1911
1912        fn my_runner(mut app: App) -> AppExit {
1913            let my_state = MyState {};
1914            app.world_mut().insert_resource(my_state);
1915
1916            for _ in 0..5 {
1917                app.update();
1918            }
1919
1920            AppExit::Success
1921        }
1922
1923        fn my_system(_: Res<MyState>) {
1924            // access state during app update
1925        }
1926
1927        // Should not panic due to missing resource
1928        App::new()
1929            .set_runner(my_runner)
1930            .add_systems(PreUpdate, my_system)
1931            .run();
1932    }
1933
1934    #[test]
1935    fn app_exit_size() {
1936        // There wont be many of them so the size isn't an issue but
1937        // it's nice they're so small let's keep it that way.
1938        assert_eq!(size_of::<AppExit>(), size_of::<u8>());
1939    }
1940
1941    #[test]
1942    fn initializing_resources_from_world() {
1943        #[derive(Resource)]
1944        struct TestResource;
1945        impl FromWorld for TestResource {
1946            fn from_world(_world: &mut World) -> Self {
1947                TestResource
1948            }
1949        }
1950
1951        #[derive(Resource)]
1952        struct NonSendTestResource {
1953            _marker: PhantomData<Mutex<()>>,
1954        }
1955        impl FromWorld for NonSendTestResource {
1956            fn from_world(_world: &mut World) -> Self {
1957                NonSendTestResource {
1958                    _marker: PhantomData,
1959                }
1960            }
1961        }
1962
1963        App::new()
1964            .init_non_send_resource::<NonSendTestResource>()
1965            .init_resource::<TestResource>();
1966    }
1967
1968    #[test]
1969    /// Plugin should not be considered inserted while it's being built
1970    ///
1971    /// bug: <https://github.com/bevyengine/bevy/issues/13815>
1972    fn plugin_should_not_be_added_during_build_time() {
1973        pub struct Foo;
1974
1975        impl Plugin for Foo {
1976            fn build(&self, app: &mut App) {
1977                assert!(!app.is_plugin_added::<Self>());
1978            }
1979        }
1980
1981        App::new().add_plugins(Foo);
1982    }
1983    #[test]
1984    fn events_should_be_updated_once_per_update() {
1985        #[derive(Message, Clone)]
1986        struct TestMessage;
1987
1988        let mut app = App::new();
1989        app.add_message::<TestMessage>();
1990
1991        // Starts empty
1992        let test_messages = app.world().resource::<Messages<TestMessage>>();
1993        assert_eq!(test_messages.len(), 0);
1994        assert_eq!(test_messages.iter_current_update_messages().count(), 0);
1995        app.update();
1996
1997        // Sending one event
1998        app.world_mut().write_message(TestMessage);
1999
2000        let test_events = app.world().resource::<Messages<TestMessage>>();
2001        assert_eq!(test_events.len(), 1);
2002        assert_eq!(test_events.iter_current_update_messages().count(), 1);
2003        app.update();
2004
2005        // Sending two events on the next frame
2006        app.world_mut().write_message(TestMessage);
2007        app.world_mut().write_message(TestMessage);
2008
2009        let test_events = app.world().resource::<Messages<TestMessage>>();
2010        assert_eq!(test_events.len(), 3); // Events are double-buffered, so we see 1 + 2 = 3
2011        assert_eq!(test_events.iter_current_update_messages().count(), 2);
2012        app.update();
2013
2014        // Sending zero events
2015        let test_events = app.world().resource::<Messages<TestMessage>>();
2016        assert_eq!(test_events.len(), 2); // Events are double-buffered, so we see 2 + 0 = 2
2017        assert_eq!(test_events.iter_current_update_messages().count(), 0);
2018    }
2019}