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

[Merged by Bors] - bevy_reflect: Fix DynamicScene not respecting component registrations during serialization #6288

Closed
wants to merge 1 commit into from

Conversation

MrGVSV
Copy link
Member

@MrGVSV MrGVSV commented Oct 18, 2022

Objective

When running the scene example, you might notice we end up printing out the following:

// ...
{
  "scene::ComponentB": (
    value: "hello",
    _time_since_startup: (
      secs: 0,
      nanos: 0,
    ),
  ),
},
// ...

We should not be printing out _time_since_startup as the field is marked with #[reflect(skip_serializing)]:

#[derive(Component, Reflect)]
#[reflect(Component)]
struct ComponentB {
  pub value: String,
  #[reflect(skip_serializing)]
  pub _time_since_startup: Duration,
}

This is because when we create the DynamicScene, we end up calling Reflect::clone_value:

entry.components.push(component.clone_value());

This results in non-Value types being cloned into Dynamic types, which means the TypeId returned from reflected_value.type_id() is not the same as the original component's.

And this meant we were not able to locate the correct TypeRegistration.

Solution

Use TypeInfo::type_id() instead of calling Any::type_id() on the value directly.


Changelog

  • Fix a bug introduced in 0.9.0-dev where scenes disregarded component's type registrations

@MrGVSV MrGVSV added C-Bug An unexpected or incorrect behavior A-Reflection Runtime information about types A-Scenes Serialized ECS data stored on the disk labels Oct 18, 2022
@MrGVSV MrGVSV added this to the Bevy 0.9 milestone Oct 18, 2022
@mockersf
Copy link
Member

is there an easier way to catch this kind of issues? Should TypeInfo::type_id be renamed and return a wrapper to "hide" a little that we're using an underlying TypeId ?

@MrGVSV
Copy link
Member Author

MrGVSV commented Oct 19, 2022

is there an easier way to catch this kind of issues? Should TypeInfo::type_id be renamed and return a wrapper to "hide" a little that we're using an underlying TypeId ?

We could do that. But the issue in this particular case was that the actual value (dyn (Tuple)Struct) was assumed to have the right TypeId. However, this was a bad assumption since it was actually a Dynamic(Tuple)Struct under the hood.

I don't think there's any way to prevent this from happening, though. We can't really override Any::type_id1. And if we did, there's no way to actually get the real TypeId without the registry (so we can get the type being represented by the Dynamic).

Footnotes

  1. We could add our own type_id method on Reflect but we still run into the issue of not being able to get the desired TypeId

@mockersf mockersf added the S-Ready-For-Final-Review This PR has been approved by the community. It's ready for a maintainer to consider merging it label Oct 19, 2022
@alice-i-cecile
Copy link
Member

bors r+

