bevy_app

Struct App

Source
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§

Source§

impl App

Source

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.

Source

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.

Source

pub fn update(&mut self)

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

Source

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.

Source

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

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);
Source

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.

Source

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.

Source

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.

Source

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

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));
Source

pub fn register_system<I, O, M>( &mut self, system: impl IntoSystem<I, O, M> + 'static, ) -> SystemId<I, O>
where I: SystemInput + 'static, O: '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.

Source

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

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

Source

pub fn add_event<T>(&mut self) -> &mut Self
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>();
Source

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

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

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

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>();
Source

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

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

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

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.

Source

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

Returns true if the Plugin has already been added.

Source

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;
Source

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

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.

Source

pub fn register_type<T: GetTypeRegistration>(&mut self) -> &mut Self

Available on crate feature bevy_reflect only.

Registers the type T in the AppTypeRegistry 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.

Source

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

Available on crate feature bevy_reflect only.

Associates type data D with type T in the AppTypeRegistry 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.

Source

pub fn register_required_components<T: Component, R: Component + Default>( &mut self, ) -> &mut Self

Registers the given component R as a required component for T.

When T is added to an entity, R and its own required components will also be added if R was not already provided. The Default constructor will be used for the creation of R. If a custom constructor is desired, use App::register_required_components_with instead.

For the non-panicking version, see App::try_register_required_components.

Note that requirements must currently be registered before T is inserted into the world for the first time. Commonly, this is done in plugins. This limitation may be fixed in the future.

§Panics

Panics if R is already a directly required component for T, or if T has ever been added on an entity before the registration.

Indirect requirements through other components are allowed. In those cases, any existing requirements will only be overwritten if the new requirement is more specific.

§Example
#[derive(Component)]
struct A;

#[derive(Component, Default, PartialEq, Eq, Debug)]
struct B(usize);

#[derive(Component, Default, PartialEq, Eq, Debug)]
struct C(u32);

// Register B as required by A and C as required by B.
app.register_required_components::<A, B>();
app.register_required_components::<B, C>();

fn setup(mut commands: Commands) {
    // This will implicitly also insert B and C with their Default constructors.
    commands.spawn(A);
}

fn validate(query: Option<Single<(&A, &B, &C)>>) {
    let (a, b, c) = query.unwrap().into_inner();
    assert_eq!(b, &B(0));
    assert_eq!(c, &C(0));
}
Source

pub fn register_required_components_with<T: Component, R: Component>( &mut self, constructor: fn() -> R, ) -> &mut Self

Registers the given component R as a required component for T.

When T is added to an entity, R and its own required components will also be added if R was not already provided. The given constructor will be used for the creation of R. If a Default constructor is desired, use App::register_required_components instead.

For the non-panicking version, see App::try_register_required_components_with.

Note that requirements must currently be registered before T is inserted into the world for the first time. Commonly, this is done in plugins. This limitation may be fixed in the future.

§Panics

Panics if R is already a directly required component for T, or if T has ever been added on an entity before the registration.

Indirect requirements through other components are allowed. In those cases, any existing requirements will only be overwritten if the new requirement is more specific.

§Example
#[derive(Component)]
struct A;

#[derive(Component, Default, PartialEq, Eq, Debug)]
struct B(usize);

#[derive(Component, Default, PartialEq, Eq, Debug)]
struct C(u32);

// Register B and C as required by A and C as required by B.
// A requiring C directly will overwrite the indirect requirement through B.
app.register_required_components::<A, B>();
app.register_required_components_with::<B, C>(|| C(1));
app.register_required_components_with::<A, C>(|| C(2));

fn setup(mut commands: Commands) {
    // This will implicitly also insert B with its Default constructor and C
    // with the custom constructor defined by A.
    commands.spawn(A);
}

fn validate(query: Option<Single<(&A, &B, &C)>>) {
    let (a, b, c) = query.unwrap().into_inner();
    assert_eq!(b, &B(0));
    assert_eq!(c, &C(2));
}
Source

pub fn try_register_required_components<T: Component, R: Component + Default>( &mut self, ) -> Result<(), RequiredComponentsError>

Tries to register the given component R as a required component for T.

When T is added to an entity, R and its own required components will also be added if R was not already provided. The Default constructor will be used for the creation of R. If a custom constructor is desired, use App::register_required_components_with instead.

For the panicking version, see App::register_required_components.

Note that requirements must currently be registered before T is inserted into the world for the first time. Commonly, this is done in plugins. This limitation may be fixed in the future.

§Errors

Returns a RequiredComponentsError if R is already a directly required component for T, or if T has ever been added on an entity before the registration.

Indirect requirements through other components are allowed. In those cases, any existing requirements will only be overwritten if the new requirement is more specific.

§Example
#[derive(Component)]
struct A;

#[derive(Component, Default, PartialEq, Eq, Debug)]
struct B(usize);

#[derive(Component, Default, PartialEq, Eq, Debug)]
struct C(u32);

// Register B as required by A and C as required by B.
app.register_required_components::<A, B>();
app.register_required_components::<B, C>();

// Duplicate registration! This will fail.
assert!(app.try_register_required_components::<A, B>().is_err());

fn setup(mut commands: Commands) {
    // This will implicitly also insert B and C with their Default constructors.
    commands.spawn(A);
}

fn validate(query: Option<Single<(&A, &B, &C)>>) {
    let (a, b, c) = query.unwrap().into_inner();
    assert_eq!(b, &B(0));
    assert_eq!(c, &C(0));
}
Source

pub fn try_register_required_components_with<T: Component, R: Component>( &mut self, constructor: fn() -> R, ) -> Result<(), RequiredComponentsError>

Tries to register the given component R as a required component for T.

When T is added to an entity, R and its own required components will also be added if R was not already provided. The given constructor will be used for the creation of R. If a Default constructor is desired, use App::register_required_components instead.

For the panicking version, see App::register_required_components_with.

Note that requirements must currently be registered before T is inserted into the world for the first time. Commonly, this is done in plugins. This limitation may be fixed in the future.

§Errors

Returns a RequiredComponentsError if R is already a directly required component for T, or if T has ever been added on an entity before the registration.

Indirect requirements through other components are allowed. In those cases, any existing requirements will only be overwritten if the new requirement is more specific.

§Example
#[derive(Component)]
struct A;

#[derive(Component, Default, PartialEq, Eq, Debug)]
struct B(usize);

#[derive(Component, Default, PartialEq, Eq, Debug)]
struct C(u32);

// Register B and C as required by A and C as required by B.
// A requiring C directly will overwrite the indirect requirement through B.
app.register_required_components::<A, B>();
app.register_required_components_with::<B, C>(|| C(1));
app.register_required_components_with::<A, C>(|| C(2));

// Duplicate registration! Even if the constructors were different, this would fail.
assert!(app.try_register_required_components_with::<B, C>(|| C(1)).is_err());

fn setup(mut commands: Commands) {
    // This will implicitly also insert B with its Default constructor and C
    // with the custom constructor defined by A.
    commands.spawn(A);
}

fn validate(query: Option<Single<(&A, &B, &C)>>) {
    let (a, b, c) = query.unwrap().into_inner();
    assert_eq!(b, &B(0));
    assert_eq!(c, &C(2));
}
Source

pub fn world(&self) -> &World

Returns a reference to the main SubApp’s World. This is the same as calling app.main().world().

Source

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

Returns a mutable reference to the main SubApp’s World. This is the same as calling app.main_mut().world_mut().

Source

pub fn main(&self) -> &SubApp

Returns a reference to the main SubApp.

Source

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

Returns a mutable reference to the main SubApp.

Source

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.

Source

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.

Source

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

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

Source

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.

Source

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

Inserts a SubApp with the given label.

Source

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

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

Source

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.

Source

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

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

Source

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

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

See add_schedule to insert an existing schedule.

Source

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

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

Source

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.

Source

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

Runs function f with the Schedule associated with label.

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

Source

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

Applies the provided ScheduleBuildSettings to all schedules.

Source

pub fn allow_ambiguous_component<T: Component>(&mut self) -> &mut Self

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();
Source

pub fn allow_ambiguous_resource<T: Resource>(&mut self) -> &mut Self

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();
Source

pub fn ignore_ambiguity<M1, M2, S1, S2>( &mut self, schedule: impl ScheduleLabel, a: S1, b: S2, ) -> &mut Self
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.

Source

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.

Source

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

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

§Examples
// An observer system can be any system where the first parameter is a trigger
app.add_observer(|trigger: Trigger<Party>, friends: Query<Entity, With<Friend>>, mut commands: Commands| {
    if trigger.event().friends_allowed {
        for friend in friends.iter() {
            commands.trigger_targets(Invite, friend);
        }
    }
});

Trait Implementations§

Source§

impl Debug for App

Source§

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

Formats the value using the given formatter. Read more
Source§

impl Default for App

Source§

fn default() -> Self

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
Source§

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

Source§

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.
Source§

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.
Source§

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.
Source§

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.
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

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

Source§

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

Creates Self using default().

Source§

impl<T> Instrument for T

Source§

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

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

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.

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.
Source§

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

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

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
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

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