Name component Reflect/Serde
- Dominant language
- Rust
- Stars
- 48.2k
- Forks
- 4.8k
- Avg merge
- 3d 22h
- Merged PRs (30d)
- 161
Description
## Bevy version and features
- Bevy version 0.16.1
## \[Optional\] Relevant system information
Running on `x86_64-unknown-linux-gnu`
(Debian 13 stable, rust 1.89 stable)
Using also dependencies:
- serde = 1
- bincode = 2 + features 'serde'
## What you did
Trying to serialize a component through reflection and deserialize it back.
This used to work in [bevy_sync](https://codeberg.org/raffaeleragni/bevy_sync)/[lux](https://codeberg.org/raffaeleragni/lux) in 0.15
## What went wrong
The component 'Name' apparently is having some reflection issues when serde to/from binary using reflection/registry since this version (0.16). I noticed it was refactored quite a bit since the previous 0.15 such as using Cow instead of owned String, and has a new hash field, maybe that can cause issues?
## Additional information
Sample code:
```rust
use bevy::{
prelude::*,
reflect::serde::{ReflectDeserializer, ReflectSerializer},
};
use bincode::{de::read::SliceReader, serde::OwnedSerdeDecoder};
use serde::de::DeserializeSeed;
const BINCODE_OPTIONS: bincode::config::Configuration<
bincode::config::BigEndian,
bincode::config::Fixint,
> = bincode::config::standard()
.with_big_endian()
.with_fixed_int_encoding();
fn main() {
let mut app = App::new();
app.register_type::();
let id = app.world_mut().spawn(Name::from("test")).id();
let c = app
.world()
.entity(id)
.get::()
.unwrap()
.as_partial_reflect()
.to_dynamic();
let registry = app.world().resource::();
let registry = registry.read();
println!("Encode ({c:?})");
let ser = ReflectSerializer::new(c.as_ref(), ®istry);
let binary = bincode::serde::encode_to_vec(ser, BINCODE_OPTIONS).unwrap();
println!("Decode ({binary:?})");
let deser = ReflectDeserializer::new(®istry);
let mut bin_deser = OwnedSerdeDecoder::from_reader(SliceReader::new(&binary), BINCODE_OPTIONS);
let data = deser.deserialize(bin_deser.as_deserializer()).unwrap();
let type_path = data.get_represented_type_info().unwrap().type_path();
let registration = registry.get_with_type_path(type_path).unwrap();
let rfr = registry
.get_type_data::(registration.type_id())
.unwrap();
let compo_back = rfr.from_reflect(&*data).unwrap().into_partial_reflect();
println!("{compo_back:?}");
}
```
Output:
```
Encode (DynamicStruct(bevy_ecs::name::Name { hash: 7383812325695175250, name: "test" }))
Decode ([0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 20, 98, 101, 118, 121, 95, 101, 99, 115, 58, 58, 110, 97, 109, 101, 58, 58, 78, 97, 109, 101, 102, 120, 146, 48, 105, 54, 58, 82, 0, 0, 0, 0, 0, 0, 0, 4, 116, 101, 115, 116])
memory allocation of 7383812325695175250 bytes failed
Aborted (core dumped)
```
I find it *very suspicious* that it tries to allocate the same amount of the value of the hash too. This error I am getting only from this example now. While I was testing it live on bevy_sync/lux I was getting a different one but I suppose mangled bytes are mangled bytes.
I didn't find this issue with other components so far.
For comparison, when I use a Transform::default() instead of a Name component in the above example, things go smooth:
```
Encode (DynamicStruct(bevy_transform::components::transform::Transform { translation: DynamicStruct(glam::Vec3 { x: 0.0, y: 0.0, z: 0.0 }), rotation: DynamicStruct(glam::Quat { x: 0.0, y: 0.0, z: 0.0, w: 1.0 }), scale: DynamicStruct(glam::Vec3 { x: 1.0, y: 1.0, z: 1.0 }) }))
Decode ([0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 48, 98, 101, 118, 121, 95, 116, 114, 97, 110, 115, 102, 111, 114, 109, 58, 58, 99, 111, 109, 112, 111, 110, 101, 110, 116, 115, 58, 58, 116, 114, 97, 110, 115, 102, 111, 114, 109, 58, 58, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, 128, 0, 0, 63, 128, 0, 0, 63, 128, 0, 0, 63, 128, 0, 0])
Transform { translation: Vec3(0.0, 0.0, 0.0), rotation: Quat(0.0, 0.0, 0.0, 1.0), scale: Vec3(1.0, 1.0, 1.0) }
```
Contributor guide
Assessment
This issue has not been assessed yet.