#resources #bevy #prototype #tuple #proto #api #nothing

bevy_proto_resource_tuples

A prototype for a new resources API in bevy

1 unstable release

0.1.0 Apr 19, 2023

#35 in #prototype

MIT/Apache

29KB
91 lines

A prototype for working with Resources in groups.

Initial PR

Usage

use bevy::prelude::*;
use bevy_proto_resource_tuples::*;

#[derive(Resource)]
struct ResourceA;

#[derive(Resource)]
struct ResourceB;

#[derive(Resource, Default)]
struct ResourceC;

#[derive(Resource, Default)]
struct ResourceD;

fn main() {
    App::new()
        .insert_resources((ResourceA, ResourceB))
        .init_resources::<(ResourceC, ResourceD)>()
        .run();
}

Motivation

With Bevy 0.10 and the upcoming 0.11 releases, it is possible to use add_systems to add multiple systems at once, instead of making multiple calls to add_system. Likewise, there are changes underway to add multiple plugins at once.

Just as those interfaces were changed to minimize calls, init_resource and insert_resource calls can also be minimized, in order for the interface to be homogenous.

This is a bit controversial; the primary concern is that by grouping resources, it in a way implies that resources form "groups", rather than being separate objects. This differs from groups of systems, where there are operations over groups of systems, while there aren't any operations to be done over groups of resources, since they are each unique pieces of data.

It appears that some view add_systems as a tool only for working with groups of systems that have common attributes (and then making separate calls for unique systems), while others see it as a tool for adding systems in batch.

In reality, there is nothing stopping anyone from using add_systems either way. But from the perspective of those who use it simply to batch calls and lower LOC, the lack of insert_resources and init_resources feels rather inconsistent. Also, if these methods were added, there's nothing stopping users from making separate calls like before.

tl;dr: The benefit of these methods is that they bring consistency and usability without preventing users from doing stuff in the old style or mixing styles to what feels appropriate.

tl;dr for the tl;dr: More user freedom.

Limitations

Because this prototype is a separate crate, I can't implement the traits for the base case (P0) due to orphan rules. So when working with a single resource, it's necessary to call init_resource/insert_resource.

Patterns

The following are some patterns enabled by these changes. Whether or not they are useful is up to users to discover in practice. Either way, these are very niche, but perhaps they have some use cases.

// It's now possible to init many resources and get their ids all at once.
let [a, b, c] = world.init_resources::<(A, B, C)>();
// It's possible to create type aliases for multiple resources.
type MyResources<T> = (Foo<T>, Bar<T>);

app.init_resources(MyResources<i32>);

Dependencies

~8–16MB
~194K SLoC