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 {
|
fn clone_dynamic(&self) -> #bevy_reflect_path::DynamicTupleStruct {
|
||||||
let mut dynamic = #bevy_reflect_path::DynamicTupleStruct::default();
|
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.insert_boxed(self.#field_idents.clone_value());)*
|
||||||
dynamic
|
dynamic
|
||||||
}
|
}
|
||||||
|
|||||||
@ -143,6 +143,7 @@ impl<K: Reflect + Clone + Eq + Hash, V: Reflect + Clone> Map for HashMap<K, V> {
|
|||||||
|
|
||||||
fn clone_dynamic(&self) -> DynamicMap {
|
fn clone_dynamic(&self) -> DynamicMap {
|
||||||
let mut dynamic_map = DynamicMap::default();
|
let mut dynamic_map = DynamicMap::default();
|
||||||
|
dynamic_map.set_name(self.type_name().to_string());
|
||||||
for (k, v) in HashMap::iter(self) {
|
for (k, v) in HashMap::iter(self) {
|
||||||
dynamic_map.insert_boxed(k.clone_value(), v.clone_value());
|
dynamic_map.insert_boxed(k.clone_value(), v.clone_value());
|
||||||
}
|
}
|
||||||
|
|||||||
@ -334,4 +334,43 @@ mod tests {
|
|||||||
let y = x.take::<Bar>().unwrap();
|
let y = x.take::<Bar>().unwrap();
|
||||||
assert_eq!(y, Bar { x: 2 });
|
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 iter(&self) -> ListIter;
|
||||||
fn clone_dynamic(&self) -> DynamicList {
|
fn clone_dynamic(&self) -> DynamicList {
|
||||||
DynamicList {
|
DynamicList {
|
||||||
|
name: self.type_name().to_string(),
|
||||||
values: self.iter().map(|value| value.clone_value()).collect(),
|
values: self.iter().map(|value| value.clone_value()).collect(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -21,10 +22,19 @@ pub trait List: Reflect {
|
|||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct DynamicList {
|
pub struct DynamicList {
|
||||||
pub(crate) values: Vec<Box<dyn Reflect>>,
|
name: String,
|
||||||
|
values: Vec<Box<dyn Reflect>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DynamicList {
|
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) {
|
pub fn push<T: Reflect>(&mut self, value: T) {
|
||||||
self.values.push(Box::new(value));
|
self.values.push(Box::new(value));
|
||||||
}
|
}
|
||||||
@ -49,6 +59,7 @@ impl List for DynamicList {
|
|||||||
|
|
||||||
fn clone_dynamic(&self) -> DynamicList {
|
fn clone_dynamic(&self) -> DynamicList {
|
||||||
DynamicList {
|
DynamicList {
|
||||||
|
name: self.name.clone(),
|
||||||
values: self
|
values: self
|
||||||
.values
|
.values
|
||||||
.iter()
|
.iter()
|
||||||
@ -72,7 +83,7 @@ impl List for DynamicList {
|
|||||||
impl Reflect for DynamicList {
|
impl Reflect for DynamicList {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn type_name(&self) -> &str {
|
fn type_name(&self) -> &str {
|
||||||
std::any::type_name::<Self>()
|
self.name.as_str()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
|||||||
@ -23,11 +23,20 @@ const HASH_ERROR: &str = "the given key does not support hashing";
|
|||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct DynamicMap {
|
pub struct DynamicMap {
|
||||||
pub values: Vec<(Box<dyn Reflect>, Box<dyn Reflect>)>,
|
name: String,
|
||||||
pub indices: HashMap<u64, usize>,
|
values: Vec<(Box<dyn Reflect>, Box<dyn Reflect>)>,
|
||||||
|
indices: HashMap<u64, usize>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DynamicMap {
|
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) {
|
pub fn insert<K: Reflect, V: Reflect>(&mut self, key: K, value: V) {
|
||||||
self.insert_boxed(Box::new(key), Box::new(value));
|
self.insert_boxed(Box::new(key), Box::new(value));
|
||||||
}
|
}
|
||||||
@ -65,6 +74,7 @@ impl Map for DynamicMap {
|
|||||||
|
|
||||||
fn clone_dynamic(&self) -> DynamicMap {
|
fn clone_dynamic(&self) -> DynamicMap {
|
||||||
DynamicMap {
|
DynamicMap {
|
||||||
|
name: self.name.clone(),
|
||||||
values: self
|
values: self
|
||||||
.values
|
.values
|
||||||
.iter()
|
.iter()
|
||||||
@ -90,7 +100,7 @@ impl Map for DynamicMap {
|
|||||||
|
|
||||||
impl Reflect for DynamicMap {
|
impl Reflect for DynamicMap {
|
||||||
fn type_name(&self) -> &str {
|
fn type_name(&self) -> &str {
|
||||||
std::any::type_name::<Self>()
|
&self.name
|
||||||
}
|
}
|
||||||
|
|
||||||
fn any(&self) -> &dyn Any {
|
fn any(&self) -> &dyn Any {
|
||||||
|
|||||||
@ -65,16 +65,40 @@ impl GetTupleField for dyn Tuple {
|
|||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct DynamicTuple {
|
pub struct DynamicTuple {
|
||||||
pub(crate) fields: Vec<Box<dyn Reflect>>,
|
name: String,
|
||||||
|
fields: Vec<Box<dyn Reflect>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DynamicTuple {
|
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>) {
|
pub fn insert_boxed(&mut self, value: Box<dyn Reflect>) {
|
||||||
self.fields.push(value);
|
self.fields.push(value);
|
||||||
|
self.generate_name();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn insert<T: Reflect>(&mut self, value: T) {
|
pub fn insert<T: Reflect>(&mut self, value: T) {
|
||||||
self.insert_boxed(Box::new(value));
|
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]
|
#[inline]
|
||||||
fn clone_dynamic(&self) -> DynamicTuple {
|
fn clone_dynamic(&self) -> DynamicTuple {
|
||||||
DynamicTuple {
|
DynamicTuple {
|
||||||
|
name: self.name.clone(),
|
||||||
fields: self
|
fields: self
|
||||||
.fields
|
.fields
|
||||||
.iter()
|
.iter()
|
||||||
@ -117,7 +142,7 @@ impl Tuple for DynamicTuple {
|
|||||||
impl Reflect for DynamicTuple {
|
impl Reflect for DynamicTuple {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn type_name(&self) -> &str {
|
fn type_name(&self) -> &str {
|
||||||
std::any::type_name::<Self>()
|
self.name()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
@ -237,12 +262,15 @@ macro_rules! impl_reflect_tuple {
|
|||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn clone_dynamic(&self) -> DynamicTuple {
|
fn clone_dynamic(&self) -> DynamicTuple {
|
||||||
DynamicTuple {
|
let mut dyn_tuple = DynamicTuple {
|
||||||
|
name: String::default(),
|
||||||
fields: self
|
fields: self
|
||||||
.iter_fields()
|
.iter_fields()
|
||||||
.map(|value| value.clone_value())
|
.map(|value| value.clone_value())
|
||||||
.collect(),
|
.collect(),
|
||||||
}
|
};
|
||||||
|
dyn_tuple.generate_name();
|
||||||
|
dyn_tuple
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -126,7 +126,7 @@ impl TupleStruct for DynamicTupleStruct {
|
|||||||
impl Reflect for DynamicTupleStruct {
|
impl Reflect for DynamicTupleStruct {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn type_name(&self) -> &str {
|
fn type_name(&self) -> &str {
|
||||||
std::any::type_name::<Self>()
|
self.name.as_str()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user