Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use scenes to serialize and deserialize resources #3576

Closed
alice-i-cecile opened this issue Jan 6, 2022 · 1 comment · Fixed by #6846
Closed

Use scenes to serialize and deserialize resources #3576

alice-i-cecile opened this issue Jan 6, 2022 · 1 comment · Fixed by #6846
Labels
A-Scenes Serialized ECS data stored on the disk C-Feature A new feature, making something new possible

Comments

@alice-i-cecile
Copy link
Member

Problem

Serializing and deserializing resources is a common and important task. Currently, this must be done manually.

However, we already have a tool for this serialization: Scenes. Each Scene stores a World, which (now) includes resources, but the rest of the machinery is missing.

Proposed solution

Update the Scene machinery to handle resources as well. This should be reasonably straightforward (we can reflect resources, and we get access to the whole world when loading / saving / storing scenes), but fleshing out the rest of the API will be a fair bit of work.

The hardest part will be updating the serde .ron format: this presumes that only entities are included.

Our scene example should also be updated to show how to serialize / deserialize resources.

Alternatives considered

We could make a distinct serialization strategy for resources. This makes sense to include as part of scenes because:

  1. Common uses of scenes (saving / loading games, grabbing scenes from editors, networking) often include critical resources (current score, global illumination settings, difficulty settings) that should be logically batched together.
  2. Refactoring between entities and resources is very common, and two seperate strategies would cause frustrating refactoring pain.
  3. We're already storing a World everywhere for scenes.

Context

Before #1144, the World only stored entities and components. This code hasn't been updated to work for resources too yet.

@alice-i-cecile alice-i-cecile added C-Feature A new feature, making something new possible A-Scenes Serialized ECS data stored on the disk labels Jan 6, 2022
@Davier
Copy link
Contributor

Davier commented Jan 7, 2022

we can reflect resources

I don't think we can actually.

I'm interested in fixing this. These should be the implementation steps:

  • create ReflectResource (something like Add reflection for resources #1260, but updated and with change detection)
  • add #derive(Reflect), and #reflect(Resource) to bevy's relevant resources
  • add resources to DynamicScenes
  • add resources to SceneSerializer and SceneDeserializer

bors bot pushed a commit that referenced this issue Jul 4, 2022
# Objective

We don't have reflection for resources.

## Solution

Introduce reflection for resources.

Continues #3580 (by @Davier), related to #3576.

---

## Changelog

### Added

* Reflection on a resource type (by adding `ReflectResource`):

```rust
#[derive(Reflect)]
#[reflect(Resource)]
struct MyResourse;
```

### Changed

* Rename `ReflectComponent::add_component` into `ReflectComponent::insert_component` for consistency.

## Migration Guide

* Rename `ReflectComponent::add_component` into `ReflectComponent::insert_component`.
inodentry pushed a commit to IyesGames/bevy that referenced this issue Aug 8, 2022
# Objective

We don't have reflection for resources.

## Solution

Introduce reflection for resources.

Continues bevyengine#3580 (by @Davier), related to bevyengine#3576.

---

## Changelog

### Added

* Reflection on a resource type (by adding `ReflectResource`):

```rust
#[derive(Reflect)]
#[reflect(Resource)]
struct MyResourse;
```

### Changed

* Rename `ReflectComponent::add_component` into `ReflectComponent::insert_component` for consistency.

## Migration Guide

* Rename `ReflectComponent::add_component` into `ReflectComponent::insert_component`.
james7132 pushed a commit to james7132/bevy that referenced this issue Oct 28, 2022
# Objective

We don't have reflection for resources.

## Solution

Introduce reflection for resources.

Continues bevyengine#3580 (by @Davier), related to bevyengine#3576.

---

## Changelog

### Added

* Reflection on a resource type (by adding `ReflectResource`):

```rust
#[derive(Reflect)]
#[reflect(Resource)]
struct MyResourse;
```

### Changed

* Rename `ReflectComponent::add_component` into `ReflectComponent::insert_component` for consistency.

## Migration Guide

* Rename `ReflectComponent::add_component` into `ReflectComponent::insert_component`.
ItsDoot pushed a commit to ItsDoot/bevy that referenced this issue Feb 1, 2023
# Objective

We don't have reflection for resources.

## Solution

Introduce reflection for resources.

Continues bevyengine#3580 (by @Davier), related to bevyengine#3576.

---

## Changelog

### Added

* Reflection on a resource type (by adding `ReflectResource`):

```rust
#[derive(Reflect)]
#[reflect(Resource)]
struct MyResourse;
```

### Changed

* Rename `ReflectComponent::add_component` into `ReflectComponent::insert_component` for consistency.

## Migration Guide

* Rename `ReflectComponent::add_component` into `ReflectComponent::insert_component`.
cart added a commit that referenced this issue Mar 20, 2023
# Objective

Co-Authored-By: davier
[bricedavier@gmail.com](mailto:bricedavier@gmail.com)
Fixes #3576.
Adds a `resources` field in scene serialization data to allow
de/serializing resources that have reflection enabled.

## Solution

Most of this code is taken from a previous closed PR:
#3580. Most of the credit goes to
@Davier , what I did was mostly getting it to work on the latest main
branch of Bevy, along with adding a few asserts in the currently
existing tests to be sure everything is working properly.

This PR changes the scene format to include resources in this way:
```
(
  resources: {
    // List of resources here, keyed by resource type name.
  },
  entities: [
    // Previous scene format here
  ],
)
```

An example taken from the tests:
```
(
  resources: {
    "bevy_scene::serde::tests::MyResource": (
      foo: 123,
    ),
  },
  entities: {
    // Previous scene format here
  },
)
```
For this, a `resources` fields has been added on the `DynamicScene` and
the `DynamicSceneBuilder` structs. The latter now also has a method
named `extract_resources` to properly extract the existing resources
registered in the local type registry, in a similar way to
`extract_entities`.


---

## Changelog


Added: Reflect resources registered in the type registry used by dynamic
scenes will now be properly de/serialized in scene data.

## Migration Guide

Since the scene format has been changed, the user may not be able to use
scenes saved prior to this PR due to the `resources` scene field being
missing. ~~To preserve backwards compatibility, I will try to make the
`resources` fully optional so that old scenes can be loaded without
issue.~~

## TODOs

- [x] I may have to update a few doc blocks still referring to dynamic
scenes as mere container of entities, since they now include resources
as well.
- [x] ~~I want to make the `resources` key optional, as specified in the
Migration Guide, so that old scenes will be compatible with this
change.~~ Since this would only be trivial for ron format, I think it
might be better to consider it in a separate PR/discussion to figure out
if it could be done for binary serialization too.
- [x] I suppose it might be a good idea to add a resources in the scene
example so that users will quickly notice they can serialize resources
just like entities.

---------

Co-authored-by: Carter Anderson <mcanders1@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-Scenes Serialized ECS data stored on the disk C-Feature A new feature, making something new possible
Projects
None yet
2 participants