You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Store Resources as components on singleton entities (#20934)
This is part of #19731.
# Resources as Components
## Motivation
More things should be entities. This simplifies the API, the lower-level
implementation and the tools we have for entities and components can be
used for other things in the engine. In particular, for resources, it is
really handy to have observers, which we currently don't have. See
#20821 under 1A, for a more specific use.
## Current Work
This removes the `resources` field from the world storage and instead
store the resources on singleton entities. For easy lookup, we add a
`HashMap<ComponentId, Entity>` to `World`, in order to quickly find the
singleton entity where the resource is stored.
Because we store resources on entities, we derive `Component` alongside
`Resource`, this means that
```rust
#[derive(Resource)]
struct Foo;
```
turns into
```rust
#[derive(Resource, Component)]
struct Foo;
```
This was also done for reflections, meaning that
```rust
#[derive(Resource, Reflect)]
#[refect(Resource)]
struct Bar;
```
becomes
```rust
#[derive(Resource, Component, Reflect)]
#[refect(Resource, Component)]
struct Bar;
```
In order to distinguish resource entities, they are tagged with the
`IsResource` component. Additionally, to ensure that they aren't queried
by accident, they are also tagged as being internal entities, which
means that they don't show up in queries by default.
## Drawbacks
- Currently you can't have a struct that is both a `Resource` and a
`Component`, because `Resource` expands to also implement `Component`,
this means that this throws a compiler error as it's implemented twice.
- Because every reflected Resource must also implement
`ReflectComponent` you need to import
`bevy_ecs::reflect::ReflectComponent` every time you use
`#[reflect(Resource)]`. This is kind of unintuitive.
## Future Work
- Simplify `Access` in the ECS, to only deal with components (and not
components *and* resources).
- Newtype `Res<Resource>` to `Single<Ref<Resource>>` (or something
similair).
- Eliminate `ReflectResource`.
- Take stabs at simplifying the public facing API.
---------
Co-authored-by: Carter Anderson <mcanders1@gmail.com>
Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
Co-authored-by: Dimitrios Loukadakis <dloukadakis@users.noreply.github.com>
0 commit comments