Struct valence::app::App

pub struct App { /* private fields */ }
Expand description

App is the primary API for writing user applications. It automates the setup of a standard lifecycle and provides interface glue for plugins.

A single App can contain multiple SubApp instances, but App methods only affect the “main” one. To access a particular SubApp, use get_sub_app or get_sub_app_mut.

§Examples

Here is a simple “Hello World” Bevy app:

fn main() {
   App::new()
       .add_systems(Update, hello_world_system)
       .run();
}

fn hello_world_system() {
   println!("hello world");
}

Implementations§

§

impl App

pub fn new() -> App

Creates a new App with some default structure to enable core engine features. This is the preferred constructor for most use cases.

pub fn empty() -> App

Creates a new empty App with minimal default configuration.

Use this constructor if you want to customize scheduling, exit handling, cleanup, etc.

pub fn update(&mut self)

Runs the default schedules of all sub-apps (starting with the “main” app) once.

pub fn run(&mut self) -> AppExit

Runs the App by calling its runner.

This will (re)build the App first. For general usage, see the example on the item level documentation.

§Caveats

Calls to App::run() will never return on iOS and Web.

Headless apps can generally expect this method to return control to the caller when it completes, but that is not the case for windowed apps. Windowed apps are typically driven by an event loop and some platforms expect the program to terminate when the event loop ends.

By default, Bevy uses the winit crate for window creation.

§Panics

Panics if not all plugins have been built.

