bevy/crates/bevy_app/src
Joseph d66c868e6f
Expressively define plugins using functions (#11080)
# Objective

Plugins are an incredible tool for encapsulating functionality. They are
low-key one of Bevy's best features. Combined with rust's module and
privacy system, it's a match made in heaven.

The one downside is that they can be a little too verbose to define. 90%
of all plugin definitions look something like this:

```rust
pub struct MyPlugin;

impl Plugin for MyPlugin {
    fn build(&self, app: &mut App) {
        app.init_resource::<CameraAssets>()
           .add_event::<SetCamera>()
           .add_systems(Update, (collect_set_camera_events, drive_camera).chain());
    }
}
```

Every so often it gets a little spicier:

```rust
pub struct MyGenericPlugin<T>(PhantomData<T>);

impl<T> Default for MyGenericPlugin<T> { 
    fn default() -> Self { ... }
 }

impl<T> Plugin for MyGenericPlugin<T> { ... }
```

This is an annoying amount of boilerplate. Ideally, plugins should be
focused and small in scope, which means any app is going to have a *lot*
of them. Writing a plugin should be as easy as possible, and the *only*
part of this process that carries any meaning is the body of `fn build`.

## Solution

Implement `Plugin` for functions that take `&mut App` as a parameter.

The two examples above now look like this:

```rust
pub fn my_plugin(app: &mut App) {
    app.init_resource::<CameraAssets>()
       .add_event::<SetCamera>()
       .add_systems(Update, (collect_set_camera_events, drive_camera).chain());
} 

pub fn my_generic_plugin<T>(app: &mut App) {
    // No need for PhantomData, it just works.
}
```

Almost all plugins can be written this way, which I believe will make
bevy code much more attractive. Less boilerplate and less meaningless
indentation. More plugins with smaller scopes.

---

## Changelog

The `Plugin` trait is now implemented for all functions that take `&mut
App` as their only parameter. This is an abbreviated way of defining
plugins with less boilerplate than manually implementing the trait.

---------

Co-authored-by: Federico Rinaldi <gisquerin@gmail.com>
2024-01-27 02:40:15 +00:00
..
app.rs Rename Schedule::name to Schedule::label (#11531) 2024-01-25 19:13:23 +00:00
ci_testing.rs Take example screenshots in CI (#8488) 2023-05-01 18:00:01 +00:00
lib.rs Add First/Pre/Post/Last schedules to the Fixed timestep (#10977) 2023-12-14 04:35:40 +00:00
main_schedule.rs Explain where rendering is (#11018) 2024-01-08 23:02:46 +00:00
plugin.rs Expressively define plugins using functions (#11080) 2024-01-27 02:40:15 +00:00
plugin_group.rs Replace or document ignored doctests (#11040) 2024-01-01 16:50:56 +00:00
schedule_runner.rs Revert App::run() behavior/Remove winit specific code from bevy_app (#10389) 2023-11-16 21:50:17 +00:00