Struct valence::app::App

pub struct App {
    pub world: World,
    pub runner: Box<dyn FnOnce(App) + Send>,
    pub main_schedule_label: Interned<dyn ScheduleLabel>,
    /* private fields */
}
Expand description

A container of app logic and data.

Bundles together the necessary elements like World and Schedule to create an ECS-based application. It also stores a pointer to a runner function. The runner is responsible for managing the application’s event loop and applying the Schedule to the World to drive application logic.

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");
}

Fields§

§world: World

The main ECS World of the App. This stores and provides access to all the main data of the application. The systems of the App will run using this World. If additional separate World-Schedule pairs are needed, you can use sub_apps.

§runner: Box<dyn FnOnce(App) + Send>

The runner function is primarily responsible for managing the application’s event loop and advancing the Schedule. Typically, it is not configured manually, but set by one of Bevy’s built-in plugins. See bevy::winit::WinitPlugin and ScheduleRunnerPlugin.

§main_schedule_label: Interned<dyn ScheduleLabel>

The schedule that systems are added to by default.

The schedule that runs the main loop of schedule execution.

This is initially set to Main.

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.

This constructor should be used if you wish to provide custom scheduling, exit handling, cleanup, etc.

pub fn update(&mut self)

Advances the execution of the Schedule by one cycle.

This method also updates sub apps. See insert_sub_app for more details.

The schedule run by this method is determined by the main_schedule_label field. By default this is Main.

Panics

The active schedule of the app must be set before this method is called.

pub fn run(&mut self)

Starts the application by calling the app’s runner function.

Finalizes the App configuration. For general usage, see the example on the item level documentation.

run() might not return

Calls to App::run() might never return.

In simple and headless applications, one can expect that execution will proceed, normally, after calling run() but this is not the case for windowed applications.

Windowed apps are typically driven by an event loop or message loop and some window-manager APIs expect programs to terminate when their primary window is closed and that event loop terminates – behavior of processes that do not is often platform dependent or undocumented.

By default, Bevy uses the winit crate for window creation. See WinitSettings::return_from_run for further discussion of this topic and for a mechanism to require that App::run() does return – albeit one that carries its own caveats and disclaimers.

Panics

Panics if called from Plugin::build(), because it would prevent other plugins to properly build.

pub fn plugins_state(&self) -> PluginsState

Check the state of all plugins already added to this app. 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)

Run 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)

Run 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_state<S>(&mut self) -> &mut App
where S: States,

Adds State<S> and NextState<S> resources, OnEnter and OnExit schedules for each state variant (if they don’t already exist), an instance of apply_state_transition::<S> in StateTransition so that transitions happen before Update and a instance of run_enter_schedule::<S> in StateTransition with a run_once condition to run the on enter schedule of the initial state.

If you would like to control how other systems run based on the current state, you can emulate this behavior using the in_state Condition.

Note that you can also apply state transitions at other points in the schedule by adding the apply_state_transition system manually.

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

Adds a system 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 configure_set( &mut self, schedule: impl ScheduleLabel, set: impl IntoSystemSetConfigs ) -> &mut App

👎Deprecated since 0.12.0: Please use configure_sets instead.

Configures a system set in the default schedule, adding the set if it does not exist.

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

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

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

Setup the application to manage events of type T.

This is done by adding a Resource of type Events::<T>, and inserting an event_update_system into First.

See Events for defining events.

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

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

Inserts a Resource to the current App and overwrites any Resource previously added of the same type.

A Resource in Bevy represents globally unique data. Resources must be added to Bevy apps before using them. This happens with insert_resource.

See init_resource for Resources that implement Default or FromWorld.

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

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

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

Inserts a non-send resource to the app.

You usually want to use insert_resource, but there are some special cases when a resource cannot be sent across threads.

Examples
struct MyCounter {
    counter: usize,
}

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

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

Initialize a Resource with standard starting values by adding it to the World.

If the Resource already exists, nothing happens.

The Resource must implement the FromWorld trait. If the Default trait is implemented, the FromWorld trait will use the Default::default method to initialize the Resource.

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

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

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

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

Initialize a non-send Resource with standard starting values by adding it to the World.

The Resource must implement the FromWorld trait. If the Default trait is implemented, the FromWorld trait will use the Default::default method to initialize the Resource.

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

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

The runner function run_fn 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) {
    loop {
        println!("In main loop");
        app.update();
    }
}

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

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

Checks if a Plugin has already been added.

This can be used by plugins to check if a plugin they depend upon has already been added.

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

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

This can be used to read the settings of any already added plugins. This vector will be length zero 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

Adds one or more Plugins.

One of Bevy’s core principles is modularity. All Bevy engine features are implemented as Plugins. This includes internal features like the renderer.

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 was already 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(Reflect)]
#[reflect(Component, Serialize, Deserialize)] // will register ReflectComponent, ReflectSerialize, ReflectDeserialize

See [bevy_reflect::TypeRegistry::register].

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

Adds the type data D to type T in the TypeRegistry resource.

Most of the time App::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 sub_app_mut(&mut self, label: impl AppLabel) -> &mut App

Retrieves a SubApp stored inside this App.

Panics

Panics if the SubApp doesn’t exist.

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

Retrieves a SubApp inside this App with the given label, if it exists. Otherwise returns an Err containing the given label.

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

Retrieves a SubApp stored inside this App.

Panics

Panics if the SubApp doesn’t exist.

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

Inserts an existing sub app into the app

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

Removes a sub app from the app. Returns None if the label doesn’t exist.

pub fn get_sub_app(&self, label: impl AppLabel) -> Result<&App, impl AppLabel>

Retrieves a SubApp inside this App with the given label, if it exists. Otherwise returns an Err containing the given label.

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

Adds a new schedule to the App under the provided label.

Warning

This method will overwrite any existing schedule at that label. To avoid this behavior, use the init_schedule method instead.

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

Initializes a new empty schedule to the App under the provided label if it does not exists.

See App::add_schedule to pass in a pre-constructed schedule.

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

Gets read-only access to the Schedule with the provided label if it exists.

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

Gets read-write access to a Schedule with the provided label if it exists.

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

Applies the function to 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();

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 !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

§

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>,

§

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>,

§

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