pub fn set_runner( &mut self, f: impl FnOnce(App) -> AppExit + 'static, ) -> &mut App

Sets the function that will be called when the app is run.

The runner function f is called only once by App::run. If the presence of a main loop in the app is desired, it is the responsibility of the runner function to provide it.

The runner function is usually not set manually, but by Bevy integrated plugins (e.g. WinitPlugin).

§Examples
fn my_runner(mut app: App) -> AppExit {
    loop {
        println!("In main loop");
        app.update();
        if let Some(exit) = app.should_exit() {
            return exit;
        }
    }
}

App::new()
    .set_runner(my_runner);

pub fn plugins_state(&mut self) -> PluginsState

Returns the state of all plugins. This is usually called by the event loop, but can be useful for situations where you want to use App::update.

pub fn finish(&mut self)

Runs Plugin::finish for each plugin. This is usually called by the event loop once all plugins are ready, but can be useful for situations where you want to use App::update.

pub fn cleanup(&mut self)

Runs Plugin::cleanup for each plugin. This is usually called by the event loop after App::finish, but can be useful for situations where you want to use App::update.

pub fn add_systems<M>( &mut self, schedule: impl ScheduleLabel, systems: impl IntoSystemConfigs<M>, ) -> &mut App

Adds one or more systems to the given schedule in this app’s Schedules.

§Examples
app.add_systems(Update, (system_a, system_b, system_c));
app.add_systems(Update, (system_a, system_b).run_if(should_run));

pub fn register_system<I, O, M, S>(&mut self, system: S) -> SystemId<I, O>
where I: 'static, O: 'static, S: IntoSystem<I, O, M> + 'static,

Registers a system and returns a SystemId so it can later be called by World::run_system.

It’s possible to register the same systems more than once, they’ll be stored separately.

This is different from adding systems to a Schedule with App::add_systems, because the SystemId that is returned can be used anywhere in the World to run the associated system. This allows for running systems in a push-based fashion. Using a Schedule is still preferred for most cases due to its better performance and ability to run non-conflicting systems simultaneously.

pub fn configure_sets( &mut self, schedule: impl ScheduleLabel, sets: impl IntoSystemSetConfigs, ) -> &mut App

Configures a collection of system sets in the provided schedule, adding any sets that do not exist.

pub fn add_event<T>(&mut self) -> &mut App
where T: Event,

Initializes T event handling by inserting an event queue resource (Events::<T>) and scheduling an event_update_system in First.

See Events for information on how to define events.

§Examples
app.add_event::<MyEvent>();

pub fn insert_resource<R>(&mut self, resource: R) -> &mut App
where R: Resource,

Inserts the Resource into the app, overwriting any existing resource of the same type.

There is also an init_resource for resources that have Default or FromWorld implementations.

§Examples
#[derive(Resource)]
struct MyCounter {
    counter: usize,
}

App::new()
   .insert_resource(MyCounter { counter: 0 });

pub fn init_resource<R>(&mut self) -> &mut App
where R: Resource + FromWorld,

Inserts the Resource, initialized with its default value, into the app, if there is no existing instance of R.

R must implement FromWorld. If R implements Default, FromWorld will be automatically implemented and initialize the Resource with Default::default.

§Examples
#[derive(Resource)]
struct MyCounter {
    counter: usize,
}

impl Default for MyCounter {
    fn default() -> MyCounter {
        MyCounter {
            counter: 100
        }
    }
}

App::new()
    .init_resource::<MyCounter>();

pub fn insert_non_send_resource<R>(&mut self, resource: R) -> &mut App
where R: 'static,

Inserts the !Send resource into the app, overwriting any existing resource of the same type.

There is also an init_non_send_resource for resources that implement Default

§Examples
struct MyCounter {
    counter: usize,
}

App::new()
    .insert_non_send_resource(MyCounter { counter: 0 });

pub fn init_non_send_resource<R>(&mut self) -> &mut App
where R: 'static + FromWorld,

Inserts the !Send resource into the app if there is no existing instance of R.

R must implement FromWorld. If R implements Default, FromWorld will be automatically implemented and initialize the Resource with Default::default.

pub fn is_plugin_added<T>(&self) -> bool
where T: Plugin,

Returns true if the Plugin has already been added.

pub fn get_added_plugins<T>(&self) -> Vec<&T>
where T: Plugin,

Returns a vector of references to all plugins of type T that have been added.

This can be used to read the settings of any existing plugins. This vector will be empty if no plugins of that type have been added. If multiple copies of the same plugin are added to the App, they will be listed in insertion order in this vector.

let default_sampler = app.get_added_plugins::<ImagePlugin>()[0].default_sampler;

pub fn add_plugins<M>(&mut self, plugins: impl Plugins<M>) -> &mut App

Installs a Plugin collection.

Bevy prioritizes modularity as a core principle. All engine features are implemented as plugins, even the complex ones like rendering.

Plugins can be grouped into a set by using a PluginGroup.

There are built-in PluginGroups that provide core engine functionality. The PluginGroups available by default are DefaultPlugins and MinimalPlugins.

To customize the plugins in the group (reorder, disable a plugin, add a new plugin before / after another plugin), call build() on the group, which will convert it to a PluginGroupBuilder.

You can also specify a group of Plugins by using a tuple over Plugins and PluginGroups. See Plugins for more details.

§Examples
App::new()
    .add_plugins(MinimalPlugins);
App::new()
    .add_plugins((MinimalPlugins, LogPlugin));
§Panics

Panics if one of the plugins had already been added to the application.

pub fn register_type<T>(&mut self) -> &mut App
where T: GetTypeRegistration,

Registers the type T in the TypeRegistry resource, adding reflect data as specified in the Reflect derive:

#[derive(Component, Serialize, Deserialize, Reflect)]
#[reflect(Component, Serialize, Deserialize)] // will register ReflectComponent, ReflectSerialize, ReflectDeserialize

See [bevy_reflect::TypeRegistry::register] for more information.

pub fn register_type_data<T, D>(&mut self) -> &mut App
where T: Reflect + TypePath, D: TypeData + FromType<T>,

Associates type data D with type T in the TypeRegistry resource.

Most of the time register_type can be used instead to register a type you derived Reflect for. However, in cases where you want to add a piece of type data that was not included in the list of #[reflect(...)] type data in the derive, or where the type is generic and cannot register e.g. ReflectSerialize unconditionally without knowing the specific type parameters, this method can be used to insert additional type data.

§Example
use bevy_app::App;
use bevy_reflect::{ReflectSerialize, ReflectDeserialize};

App::new()
    .register_type::<Option<String>>()
    .register_type_data::<Option<String>, ReflectSerialize>()
    .register_type_data::<Option<String>, ReflectDeserialize>();

See [bevy_reflect::TypeRegistry::register_type_data].

pub fn world(&self) -> &World

Returns a reference to the World.

pub fn world_mut(&mut self) -> &mut World

Returns a mutable reference to the World.

pub fn main(&self) -> &SubApp

Returns a reference to the main SubApp.

pub fn main_mut(&mut self) -> &mut SubApp

Returns a mutable reference to the main SubApp.

pub fn sub_app(&self, label: impl AppLabel) -> &SubApp

Returns a reference to the SubApp with the given label.

§Panics

Panics if the SubApp doesn’t exist.

pub fn sub_app_mut(&mut self, label: impl AppLabel) -> &mut SubApp

Returns a reference to the SubApp with the given label.

§Panics

Panics if the SubApp doesn’t exist.

pub fn get_sub_app(&self, label: impl AppLabel) -> Option<&SubApp>

Returns a reference to the SubApp with the given label, if it exists.

pub fn get_sub_app_mut(&mut self, label: impl AppLabel) -> Option<&mut SubApp>

Returns a mutable reference to the SubApp with the given label, if it exists.

pub fn insert_sub_app(&mut self, label: impl AppLabel, sub_app: SubApp)

Inserts a SubApp with the given label.

pub fn remove_sub_app(&mut self, label: impl AppLabel) -> Option<SubApp>

Removes the SubApp with the given label, if it exists.

pub fn update_sub_app_by_label(&mut self, label: impl AppLabel)

Extract data from the main world into the SubApp with the given label and perform an update if it exists.

pub fn add_schedule(&mut self, schedule: Schedule) -> &mut App

Inserts a new schedule under the provided label, overwriting any existing schedule with the same label.

pub fn init_schedule(&mut self, label: impl ScheduleLabel) -> &mut App

Initializes an empty schedule under the provided label, if it does not exist.

See add_schedule to insert an existing schedule.

pub fn get_schedule(&self, label: impl ScheduleLabel) -> Option<&Schedule>

Returns a reference to the Schedule with the provided label if it exists.

pub fn get_schedule_mut( &mut self, label: impl ScheduleLabel, ) -> Option<&mut Schedule>

Returns a mutable reference to the Schedule with the provided label if it exists.

pub fn edit_schedule( &mut self, label: impl ScheduleLabel, f: impl FnMut(&mut Schedule), ) -> &mut App

Runs function f with the Schedule associated with label.

Note: This will create the schedule if it does not already exist.

pub fn configure_schedules( &mut self, schedule_build_settings: ScheduleBuildSettings, ) -> &mut App

Applies the provided ScheduleBuildSettings to all schedules.

pub fn allow_ambiguous_component<T>(&mut self) -> &mut App
where T: Component,

When doing ambiguity checking this ignores systems that are ambiguous on Component T.

This settings only applies to the main world. To apply this to other worlds call the corresponding method on World

§Example

#[derive(Component)]
struct A;

// these systems are ambiguous on A
fn system_1(_: Query<&mut A>) {}
fn system_2(_: Query<&A>) {}

let mut app = App::new();
app.configure_schedules(ScheduleBuildSettings {
  ambiguity_detection: LogLevel::Error,
  ..default()
});

app.add_systems(Update, ( system_1, system_2 ));
app.allow_ambiguous_component::<A>();

// running the app does not error.
app.update();

pub fn allow_ambiguous_resource<T>(&mut self) -> &mut App
where T: Resource,

When doing ambiguity checking this ignores systems that are ambiguous on Resource T.

This settings only applies to the main world. To apply this to other worlds call the corresponding method on World

§Example

#[derive(Resource)]
struct R;

// these systems are ambiguous on R
fn system_1(_: ResMut<R>) {}
fn system_2(_: Res<R>) {}

let mut app = App::new();
app.configure_schedules(ScheduleBuildSettings {
  ambiguity_detection: LogLevel::Error,
  ..default()
});
app.insert_resource(R);

app.add_systems(Update, ( system_1, system_2 ));
app.allow_ambiguous_resource::<R>();

// running the app does not error.
app.update();

pub fn ignore_ambiguity<M1, M2, S1, S2>( &mut self, schedule: impl ScheduleLabel, a: S1, b: S2, ) -> &mut App
where S1: IntoSystemSet<M1>, S2: IntoSystemSet<M2>,

Suppress warnings and errors that would result from systems in these sets having ambiguities (conflicting access but indeterminate order) with systems in set.

When possible, do this directly in the .add_systems(Update, a.ambiguous_with(b)) call. However, sometimes two independent plugins A and B are reported as ambiguous, which you can only suppress as the consumer of both.

pub fn should_exit(&self) -> Option<AppExit>

Attempts to determine if an AppExit was raised since the last update.

Will attempt to return the first Error it encounters. This should be called after every update() otherwise you risk dropping possible AppExit events.

pub fn observe<E, B, M>( &mut self, observer: impl IntoObserverSystem<E, B, M>, ) -> &mut App
where E: Event, B: Bundle,

Spawns an Observer entity, which will watch for and respond to the given event.

Trait Implementations§

source§

impl AddCommand for App

source§

fn add_command<T>(&mut self) -> &mut App
where T: Command + Send + Sync + 'static,

§

impl Debug for App

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl Default for App

§

fn default() -> App

Returns the “default value” for a type. Read more

Auto Trait Implementations§

§

impl !Freeze for App

§

impl !RefUnwindSafe for App

§

impl !Send for App

§

impl !Sync for App

§

impl Unpin for App

§

impl !UnwindSafe for App

Blanket Implementations§

source§

impl<T> Any for T
where T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<T> Conv for T

§

fn conv<T>(self) -> T
where Self: Into<T>,

Converts self into T using Into<T>. Read more
§

impl<T> Downcast for T
where T: Any,

§

fn into_any(self: Box<T>) -> Box<dyn Any>

Convert Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>. Box<dyn Any> can then be further downcast into Box<ConcreteType> where ConcreteType implements Trait.
§

fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>

Convert Rc<Trait> (where Trait: Downcast) to Rc<Any>. Rc<Any> can then be further downcast into Rc<ConcreteType> where ConcreteType implements Trait.
§

fn as_any(&self) -> &(dyn Any + 'static)

Convert &Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot generate &Any’s vtable from &Trait’s.
§

fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)

Convert &mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot generate &mut Any’s vtable from &mut Trait’s.
§

impl<T> FmtForward for T

§

fn fmt_binary(self) -> FmtBinary<Self>
where Self: Binary,

Causes self to use its Binary implementation when Debug-formatted.
§

fn fmt_display(self) -> FmtDisplay<Self>
where Self: Display,

Causes self to use its Display implementation when Debug-formatted.
§

fn fmt_lower_exp(self) -> FmtLowerExp<Self>
where Self: LowerExp,

Causes self to use its LowerExp implementation when Debug-formatted.
§

fn fmt_lower_hex(self) -> FmtLowerHex<Self>
where Self: LowerHex,

Causes self to use its LowerHex implementation when Debug-formatted.
§

fn fmt_octal(self) -> FmtOctal<Self>
where Self: Octal,

Causes self to use its Octal implementation when Debug-formatted.
§

fn fmt_pointer(self) -> FmtPointer<Self>
where Self: Pointer,

Causes self to use its Pointer implementation when Debug-formatted.
§

fn fmt_upper_exp(self) -> FmtUpperExp<Self>
where Self: UpperExp,

Causes self to use its UpperExp implementation when Debug-formatted.
§

fn fmt_upper_hex(self) -> FmtUpperHex<Self>
where Self: UpperHex,

Causes self to use its UpperHex implementation when Debug-formatted.
§

fn fmt_list(self) -> FmtList<Self>
where &'a Self: for<'a> IntoIterator,

Formats each item in a sequence. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

§

impl<T> FromWorld for T
where T: Default,

§

fn from_world(_world: &mut World) -> T

Creates Self using data from the given World.
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

§

impl<T> Pipe for T
where T: ?Sized,

§

fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> R
where Self: Sized,

Pipes by value. This is generally the method you want to use. Read more
§

fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> R
where R: 'a,

Borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> R
where R: 'a,

Mutably borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
where Self: Borrow<B>, B: 'a + ?Sized, R: 'a,

Borrows self, then passes self.borrow() into the pipe function. Read more
§

fn pipe_borrow_mut<'a, B, R>( &'a mut self, func: impl FnOnce(&'a mut B) -> R, ) -> R
where Self: BorrowMut<B>, B: 'a + ?Sized, R: 'a,

Mutably borrows self, then passes self.borrow_mut() into the pipe function. Read more
§

fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
where Self: AsRef<U>, U: 'a + ?Sized, R: 'a,

Borrows self, then passes self.as_ref() into the pipe function.
§

fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
where Self: AsMut<U>, U: 'a + ?Sized, R: 'a,

Mutably borrows self, then passes self.as_mut() into the pipe function.
§

fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
where Self: Deref<Target = T>, T: 'a + ?Sized, R: 'a,

Borrows self, then passes self.deref() into the pipe function.
§

fn pipe_deref_mut<'a, T, R>( &'a mut self, func: impl FnOnce(&'a mut T) -> R, ) -> R
where Self: DerefMut<Target = T> + Deref, T: 'a + ?Sized, R: 'a,

Mutably borrows self, then passes self.deref_mut() into the pipe function.
source§

impl<T> Same for T

source§

type Output = T

Should always be Self
§

impl<T> Tap for T

§

fn tap(self, func: impl FnOnce(&Self)) -> Self

Immutable access to a value. Read more
§

fn tap_mut(self, func: impl FnOnce(&mut Self)) -> Self

Mutable access to a value. Read more
§

fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
where Self: Borrow<B>, B: ?Sized,

Immutable access to the Borrow<B> of a value. Read more
§

fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
where Self: BorrowMut<B>, B: ?Sized,

Mutable access to the BorrowMut<B> of a value. Read more
§

fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
where Self: AsRef<R>, R: ?Sized,

Immutable access to the AsRef<R> view of a value. Read more
§

fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
where Self: AsMut<R>, R: ?Sized,

Mutable access to the AsMut<R> view of a value. Read more
§

fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
where Self: Deref<Target = T>, T: ?Sized,

Immutable access to the Deref::Target of a value. Read more
§

fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
where Self: DerefMut<Target = T> + Deref, T: ?Sized,

Mutable access to the Deref::Target of a value. Read more
§

fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self

Calls .tap() only in debug builds, and is erased in release builds.
§

fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self

Calls .tap_mut() only in debug builds, and is erased in release builds.
§

fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
where Self: Borrow<B>, B: ?Sized,

Calls .tap_borrow() only in debug builds, and is erased in release builds.
§

fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
where Self: BorrowMut<B>, B: ?Sized,

Calls .tap_borrow_mut() only in debug builds, and is erased in release builds.
§

fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
where Self: AsRef<R>, R: ?Sized,

Calls .tap_ref() only in debug builds, and is erased in release builds.
§

fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
where Self: AsMut<R>, R: ?Sized,

Calls .tap_ref_mut() only in debug builds, and is erased in release builds.
§

fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
where Self: Deref<Target = T>, T: ?Sized,

Calls .tap_deref() only in debug builds, and is erased in release builds.
§

fn tap_deref_mut_dbg<T>(self, func: impl FnOnce(&mut T)) -> Self
where Self: DerefMut<Target = T> + Deref, T: ?Sized,

Calls .tap_deref_mut() only in debug builds, and is erased in release builds.
§

impl<T> TryConv for T

§

fn try_conv<T>(self) -> Result<T, Self::Error>
where Self: TryInto<T>,

Attempts to convert self into T using TryInto<T>. Read more
source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

source§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a [WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a [WithDispatch] wrapper. Read more