bevy/assets/scenes/load_scene_example.scn.ron

38 lines
856 B
Text
Raw Normal View History

(
(De) serialize resources in scenes (#6846) # 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: https://github.com/bevyengine/bevy/pull/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>
2023-03-20 21:17:02 +00:00
resources: {
"scene::ResourceA": (
score: 1,
(De) serialize resources in scenes (#6846) # 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: https://github.com/bevyengine/bevy/pull/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>
2023-03-20 21:17:02 +00:00
),
},
entities: {
4294967296: (
bevy_scene: Use map for scene `components` (#6345) # Objective Currently scenes define components using a list: ```rust [ ( entity: 0, components: [ { "bevy_transform::components::transform::Transform": ( translation: ( x: 0.0, y: 0.0, z: 0.0 ), rotation: (0.0, 0.0, 0.0, 1.0), scale: ( x: 1.0, y: 1.0, z: 1.0 ), ), }, { "my_crate::Foo": ( text: "Hello World", ), }, { "my_crate::Bar": ( baz: 123, ), }, ], ), ] ``` However, this representation has some drawbacks (as pointed out by @Metadorius in [this](https://github.com/bevyengine/bevy/pull/4561#issuecomment-1202215565) comment): 1. Increased nesting and more characters (minor effect on overall size) 2. More importantly, by definition, entities cannot have more than one instance of any given component. Therefore, such data is best stored as a map— where all values are meant to have unique keys. ## Solution Change `components` to store a map of components rather than a list: ```rust [ ( entity: 0, components: { "bevy_transform::components::transform::Transform": ( translation: ( x: 0.0, y: 0.0, z: 0.0 ), rotation: (0.0, 0.0, 0.0, 1.0), scale: ( x: 1.0, y: 1.0, z: 1.0 ), ), "my_crate::Foo": ( text: "Hello World", ), "my_crate::Bar": ( baz: 123 ), }, ), ] ``` #### Code Representation This change only affects the scene format itself. `DynamicEntity` still stores its components as a list. The reason for this is that storing such data as a map is not really needed since: 1. The "key" of each value is easily found by just calling `Reflect::type_name` on it 2. We should be generating such structs using the `World` itself which upholds the one-component-per-entity rule One could in theory create manually create a `DynamicEntity` with duplicate components, but this isn't something I think we should focus on in this PR. `DynamicEntity` can be broken in other ways (i.e. storing a non-component in the components list), and resolving its issues can be done in a separate PR. --- ## Changelog * The scene format now uses a map to represent the collection of components rather than a list ## Migration Guide The scene format now uses a map to represent the collection of components. Scene files will need to update from the old list format. <details> <summary>Example Code</summary> ```rust // OLD [ ( entity: 0, components: [ { "bevy_transform::components::transform::Transform": ( translation: ( x: 0.0, y: 0.0, z: 0.0 ), rotation: (0.0, 0.0, 0.0, 1.0), scale: ( x: 1.0, y: 1.0, z: 1.0 ), ), }, { "my_crate::Foo": ( text: "Hello World", ), }, { "my_crate::Bar": ( baz: 123, ), }, ], ), ] // NEW [ ( entity: 0, components: { "bevy_transform::components::transform::Transform": ( translation: ( x: 0.0, y: 0.0, z: 0.0 ), rotation: (0.0, 0.0, 0.0, 1.0), scale: ( x: 1.0, y: 1.0, z: 1.0 ), ), "my_crate::Foo": ( text: "Hello World", ), "my_crate::Bar": ( baz: 123 ), }, ), ] ``` </details>
2022-10-27 01:46:33 +00:00
components: {
"bevy_core::name::Name": (
hash: 17588334858059901562,
name: "joe",
bevy_scene: Use map for scene `components` (#6345) # Objective Currently scenes define components using a list: ```rust [ ( entity: 0, components: [ { "bevy_transform::components::transform::Transform": ( translation: ( x: 0.0, y: 0.0, z: 0.0 ), rotation: (0.0, 0.0, 0.0, 1.0), scale: ( x: 1.0, y: 1.0, z: 1.0 ), ), }, { "my_crate::Foo": ( text: "Hello World", ), }, { "my_crate::Bar": ( baz: 123, ), }, ], ), ] ``` However, this representation has some drawbacks (as pointed out by @Metadorius in [this](https://github.com/bevyengine/bevy/pull/4561#issuecomment-1202215565) comment): 1. Increased nesting and more characters (minor effect on overall size) 2. More importantly, by definition, entities cannot have more than one instance of any given component. Therefore, such data is best stored as a map— where all values are meant to have unique keys. ## Solution Change `components` to store a map of components rather than a list: ```rust [ ( entity: 0, components: { "bevy_transform::components::transform::Transform": ( translation: ( x: 0.0, y: 0.0, z: 0.0 ), rotation: (0.0, 0.0, 0.0, 1.0), scale: ( x: 1.0, y: 1.0, z: 1.0 ), ), "my_crate::Foo": ( text: "Hello World", ), "my_crate::Bar": ( baz: 123 ), }, ), ] ``` #### Code Representation This change only affects the scene format itself. `DynamicEntity` still stores its components as a list. The reason for this is that storing such data as a map is not really needed since: 1. The "key" of each value is easily found by just calling `Reflect::type_name` on it 2. We should be generating such structs using the `World` itself which upholds the one-component-per-entity rule One could in theory create manually create a `DynamicEntity` with duplicate components, but this isn't something I think we should focus on in this PR. `DynamicEntity` can be broken in other ways (i.e. storing a non-component in the components list), and resolving its issues can be done in a separate PR. --- ## Changelog * The scene format now uses a map to represent the collection of components rather than a list ## Migration Guide The scene format now uses a map to represent the collection of components. Scene files will need to update from the old list format. <details> <summary>Example Code</summary> ```rust // OLD [ ( entity: 0, components: [ { "bevy_transform::components::transform::Transform": ( translation: ( x: 0.0, y: 0.0, z: 0.0 ), rotation: (0.0, 0.0, 0.0, 1.0), scale: ( x: 1.0, y: 1.0, z: 1.0 ), ), }, { "my_crate::Foo": ( text: "Hello World", ), }, { "my_crate::Bar": ( baz: 123, ), }, ], ), ] // NEW [ ( entity: 0, components: { "bevy_transform::components::transform::Transform": ( translation: ( x: 0.0, y: 0.0, z: 0.0 ), rotation: (0.0, 0.0, 0.0, 1.0), scale: ( x: 1.0, y: 1.0, z: 1.0 ), ), "my_crate::Foo": ( text: "Hello World", ), "my_crate::Bar": ( baz: 123 ), }, ), ] ``` </details>
2022-10-27 01:46:33 +00:00
),
"bevy_transform::components::global_transform::GlobalTransform": ((1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0)),
"bevy_transform::components::transform::Transform": (
translation: (0.0, 0.0, 0.0),
rotation: (0.0, 0.0, 0.0, 1.0),
scale: (1.0, 1.0, 1.0),
bevy_scene: Use map for scene `components` (#6345) # Objective Currently scenes define components using a list: ```rust [ ( entity: 0, components: [ { "bevy_transform::components::transform::Transform": ( translation: ( x: 0.0, y: 0.0, z: 0.0 ), rotation: (0.0, 0.0, 0.0, 1.0), scale: ( x: 1.0, y: 1.0, z: 1.0 ), ), }, { "my_crate::Foo": ( text: "Hello World", ), }, { "my_crate::Bar": ( baz: 123, ), }, ], ), ] ``` However, this representation has some drawbacks (as pointed out by @Metadorius in [this](https://github.com/bevyengine/bevy/pull/4561#issuecomment-1202215565) comment): 1. Increased nesting and more characters (minor effect on overall size) 2. More importantly, by definition, entities cannot have more than one instance of any given component. Therefore, such data is best stored as a map— where all values are meant to have unique keys. ## Solution Change `components` to store a map of components rather than a list: ```rust [ ( entity: 0, components: { "bevy_transform::components::transform::Transform": ( translation: ( x: 0.0, y: 0.0, z: 0.0 ), rotation: (0.0, 0.0, 0.0, 1.0), scale: ( x: 1.0, y: 1.0, z: 1.0 ), ), "my_crate::Foo": ( text: "Hello World", ), "my_crate::Bar": ( baz: 123 ), }, ), ] ``` #### Code Representation This change only affects the scene format itself. `DynamicEntity` still stores its components as a list. The reason for this is that storing such data as a map is not really needed since: 1. The "key" of each value is easily found by just calling `Reflect::type_name` on it 2. We should be generating such structs using the `World` itself which upholds the one-component-per-entity rule One could in theory create manually create a `DynamicEntity` with duplicate components, but this isn't something I think we should focus on in this PR. `DynamicEntity` can be broken in other ways (i.e. storing a non-component in the components list), and resolving its issues can be done in a separate PR. --- ## Changelog * The scene format now uses a map to represent the collection of components rather than a list ## Migration Guide The scene format now uses a map to represent the collection of components. Scene files will need to update from the old list format. <details> <summary>Example Code</summary> ```rust // OLD [ ( entity: 0, components: [ { "bevy_transform::components::transform::Transform": ( translation: ( x: 0.0, y: 0.0, z: 0.0 ), rotation: (0.0, 0.0, 0.0, 1.0), scale: ( x: 1.0, y: 1.0, z: 1.0 ), ), }, { "my_crate::Foo": ( text: "Hello World", ), }, { "my_crate::Bar": ( baz: 123, ), }, ], ), ] // NEW [ ( entity: 0, components: { "bevy_transform::components::transform::Transform": ( translation: ( x: 0.0, y: 0.0, z: 0.0 ), rotation: (0.0, 0.0, 0.0, 1.0), scale: ( x: 1.0, y: 1.0, z: 1.0 ), ), "my_crate::Foo": ( text: "Hello World", ), "my_crate::Bar": ( baz: 123 ), }, ), ] ``` </details>
2022-10-27 01:46:33 +00:00
),
"scene::ComponentA": (
x: 1.0,
y: 2.0,
),
"scene::ComponentB": (
value: "hello",
),
bevy_scene: Use map for scene `components` (#6345) # Objective Currently scenes define components using a list: ```rust [ ( entity: 0, components: [ { "bevy_transform::components::transform::Transform": ( translation: ( x: 0.0, y: 0.0, z: 0.0 ), rotation: (0.0, 0.0, 0.0, 1.0), scale: ( x: 1.0, y: 1.0, z: 1.0 ), ), }, { "my_crate::Foo": ( text: "Hello World", ), }, { "my_crate::Bar": ( baz: 123, ), }, ], ), ] ``` However, this representation has some drawbacks (as pointed out by @Metadorius in [this](https://github.com/bevyengine/bevy/pull/4561#issuecomment-1202215565) comment): 1. Increased nesting and more characters (minor effect on overall size) 2. More importantly, by definition, entities cannot have more than one instance of any given component. Therefore, such data is best stored as a map— where all values are meant to have unique keys. ## Solution Change `components` to store a map of components rather than a list: ```rust [ ( entity: 0, components: { "bevy_transform::components::transform::Transform": ( translation: ( x: 0.0, y: 0.0, z: 0.0 ), rotation: (0.0, 0.0, 0.0, 1.0), scale: ( x: 1.0, y: 1.0, z: 1.0 ), ), "my_crate::Foo": ( text: "Hello World", ), "my_crate::Bar": ( baz: 123 ), }, ), ] ``` #### Code Representation This change only affects the scene format itself. `DynamicEntity` still stores its components as a list. The reason for this is that storing such data as a map is not really needed since: 1. The "key" of each value is easily found by just calling `Reflect::type_name` on it 2. We should be generating such structs using the `World` itself which upholds the one-component-per-entity rule One could in theory create manually create a `DynamicEntity` with duplicate components, but this isn't something I think we should focus on in this PR. `DynamicEntity` can be broken in other ways (i.e. storing a non-component in the components list), and resolving its issues can be done in a separate PR. --- ## Changelog * The scene format now uses a map to represent the collection of components rather than a list ## Migration Guide The scene format now uses a map to represent the collection of components. Scene files will need to update from the old list format. <details> <summary>Example Code</summary> ```rust // OLD [ ( entity: 0, components: [ { "bevy_transform::components::transform::Transform": ( translation: ( x: 0.0, y: 0.0, z: 0.0 ), rotation: (0.0, 0.0, 0.0, 1.0), scale: ( x: 1.0, y: 1.0, z: 1.0 ), ), }, { "my_crate::Foo": ( text: "Hello World", ), }, { "my_crate::Bar": ( baz: 123, ), }, ], ), ] // NEW [ ( entity: 0, components: { "bevy_transform::components::transform::Transform": ( translation: ( x: 0.0, y: 0.0, z: 0.0 ), rotation: (0.0, 0.0, 0.0, 1.0), scale: ( x: 1.0, y: 1.0, z: 1.0 ), ), "my_crate::Foo": ( text: "Hello World", ), "my_crate::Bar": ( baz: 123 ), }, ), ] ``` </details>
2022-10-27 01:46:33 +00:00
},
),
4294967297: (
bevy_scene: Use map for scene `components` (#6345) # Objective Currently scenes define components using a list: ```rust [ ( entity: 0, components: [ { "bevy_transform::components::transform::Transform": ( translation: ( x: 0.0, y: 0.0, z: 0.0 ), rotation: (0.0, 0.0, 0.0, 1.0), scale: ( x: 1.0, y: 1.0, z: 1.0 ), ), }, { "my_crate::Foo": ( text: "Hello World", ), }, { "my_crate::Bar": ( baz: 123, ), }, ], ), ] ``` However, this representation has some drawbacks (as pointed out by @Metadorius in [this](https://github.com/bevyengine/bevy/pull/4561#issuecomment-1202215565) comment): 1. Increased nesting and more characters (minor effect on overall size) 2. More importantly, by definition, entities cannot have more than one instance of any given component. Therefore, such data is best stored as a map— where all values are meant to have unique keys. ## Solution Change `components` to store a map of components rather than a list: ```rust [ ( entity: 0, components: { "bevy_transform::components::transform::Transform": ( translation: ( x: 0.0, y: 0.0, z: 0.0 ), rotation: (0.0, 0.0, 0.0, 1.0), scale: ( x: 1.0, y: 1.0, z: 1.0 ), ), "my_crate::Foo": ( text: "Hello World", ), "my_crate::Bar": ( baz: 123 ), }, ), ] ``` #### Code Representation This change only affects the scene format itself. `DynamicEntity` still stores its components as a list. The reason for this is that storing such data as a map is not really needed since: 1. The "key" of each value is easily found by just calling `Reflect::type_name` on it 2. We should be generating such structs using the `World` itself which upholds the one-component-per-entity rule One could in theory create manually create a `DynamicEntity` with duplicate components, but this isn't something I think we should focus on in this PR. `DynamicEntity` can be broken in other ways (i.e. storing a non-component in the components list), and resolving its issues can be done in a separate PR. --- ## Changelog * The scene format now uses a map to represent the collection of components rather than a list ## Migration Guide The scene format now uses a map to represent the collection of components. Scene files will need to update from the old list format. <details> <summary>Example Code</summary> ```rust // OLD [ ( entity: 0, components: [ { "bevy_transform::components::transform::Transform": ( translation: ( x: 0.0, y: 0.0, z: 0.0 ), rotation: (0.0, 0.0, 0.0, 1.0), scale: ( x: 1.0, y: 1.0, z: 1.0 ), ), }, { "my_crate::Foo": ( text: "Hello World", ), }, { "my_crate::Bar": ( baz: 123, ), }, ], ), ] // NEW [ ( entity: 0, components: { "bevy_transform::components::transform::Transform": ( translation: ( x: 0.0, y: 0.0, z: 0.0 ), rotation: (0.0, 0.0, 0.0, 1.0), scale: ( x: 1.0, y: 1.0, z: 1.0 ), ), "my_crate::Foo": ( text: "Hello World", ), "my_crate::Bar": ( baz: 123 ), }, ), ] ``` </details>
2022-10-27 01:46:33 +00:00
components: {
"scene::ComponentA": (
x: 3.0,
y: 4.0,
),
},
),
},
)