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