Oregami
Repositories/oxedyne/fe2o3

oxedyne/fe2o3/fe2o3_text/tests/annealer_corpus/bevy_app.rs

71.0 KiB, 1 run

created by r1870400018:11694, which is this file's identity for as long as the history lasts, whatever it is later renamed to

download · who wrote it · its history

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