bors bot pushed a commit that referenced this pull request Oct 24, 2022
…ns during serialization (#6288)

# Objective

When running the scene example, you might notice we end up printing out the following:
```ron
// ...
{
  "scene::ComponentB": (
    value: "hello",
    _time_since_startup: (
      secs: 0,
      nanos: 0,
    ),
  ),
},
// ...
```

We should not be printing out `_time_since_startup` as the field is marked with `#[reflect(skip_serializing)]`:

```rust
#[derive(Component, Reflect)]
#[reflect(Component)]
struct ComponentB {
  pub value: String,
  #[reflect(skip_serializing)]
  pub _time_since_startup: Duration,
}
```

This is because when we create the `DynamicScene`, we end up calling `Reflect::clone_value`:

https://github.com/bevyengine/bevy/blob/82126697ee4f635cf6b22e0b9f25e5aca95fda4a/crates/bevy_scene/src/dynamic_scene_builder.rs#L114-L114

This results in non-Value types being cloned into Dynamic types, which means the `TypeId` returned from `reflected_value.type_id()` is not the same as the original component's. 

And this meant we were not able to locate the correct `TypeRegistration`.

## Solution

Use `TypeInfo::type_id()` instead of calling `Any::type_id()` on the value directly.

---

## Changelog

* Fix a bug introduced in `0.9.0-dev` where scenes disregarded component's type registrations
@bors
Copy link
Contributor

bors bot commented Oct 24, 2022

Build failed (retrying...):

bors bot pushed a commit that referenced this pull request Oct 24, 2022
…ns during serialization (#6288)

# Objective

When running the scene example, you might notice we end up printing out the following:
```ron
// ...
{
  "scene::ComponentB": (
    value: "hello",
    _time_since_startup: (
      secs: 0,
      nanos: 0,
    ),
  ),
},
// ...
```

We should not be printing out `_time_since_startup` as the field is marked with `#[reflect(skip_serializing)]`:

```rust
#[derive(Component, Reflect)]
#[reflect(Component)]
struct ComponentB {
  pub value: String,
  #[reflect(skip_serializing)]
  pub _time_since_startup: Duration,
}
```

This is because when we create the `DynamicScene`, we end up calling `Reflect::clone_value`:

https://github.com/bevyengine/bevy/blob/82126697ee4f635cf6b22e0b9f25e5aca95fda4a/crates/bevy_scene/src/dynamic_scene_builder.rs#L114-L114

This results in non-Value types being cloned into Dynamic types, which means the `TypeId` returned from `reflected_value.type_id()` is not the same as the original component's. 

And this meant we were not able to locate the correct `TypeRegistration`.

## Solution

Use `TypeInfo::type_id()` instead of calling `Any::type_id()` on the value directly.

---

## Changelog

* Fix a bug introduced in `0.9.0-dev` where scenes disregarded component's type registrations
@bors bors bot changed the title bevy_reflect: Fix DynamicScene not respecting component registrations during serialization [Merged by Bors] - bevy_reflect: Fix DynamicScene not respecting component registrations during serialization Oct 24, 2022
@bors bors bot closed this Oct 24, 2022
@mockersf mockersf added the hacktoberfest-accepted A PR that was accepted for Hacktoberfest, an annual open source event label Oct 24, 2022
james7132 pushed a commit to james7132/bevy that referenced this pull request Oct 28, 2022
…ns during serialization (bevyengine#6288)

# Objective

When running the scene example, you might notice we end up printing out the following:
```ron
// ...
{
  "scene::ComponentB": (
    value: "hello",
    _time_since_startup: (
      secs: 0,
      nanos: 0,
    ),
  ),
},
// ...
```

We should not be printing out `_time_since_startup` as the field is marked with `#[reflect(skip_serializing)]`:

```rust
#[derive(Component, Reflect)]
#[reflect(Component)]
struct ComponentB {
  pub value: String,
  #[reflect(skip_serializing)]
  pub _time_since_startup: Duration,
}
```

This is because when we create the `DynamicScene`, we end up calling `Reflect::clone_value`:

https://github.com/bevyengine/bevy/blob/82126697ee4f635cf6b22e0b9f25e5aca95fda4a/crates/bevy_scene/src/dynamic_scene_builder.rs#L114-L114

This results in non-Value types being cloned into Dynamic types, which means the `TypeId` returned from `reflected_value.type_id()` is not the same as the original component's. 

And this meant we were not able to locate the correct `TypeRegistration`.

## Solution

Use `TypeInfo::type_id()` instead of calling `Any::type_id()` on the value directly.

---

## Changelog

* Fix a bug introduced in `0.9.0-dev` where scenes disregarded component's type registrations
Pietrek14 pushed a commit to Pietrek14/bevy that referenced this pull request Dec 17, 2022
…ns during serialization (bevyengine#6288)

# Objective

When running the scene example, you might notice we end up printing out the following:
```ron
// ...
{
  "scene::ComponentB": (
    value: "hello",
    _time_since_startup: (
      secs: 0,
      nanos: 0,
    ),
  ),
},
// ...
```

We should not be printing out `_time_since_startup` as the field is marked with `#[reflect(skip_serializing)]`:

```rust
#[derive(Component, Reflect)]
#[reflect(Component)]
struct ComponentB {
  pub value: String,
  #[reflect(skip_serializing)]
  pub _time_since_startup: Duration,
}
```

This is because when we create the `DynamicScene`, we end up calling `Reflect::clone_value`:

https://github.com/bevyengine/bevy/blob/82126697ee4f635cf6b22e0b9f25e5aca95fda4a/crates/bevy_scene/src/dynamic_scene_builder.rs#L114-L114

This results in non-Value types being cloned into Dynamic types, which means the `TypeId` returned from `reflected_value.type_id()` is not the same as the original component's. 

And this meant we were not able to locate the correct `TypeRegistration`.

## Solution

Use `TypeInfo::type_id()` instead of calling `Any::type_id()` on the value directly.

---

## Changelog

* Fix a bug introduced in `0.9.0-dev` where scenes disregarded component's type registrations
ItsDoot pushed a commit to ItsDoot/bevy that referenced this pull request Feb 1, 2023
…ns during serialization (bevyengine#6288)

# Objective

When running the scene example, you might notice we end up printing out the following:
```ron
// ...
{
  "scene::ComponentB": (
    value: "hello",
    _time_since_startup: (
      secs: 0,
      nanos: 0,
    ),
  ),
},
// ...
```

We should not be printing out `_time_since_startup` as the field is marked with `#[reflect(skip_serializing)]`:

```rust
#[derive(Component, Reflect)]
#[reflect(Component)]
struct ComponentB {
  pub value: String,
  #[reflect(skip_serializing)]
  pub _time_since_startup: Duration,
}
```

This is because when we create the `DynamicScene`, we end up calling `Reflect::clone_value`:

https://github.com/bevyengine/bevy/blob/82126697ee4f635cf6b22e0b9f25e5aca95fda4a/crates/bevy_scene/src/dynamic_scene_builder.rs#L114-L114

This results in non-Value types being cloned into Dynamic types, which means the `TypeId` returned from `reflected_value.type_id()` is not the same as the original component's. 

And this meant we were not able to locate the correct `TypeRegistration`.

## Solution

Use `TypeInfo::type_id()` instead of calling `Any::type_id()` on the value directly.

---

## Changelog

* Fix a bug introduced in `0.9.0-dev` where scenes disregarded component's type registrations
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-Reflection Runtime information about types A-Scenes Serialized ECS data stored on the disk C-Bug An unexpected or incorrect behavior hacktoberfest-accepted A PR that was accepted for Hacktoberfest, an annual open source event S-Ready-For-Final-Review This PR has been approved by the community. It's ready for a maintainer to consider merging it
Projects
Status: Done
Development

Successfully merging this pull request may close these issues.

None yet

3 participants