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