From 7de22603074eae89a69d087c4d27a1d107b71c31 Mon Sep 17 00:00:00 2001 From: Gino Valente Date: Mon, 7 Nov 2022 02:11:16 +0000 Subject: [PATCH] bevy_reflect: Add `Reflect::into_reflect` (#6502) # Objective Using `Reflect` we can easily switch between a specific reflection trait object, such as a `dyn Struct`, to a `dyn Reflect` object via `Reflect::as_reflect` or `Reflect::as_reflect_mut`. ```rust fn do_something(value: &dyn Reflect) {/* ... */} let foo: Box = Box::new(Foo::default()); do_something(foo.as_reflect()); ``` However, there is no way to convert a _boxed_ reflection trait object to a `Box`. ## Solution Add a `Reflect::into_reflect` method which allows converting a boxed reflection trait object back into a boxed `Reflect` trait object. ```rust fn do_something(value: Box) {/* ... */} let foo: Box = Box::new(Foo::default()); do_something(foo.into_reflect()); ``` --- ## Changelog - Added `Reflect::into_reflect` --- .../bevy_reflect_derive/src/impls/enums.rs | 5 ++++ .../bevy_reflect_derive/src/impls/structs.rs | 5 ++++ .../src/impls/tuple_structs.rs | 5 ++++ .../bevy_reflect_derive/src/impls/values.rs | 5 ++++ crates/bevy_reflect/src/array.rs | 5 ++++ crates/bevy_reflect/src/enums/dynamic_enum.rs | 5 ++++ crates/bevy_reflect/src/impls/smallvec.rs | 4 ++++ crates/bevy_reflect/src/impls/std.rs | 23 +++++++++++++++++++ crates/bevy_reflect/src/lib.rs | 15 ++++++++++++ crates/bevy_reflect/src/list.rs | 5 ++++ crates/bevy_reflect/src/map.rs | 5 ++++ crates/bevy_reflect/src/reflect.rs | 7 ++++-- crates/bevy_reflect/src/struct_trait.rs | 5 ++++ crates/bevy_reflect/src/tuple.rs | 9 ++++++++ crates/bevy_reflect/src/tuple_struct.rs | 5 ++++ crates/bevy_reflect/src/type_info.rs | 1 + crates/bevy_reflect/src/utility.rs | 2 ++ 17 files changed, 109 insertions(+), 2 deletions(-) diff --git a/crates/bevy_reflect/bevy_reflect_derive/src/impls/enums.rs b/crates/bevy_reflect/bevy_reflect_derive/src/impls/enums.rs index d3399c4f504609..a1d10aa7c70a8e 100644 --- a/crates/bevy_reflect/bevy_reflect_derive/src/impls/enums.rs +++ b/crates/bevy_reflect/bevy_reflect_derive/src/impls/enums.rs @@ -202,6 +202,11 @@ pub(crate) fn impl_enum(reflect_enum: &ReflectEnum) -> TokenStream { self } + #[inline] + fn into_reflect(self: Box) -> Box { + self + } + #[inline] fn as_reflect(&self) -> &dyn #bevy_reflect_path::Reflect { self diff --git a/crates/bevy_reflect/bevy_reflect_derive/src/impls/structs.rs b/crates/bevy_reflect/bevy_reflect_derive/src/impls/structs.rs index 923457f2b19f9a..b73fbcf1a4b274 100644 --- a/crates/bevy_reflect/bevy_reflect_derive/src/impls/structs.rs +++ b/crates/bevy_reflect/bevy_reflect_derive/src/impls/structs.rs @@ -183,6 +183,11 @@ pub(crate) fn impl_struct(reflect_struct: &ReflectStruct) -> TokenStream { self } + #[inline] + fn into_reflect(self: Box) -> Box { + self + } + #[inline] fn as_reflect(&self) -> &dyn #bevy_reflect_path::Reflect { self diff --git a/crates/bevy_reflect/bevy_reflect_derive/src/impls/tuple_structs.rs b/crates/bevy_reflect/bevy_reflect_derive/src/impls/tuple_structs.rs index 30bcaf3c9c143c..0c0c233c9a7ff9 100644 --- a/crates/bevy_reflect/bevy_reflect_derive/src/impls/tuple_structs.rs +++ b/crates/bevy_reflect/bevy_reflect_derive/src/impls/tuple_structs.rs @@ -145,6 +145,11 @@ pub(crate) fn impl_tuple_struct(reflect_struct: &ReflectStruct) -> TokenStream { self } + #[inline] + fn into_reflect(self: Box) -> Box { + self + } + #[inline] fn as_reflect(&self) -> &dyn #bevy_reflect_path::Reflect { self diff --git a/crates/bevy_reflect/bevy_reflect_derive/src/impls/values.rs b/crates/bevy_reflect/bevy_reflect_derive/src/impls/values.rs index 1c768fbf0b96ea..5bf7d3ec77ecc0 100644 --- a/crates/bevy_reflect/bevy_reflect_derive/src/impls/values.rs +++ b/crates/bevy_reflect/bevy_reflect_derive/src/impls/values.rs @@ -64,6 +64,11 @@ pub(crate) fn impl_value(meta: &ReflectMeta) -> TokenStream { self } + #[inline] + fn into_reflect(self: Box) -> Box { + self + } + #[inline] fn as_reflect(&self) -> &dyn #bevy_reflect_path::Reflect { self diff --git a/crates/bevy_reflect/src/array.rs b/crates/bevy_reflect/src/array.rs index 206eda8006ae61..438a135c040a3d 100644 --- a/crates/bevy_reflect/src/array.rs +++ b/crates/bevy_reflect/src/array.rs @@ -197,6 +197,11 @@ impl Reflect for DynamicArray { self } + #[inline] + fn into_reflect(self: Box) -> Box { + self + } + #[inline] fn as_reflect(&self) -> &dyn Reflect { self diff --git a/crates/bevy_reflect/src/enums/dynamic_enum.rs b/crates/bevy_reflect/src/enums/dynamic_enum.rs index a3424c66263d3c..fd3a8585b763f8 100644 --- a/crates/bevy_reflect/src/enums/dynamic_enum.rs +++ b/crates/bevy_reflect/src/enums/dynamic_enum.rs @@ -315,6 +315,11 @@ impl Reflect for DynamicEnum { self } + #[inline] + fn into_reflect(self: Box) -> Box { + self + } + #[inline] fn as_reflect(&self) -> &dyn Reflect { self diff --git a/crates/bevy_reflect/src/impls/smallvec.rs b/crates/bevy_reflect/src/impls/smallvec.rs index dfff11e6de65fd..f44957175f3846 100644 --- a/crates/bevy_reflect/src/impls/smallvec.rs +++ b/crates/bevy_reflect/src/impls/smallvec.rs @@ -90,6 +90,10 @@ where self } + fn into_reflect(self: Box) -> Box { + self + } + fn as_reflect(&self) -> &dyn Reflect { self } diff --git a/crates/bevy_reflect/src/impls/std.rs b/crates/bevy_reflect/src/impls/std.rs index 169b35f41f5ca1..8eeac36461817d 100644 --- a/crates/bevy_reflect/src/impls/std.rs +++ b/crates/bevy_reflect/src/impls/std.rs @@ -245,6 +245,10 @@ impl Reflect for Vec { self } + fn into_reflect(self: Box) -> Box { + self + } + fn as_reflect(&self) -> &dyn Reflect { self } @@ -413,6 +417,11 @@ impl Reflect for HashMap { self } + #[inline] + fn into_reflect(self: Box) -> Box { + self + } + fn as_reflect(&self) -> &dyn Reflect { self } @@ -543,6 +552,11 @@ impl Reflect for [T; N] { self } + #[inline] + fn into_reflect(self: Box) -> Box { + self + } + #[inline] fn as_reflect(&self) -> &dyn Reflect { self @@ -661,6 +675,10 @@ impl Reflect for Cow<'static, str> { self } + fn into_reflect(self: Box) -> Box { + self + } + fn as_reflect(&self) -> &dyn Reflect { self } @@ -819,6 +837,11 @@ impl Reflect for Option { self } + #[inline] + fn into_reflect(self: Box) -> Box { + self + } + fn as_reflect(&self) -> &dyn Reflect { self } diff --git a/crates/bevy_reflect/src/lib.rs b/crates/bevy_reflect/src/lib.rs index 24c84009a41f19..6c1c3c8dc320e1 100644 --- a/crates/bevy_reflect/src/lib.rs +++ b/crates/bevy_reflect/src/lib.rs @@ -989,6 +989,21 @@ mod tests { } } + #[test] + fn into_reflect() { + trait TestTrait: Reflect {} + + #[derive(Reflect)] + struct TestStruct; + + impl TestTrait for TestStruct {} + + let trait_object: Box = Box::new(TestStruct); + + // Should compile: + let _ = trait_object.into_reflect(); + } + #[test] fn as_reflect() { trait TestTrait: Reflect {} diff --git a/crates/bevy_reflect/src/list.rs b/crates/bevy_reflect/src/list.rs index b05597a5f2a796..7e139d48b05e68 100644 --- a/crates/bevy_reflect/src/list.rs +++ b/crates/bevy_reflect/src/list.rs @@ -216,6 +216,11 @@ impl Reflect for DynamicList { self } + #[inline] + fn into_reflect(self: Box) -> Box { + self + } + #[inline] fn as_reflect(&self) -> &dyn Reflect { self diff --git a/crates/bevy_reflect/src/map.rs b/crates/bevy_reflect/src/map.rs index f6f2d0efaa9418..9618b5cd2dd44d 100644 --- a/crates/bevy_reflect/src/map.rs +++ b/crates/bevy_reflect/src/map.rs @@ -273,6 +273,11 @@ impl Reflect for DynamicMap { self } + #[inline] + fn into_reflect(self: Box) -> Box { + self + } + #[inline] fn as_reflect(&self) -> &dyn Reflect { self diff --git a/crates/bevy_reflect/src/reflect.rs b/crates/bevy_reflect/src/reflect.rs index a700ba4f993bb9..0ba2e5d9eb4755 100644 --- a/crates/bevy_reflect/src/reflect.rs +++ b/crates/bevy_reflect/src/reflect.rs @@ -92,10 +92,13 @@ pub trait Reflect: Any + Send + Sync { /// Returns the value as a [`&mut dyn Any`][std::any::Any]. fn as_any_mut(&mut self) -> &mut dyn Any; - /// Casts this type to a reflected value + /// Casts this type to a boxed reflected value. + fn into_reflect(self: Box) -> Box; + + /// Casts this type to a reflected value. fn as_reflect(&self) -> &dyn Reflect; - /// Casts this type to a mutable reflected value + /// Casts this type to a mutable reflected value. fn as_reflect_mut(&mut self) -> &mut dyn Reflect; /// Applies a reflected value to this value. diff --git a/crates/bevy_reflect/src/struct_trait.rs b/crates/bevy_reflect/src/struct_trait.rs index b4c897efd73a6e..4b8485cbb5b3eb 100644 --- a/crates/bevy_reflect/src/struct_trait.rs +++ b/crates/bevy_reflect/src/struct_trait.rs @@ -404,6 +404,11 @@ impl Reflect for DynamicStruct { self } + #[inline] + fn into_reflect(self: Box) -> Box { + self + } + #[inline] fn as_reflect(&self) -> &dyn Reflect { self diff --git a/crates/bevy_reflect/src/tuple.rs b/crates/bevy_reflect/src/tuple.rs index 527982b029539e..cebabaf3ffc9d2 100644 --- a/crates/bevy_reflect/src/tuple.rs +++ b/crates/bevy_reflect/src/tuple.rs @@ -316,6 +316,11 @@ impl Reflect for DynamicTuple { self } + #[inline] + fn into_reflect(self: Box) -> Box { + self + } + #[inline] fn as_reflect(&self) -> &dyn Reflect { self @@ -520,6 +525,10 @@ macro_rules! impl_reflect_tuple { self } + fn into_reflect(self: Box) -> Box { + self + } + fn as_reflect(&self) -> &dyn Reflect { self } diff --git a/crates/bevy_reflect/src/tuple_struct.rs b/crates/bevy_reflect/src/tuple_struct.rs index d6549521bc34f4..e8c52bdadddbd2 100644 --- a/crates/bevy_reflect/src/tuple_struct.rs +++ b/crates/bevy_reflect/src/tuple_struct.rs @@ -307,6 +307,11 @@ impl Reflect for DynamicTupleStruct { self } + #[inline] + fn into_reflect(self: Box) -> Box { + self + } + #[inline] fn as_reflect(&self) -> &dyn Reflect { self diff --git a/crates/bevy_reflect/src/type_info.rs b/crates/bevy_reflect/src/type_info.rs index f309d6daa5bffe..42e011c14915f4 100644 --- a/crates/bevy_reflect/src/type_info.rs +++ b/crates/bevy_reflect/src/type_info.rs @@ -53,6 +53,7 @@ use std::any::{Any, TypeId}; /// # fn into_any(self: Box) -> Box { todo!() } /// # fn as_any(&self) -> &dyn Any { todo!() } /// # fn as_any_mut(&mut self) -> &mut dyn Any { todo!() } +/// # fn into_reflect(self: Box) -> Box { todo!() } /// # fn as_reflect(&self) -> &dyn Reflect { todo!() } /// # fn as_reflect_mut(&mut self) -> &mut dyn Reflect { todo!() } /// # fn apply(&mut self, value: &dyn Reflect) { todo!() } diff --git a/crates/bevy_reflect/src/utility.rs b/crates/bevy_reflect/src/utility.rs index 773360312cea11..8474bcb6e8595b 100644 --- a/crates/bevy_reflect/src/utility.rs +++ b/crates/bevy_reflect/src/utility.rs @@ -40,6 +40,7 @@ use std::any::{Any, TypeId}; /// # fn into_any(self: Box) -> Box { todo!() } /// # fn as_any(&self) -> &dyn Any { todo!() } /// # fn as_any_mut(&mut self) -> &mut dyn Any { todo!() } +/// # fn into_reflect(self: Box) -> Box { todo!() } /// # fn as_reflect(&self) -> &dyn Reflect { todo!() } /// # fn as_reflect_mut(&mut self) -> &mut dyn Reflect { todo!() } /// # fn apply(&mut self, value: &dyn Reflect) { todo!() } @@ -102,6 +103,7 @@ impl NonGenericTypeInfoCell { /// # fn into_any(self: Box) -> Box { todo!() } /// # fn as_any(&self) -> &dyn Any { todo!() } /// # fn as_any_mut(&mut self) -> &mut dyn Any { todo!() } +/// # fn into_reflect(self: Box) -> Box { todo!() } /// # fn as_reflect(&self) -> &dyn Reflect { todo!() } /// # fn as_reflect_mut(&mut self) -> &mut dyn Reflect { todo!() } /// # fn apply(&mut self, value: &dyn Reflect) { todo!() }