Fix Reflect serialization of tuple structs (#1366)
* Fix DynamicTupleStruct::type_name() * Fix type_name() for DynamicList, DynamicMap and DynamicTuple
This commit is contained in:
parent
4796ea8d22
commit
5b115397ba
@ -376,6 +376,7 @@ fn impl_tuple_struct(
|
||||
|
||||
fn clone_dynamic(&self) -> #bevy_reflect_path::DynamicTupleStruct {
|
||||
let mut dynamic = #bevy_reflect_path::DynamicTupleStruct::default();
|
||||
dynamic.set_name(self.type_name().to_string());
|
||||
#(dynamic.insert_boxed(self.#field_idents.clone_value());)*
|
||||
dynamic
|
||||
}
|
||||
|
||||
@ -143,6 +143,7 @@ impl<K: Reflect + Clone + Eq + Hash, V: Reflect + Clone> Map for HashMap<K, V> {
|
||||
|
||||
fn clone_dynamic(&self) -> DynamicMap {
|
||||
let mut dynamic_map = DynamicMap::default();
|
||||
dynamic_map.set_name(self.type_name().to_string());
|
||||
for (k, v) in HashMap::iter(self) {
|
||||
dynamic_map.insert_boxed(k.clone_value(), v.clone_value());
|
||||
}
|
||||
|
||||
@ -334,4 +334,43 @@ mod tests {
|
||||
let y = x.take::<Bar>().unwrap();
|
||||
assert_eq!(y, Bar { x: 2 });
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn dynamic_names() {
|
||||
let list = Vec::<usize>::new();
|
||||
let dyn_list = list.clone_dynamic();
|
||||
assert_eq!(dyn_list.type_name(), std::any::type_name::<Vec<usize>>());
|
||||
|
||||
let map = HashMap::<usize, String>::default();
|
||||
let dyn_map = map.clone_dynamic();
|
||||
assert_eq!(
|
||||
dyn_map.type_name(),
|
||||
std::any::type_name::<HashMap<usize, String>>()
|
||||
);
|
||||
|
||||
let tuple = (0usize, "1".to_string(), 2.0f32);
|
||||
let mut dyn_tuple = tuple.clone_dynamic();
|
||||
dyn_tuple.insert::<usize>(3);
|
||||
assert_eq!(
|
||||
dyn_tuple.type_name(),
|
||||
std::any::type_name::<(usize, String, f32, usize)>()
|
||||
);
|
||||
|
||||
#[derive(Reflect)]
|
||||
struct TestStruct {
|
||||
a: usize,
|
||||
}
|
||||
let struct_ = TestStruct { a: 0 };
|
||||
let dyn_struct = struct_.clone_dynamic();
|
||||
assert_eq!(dyn_struct.type_name(), std::any::type_name::<TestStruct>());
|
||||
|
||||
#[derive(Reflect)]
|
||||
struct TestTupleStruct(usize);
|
||||
let tuple_struct = TestTupleStruct(0);
|
||||
let dyn_tuple_struct = tuple_struct.clone_dynamic();
|
||||
assert_eq!(
|
||||
dyn_tuple_struct.type_name(),
|
||||
std::any::type_name::<TestTupleStruct>()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -14,6 +14,7 @@ pub trait List: Reflect {
|
||||
fn iter(&self) -> ListIter;
|
||||
fn clone_dynamic(&self) -> DynamicList {
|
||||
DynamicList {
|
||||
name: self.type_name().to_string(),
|
||||
values: self.iter().map(|value| value.clone_value()).collect(),
|
||||
}
|
||||
}
|
||||
@ -21,10 +22,19 @@ pub trait List: Reflect {
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct DynamicList {
|
||||
pub(crate) values: Vec<Box<dyn Reflect>>,
|
||||
name: String,
|
||||
values: Vec<Box<dyn Reflect>>,
|
||||
}
|
||||
|
||||
impl DynamicList {
|
||||
pub fn name(&self) -> &str {
|
||||
&self.name
|
||||
}
|
||||
|
||||
pub fn set_name(&mut self, name: String) {
|
||||
self.name = name;
|
||||
}
|
||||
|
||||
pub fn push<T: Reflect>(&mut self, value: T) {
|
||||
self.values.push(Box::new(value));
|
||||
}
|
||||
@ -49,6 +59,7 @@ impl List for DynamicList {
|
||||
|
||||
fn clone_dynamic(&self) -> DynamicList {
|
||||
DynamicList {
|
||||
name: self.name.clone(),
|
||||
values: self
|
||||
.values
|
||||
.iter()
|
||||
@ -72,7 +83,7 @@ impl List for DynamicList {
|
||||
impl Reflect for DynamicList {
|
||||
#[inline]
|
||||
fn type_name(&self) -> &str {
|
||||
std::any::type_name::<Self>()
|
||||
self.name.as_str()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
||||
@ -23,11 +23,20 @@ const HASH_ERROR: &str = "the given key does not support hashing";
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct DynamicMap {
|
||||
pub values: Vec<(Box<dyn Reflect>, Box<dyn Reflect>)>,
|
||||
pub indices: HashMap<u64, usize>,
|
||||
name: String,
|
||||
values: Vec<(Box<dyn Reflect>, Box<dyn Reflect>)>,
|
||||
indices: HashMap<u64, usize>,
|
||||
}
|
||||
|
||||
impl DynamicMap {
|
||||
pub fn name(&self) -> &str {
|
||||
&self.name
|
||||
}
|
||||
|
||||
pub fn set_name(&mut self, name: String) {
|
||||
self.name = name;
|
||||
}
|
||||
|
||||
pub fn insert<K: Reflect, V: Reflect>(&mut self, key: K, value: V) {
|
||||
self.insert_boxed(Box::new(key), Box::new(value));
|
||||
}
|
||||
@ -65,6 +74,7 @@ impl Map for DynamicMap {
|
||||
|
||||
fn clone_dynamic(&self) -> DynamicMap {
|
||||
DynamicMap {
|
||||
name: self.name.clone(),
|
||||
values: self
|
||||
.values
|
||||
.iter()
|
||||
@ -90,7 +100,7 @@ impl Map for DynamicMap {
|
||||
|
||||
impl Reflect for DynamicMap {
|
||||
fn type_name(&self) -> &str {
|
||||
std::any::type_name::<Self>()
|
||||
&self.name
|
||||
}
|
||||
|
||||
fn any(&self) -> &dyn Any {
|
||||
|
||||
@ -65,16 +65,40 @@ impl GetTupleField for dyn Tuple {
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct DynamicTuple {
|
||||
pub(crate) fields: Vec<Box<dyn Reflect>>,
|
||||
name: String,
|
||||
fields: Vec<Box<dyn Reflect>>,
|
||||
}
|
||||
|
||||
impl DynamicTuple {
|
||||
pub fn name(&self) -> &str {
|
||||
&self.name
|
||||
}
|
||||
|
||||
pub fn set_name(&mut self, name: String) {
|
||||
self.name = name;
|
||||
}
|
||||
|
||||
pub fn insert_boxed(&mut self, value: Box<dyn Reflect>) {
|
||||
self.fields.push(value);
|
||||
self.generate_name();
|
||||
}
|
||||
|
||||
pub fn insert<T: Reflect>(&mut self, value: T) {
|
||||
self.insert_boxed(Box::new(value));
|
||||
self.generate_name();
|
||||
}
|
||||
|
||||
fn generate_name(&mut self) {
|
||||
let name = &mut self.name;
|
||||
name.clear();
|
||||
name.push('(');
|
||||
for (i, field) in self.fields.iter().enumerate() {
|
||||
if i > 0 {
|
||||
name.push_str(", ");
|
||||
}
|
||||
name.push_str(field.type_name());
|
||||
}
|
||||
name.push(')');
|
||||
}
|
||||
}
|
||||
|
||||
@ -105,6 +129,7 @@ impl Tuple for DynamicTuple {
|
||||
#[inline]
|
||||
fn clone_dynamic(&self) -> DynamicTuple {
|
||||
DynamicTuple {
|
||||
name: self.name.clone(),
|
||||
fields: self
|
||||
.fields
|
||||
.iter()
|
||||
@ -117,7 +142,7 @@ impl Tuple for DynamicTuple {
|
||||
impl Reflect for DynamicTuple {
|
||||
#[inline]
|
||||
fn type_name(&self) -> &str {
|
||||
std::any::type_name::<Self>()
|
||||
self.name()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
@ -237,12 +262,15 @@ macro_rules! impl_reflect_tuple {
|
||||
|
||||
#[inline]
|
||||
fn clone_dynamic(&self) -> DynamicTuple {
|
||||
DynamicTuple {
|
||||
let mut dyn_tuple = DynamicTuple {
|
||||
name: String::default(),
|
||||
fields: self
|
||||
.iter_fields()
|
||||
.map(|value| value.clone_value())
|
||||
.collect(),
|
||||
}
|
||||
};
|
||||
dyn_tuple.generate_name();
|
||||
dyn_tuple
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -126,7 +126,7 @@ impl TupleStruct for DynamicTupleStruct {
|
||||
impl Reflect for DynamicTupleStruct {
|
||||
#[inline]
|
||||
fn type_name(&self) -> &str {
|
||||
std::any::type_name::<Self>()
|
||||
self.name.as_str()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
||||
Loading…
Reference in New Issue
Block a user