From a4387f2421ba0688490044ccd621ca642630eac9 Mon Sep 17 00:00:00 2001 From: Francisco Aguirre Date: Mon, 20 Dec 2021 13:10:31 -0300 Subject: [PATCH 1/6] Implement Reflect for Box --- crates/bevy_reflect/src/lib.rs | 15 ++++++++++ crates/bevy_reflect/src/list.rs | 4 +-- crates/bevy_reflect/src/reflect.rs | 47 ++++++++++++++++++++++++++++++ 3 files changed, 64 insertions(+), 2 deletions(-) diff --git a/crates/bevy_reflect/src/lib.rs b/crates/bevy_reflect/src/lib.rs index 231ab7d0e0c58..6a47cb584fcfd 100644 --- a/crates/bevy_reflect/src/lib.rs +++ b/crates/bevy_reflect/src/lib.rs @@ -1868,6 +1868,21 @@ bevy_reflect::tests::Test { assert_eq!("123", format!("{:?}", foo)); } + #[test] + fn box_dyn_reflect() { + #[derive(Reflect)] + struct Foo { + a: u32, + } + + let boxed: Box = Box::new(Foo { a: 1 }); + + assert_eq!( + boxed.type_name(), + "bevy_reflect::tests::box_dyn_reflect::Foo" + ); + } + #[test] fn recursive_typed_storage_does_not_hang() { #[derive(Reflect)] diff --git a/crates/bevy_reflect/src/list.rs b/crates/bevy_reflect/src/list.rs index 8c0f03837c470..dfaef683bab75 100644 --- a/crates/bevy_reflect/src/list.rs +++ b/crates/bevy_reflect/src/list.rs @@ -225,11 +225,11 @@ impl DynamicList { impl List for DynamicList { fn get(&self, index: usize) -> Option<&dyn Reflect> { - self.values.get(index).map(|value| &**value) + self.values.get(index) } fn get_mut(&mut self, index: usize) -> Option<&mut dyn Reflect> { - self.values.get_mut(index).map(|value| &mut **value) + self.values.get_mut(index).map(|value| &mut *value) } fn insert(&mut self, index: usize, element: Box) { diff --git a/crates/bevy_reflect/src/reflect.rs b/crates/bevy_reflect/src/reflect.rs index 458022566baa5..bafff2c98b447 100644 --- a/crates/bevy_reflect/src/reflect.rs +++ b/crates/bevy_reflect/src/reflect.rs @@ -6,6 +6,7 @@ use crate::{ use std::{ any::{Any, TypeId}, fmt::Debug, + ops::{Deref, DerefMut}, }; use crate::utility::NonGenericTypeInfoCell; @@ -326,3 +327,49 @@ impl dyn Reflect { self.as_any_mut().downcast_mut::() } } + +unsafe impl Reflect for Box { + fn type_name(&self) -> &str { + self.deref().type_name() + } + + fn any(&self) -> &dyn Any { + self.deref().any() + } + + fn any_mut(&mut self) -> &mut dyn Any { + self.deref_mut().any_mut() + } + + fn apply(&mut self, value: &dyn Reflect) { + self.deref_mut().apply(value) + } + + fn set(&mut self, value: Box) -> Result<(), Box> { + self.deref_mut().set(value) + } + + fn reflect_ref(&self) -> ReflectRef { + self.deref().reflect_ref() + } + + fn reflect_mut(&mut self) -> ReflectMut { + self.deref_mut().reflect_mut() + } + + fn clone_value(&self) -> Box { + self.deref().clone_value() + } + + fn reflect_hash(&self) -> Option { + self.deref().reflect_hash() + } + + fn reflect_partial_eq(&self, value: &dyn Reflect) -> Option { + self.deref().reflect_partial_eq(value) + } + + fn serializable(&self) -> Option { + self.deref().serializable() + } +} From eb12d3cdfae72ad96b9192a7d2430e087b9a3258 Mon Sep 17 00:00:00 2001 From: Francisco Aguirre Date: Mon, 20 Dec 2021 16:51:40 -0300 Subject: [PATCH 2/6] Add `Box` to reflection example --- examples/reflection/reflection.rs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/examples/reflection/reflection.rs b/examples/reflection/reflection.rs index 8f874633f8af6..085b4224e5d47 100644 --- a/examples/reflection/reflection.rs +++ b/examples/reflection/reflection.rs @@ -32,17 +32,20 @@ fn main() { /// how to handle the field. /// To do this, you can either define a `#[reflect(default = "...")]` attribute on the ignored field, or /// opt-out of `FromReflect`'s auto-derive using the `#[reflect(from_reflect = false)]` attribute. +/// +/// `Box` will forward all reflect methods to its inner value #[derive(Reflect)] #[reflect(from_reflect = false)] pub struct Foo { a: usize, nested: Bar, + boxed: Box, #[reflect(ignore)] _ignored: NonReflectedValue, } -/// This `Bar` type is used in the `nested` field on the `Test` type. We must derive `Reflect` here -/// too (or ignore it) +/// This `Bar` type is used in the `nested` and `boxed` fields on the `Test` type. +/// We must derive `Reflect` here too (or ignore it) #[derive(Reflect)] pub struct Bar { b: usize, @@ -58,6 +61,7 @@ fn setup(type_registry: Res) { a: 1, _ignored: NonReflectedValue { _a: 10 }, nested: Bar { b: 8 }, + boxed: Box::new(Bar { b: 4 }), }; // You can set field values like this. The type must match exactly or this will fail. From b6f11656d94f0bceef771e8a97fb070298a194b0 Mon Sep 17 00:00:00 2001 From: Francisco Aguirre Date: Sat, 20 Jan 2024 11:40:07 +0100 Subject: [PATCH 3/6] Update code --- crates/bevy_reflect/src/lib.rs | 5 +-- crates/bevy_reflect/src/list.rs | 4 +-- crates/bevy_reflect/src/reflect.rs | 56 ++++++++++++++++++++++++++---- 3 files changed, 52 insertions(+), 13 deletions(-) diff --git a/crates/bevy_reflect/src/lib.rs b/crates/bevy_reflect/src/lib.rs index 6a47cb584fcfd..1605399193ce4 100644 --- a/crates/bevy_reflect/src/lib.rs +++ b/crates/bevy_reflect/src/lib.rs @@ -1877,10 +1877,7 @@ bevy_reflect::tests::Test { let boxed: Box = Box::new(Foo { a: 1 }); - assert_eq!( - boxed.type_name(), - "bevy_reflect::tests::box_dyn_reflect::Foo" - ); + assert_eq!(boxed.reflect_type_path(), "bevy_reflect::tests::Foo"); } #[test] diff --git a/crates/bevy_reflect/src/list.rs b/crates/bevy_reflect/src/list.rs index dfaef683bab75..8c0f03837c470 100644 --- a/crates/bevy_reflect/src/list.rs +++ b/crates/bevy_reflect/src/list.rs @@ -225,11 +225,11 @@ impl DynamicList { impl List for DynamicList { fn get(&self, index: usize) -> Option<&dyn Reflect> { - self.values.get(index) + self.values.get(index).map(|value| &**value) } fn get_mut(&mut self, index: usize) -> Option<&mut dyn Reflect> { - self.values.get_mut(index).map(|value| &mut *value) + self.values.get_mut(index).map(|value| &mut **value) } fn insert(&mut self, index: usize, element: Box) { diff --git a/crates/bevy_reflect/src/reflect.rs b/crates/bevy_reflect/src/reflect.rs index bafff2c98b447..4ec195f43a107 100644 --- a/crates/bevy_reflect/src/reflect.rs +++ b/crates/bevy_reflect/src/reflect.rs @@ -328,17 +328,43 @@ impl dyn Reflect { } } -unsafe impl Reflect for Box { - fn type_name(&self) -> &str { - self.deref().type_name() +impl DynamicTypePath for Box { + fn reflect_type_path(&self) -> &str { + self.deref().reflect_type_path() } - fn any(&self) -> &dyn Any { - self.deref().any() + fn reflect_short_type_path(&self) -> &str { + self.deref().reflect_short_type_path() } - fn any_mut(&mut self) -> &mut dyn Any { - self.deref_mut().any_mut() + fn reflect_type_ident(&self) -> Option<&str> { + self.deref().reflect_type_ident() + } + + fn reflect_crate_name(&self) -> Option<&str> { + self.deref().reflect_crate_name() + } + + fn reflect_module_path(&self) -> Option<&str> { + self.deref().reflect_module_path() + } +} + +impl Reflect for Box { + fn get_represented_type_info(&self) -> Option<&'static TypeInfo> { + self.deref().get_represented_type_info() + } + + fn into_any(self: Box) -> Box { + Box::new((*self).into_any()) + } + + fn as_any(&self) -> &dyn Any { + self.deref().as_any() + } + + fn as_any_mut(&mut self) -> &mut dyn Any { + self.deref_mut().as_any_mut() } fn apply(&mut self, value: &dyn Reflect) { @@ -349,6 +375,18 @@ unsafe impl Reflect for Box { self.deref_mut().set(value) } + fn into_reflect(self: Box) -> Box { + Box::new((*self).into_reflect()) + } + + fn as_reflect(&self) -> &dyn Reflect { + self.deref().as_reflect() + } + + fn as_reflect_mut(&mut self) -> &mut dyn Reflect { + self.deref_mut().as_reflect_mut() + } + fn reflect_ref(&self) -> ReflectRef { self.deref().reflect_ref() } @@ -357,6 +395,10 @@ unsafe impl Reflect for Box { self.deref_mut().reflect_mut() } + fn reflect_owned(self: Box) -> ReflectOwned { + (*self).reflect_owned() + } + fn clone_value(&self) -> Box { self.deref().clone_value() } From 0a3706838e86e3a1f365492454cf05f184e86d4c Mon Sep 17 00:00:00 2001 From: Francisco Aguirre Date: Sat, 20 Jan 2024 11:43:03 +0100 Subject: [PATCH 4/6] Fix linter issue --- crates/bevy_reflect/src/reflect.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/bevy_reflect/src/reflect.rs b/crates/bevy_reflect/src/reflect.rs index 4ec195f43a107..9e85bd237b7ef 100644 --- a/crates/bevy_reflect/src/reflect.rs +++ b/crates/bevy_reflect/src/reflect.rs @@ -368,7 +368,7 @@ impl Reflect for Box { } fn apply(&mut self, value: &dyn Reflect) { - self.deref_mut().apply(value) + self.deref_mut().apply(value); } fn set(&mut self, value: Box) -> Result<(), Box> { From 371c22a451c2c4da58832f94e59ac4f3bce5a250 Mon Sep 17 00:00:00 2001 From: Francisco Aguirre Date: Sat, 20 Jan 2024 11:53:30 +0100 Subject: [PATCH 5/6] Implement TypePath instead of DynamicTypePath for Box --- crates/bevy_reflect/src/reflect.rs | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/crates/bevy_reflect/src/reflect.rs b/crates/bevy_reflect/src/reflect.rs index 9e85bd237b7ef..c788cb2136060 100644 --- a/crates/bevy_reflect/src/reflect.rs +++ b/crates/bevy_reflect/src/reflect.rs @@ -328,25 +328,25 @@ impl dyn Reflect { } } -impl DynamicTypePath for Box { - fn reflect_type_path(&self) -> &str { - self.deref().reflect_type_path() +impl TypePath for Box { + fn type_path() -> &'static str { + "std::boxed::Box(dyn bevy_reflect::Reflect)" } - fn reflect_short_type_path(&self) -> &str { - self.deref().reflect_short_type_path() + fn short_type_path() -> &'static str { + "Box(dyn Reflect)" } - fn reflect_type_ident(&self) -> Option<&str> { - self.deref().reflect_type_ident() + fn type_ident() -> Option<&'static str> { + Some("Box") } - fn reflect_crate_name(&self) -> Option<&str> { - self.deref().reflect_crate_name() + fn crate_name() -> Option<&'static str> { + Some("std") } - fn reflect_module_path(&self) -> Option<&str> { - self.deref().reflect_module_path() + fn module_path() -> Option<&'static str> { + Some("std::boxed") } } From 57ad19e3d1429503b929bd9e8683df99be2d8727 Mon Sep 17 00:00:00 2001 From: Francisco Aguirre Date: Sat, 20 Jan 2024 11:58:52 +0100 Subject: [PATCH 6/6] Modify test --- crates/bevy_reflect/src/lib.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/crates/bevy_reflect/src/lib.rs b/crates/bevy_reflect/src/lib.rs index 1605399193ce4..39dca6fcb888f 100644 --- a/crates/bevy_reflect/src/lib.rs +++ b/crates/bevy_reflect/src/lib.rs @@ -1877,7 +1877,10 @@ bevy_reflect::tests::Test { let boxed: Box = Box::new(Foo { a: 1 }); - assert_eq!(boxed.reflect_type_path(), "bevy_reflect::tests::Foo"); + assert_eq!( + boxed.reflect_type_path(), + "std::boxed::Box(dyn bevy_reflect::Reflect)" + ); } #[test]