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<dyn Struct> = Box::new(Foo::default());
do_something(foo.as_reflect());
```

However, there is no way to convert a _boxed_ reflection trait object to a `Box<dyn Reflect>`.

## 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<dyn Reflect>) {/* ... */}

let foo: Box<dyn Struct> = Box::new(Foo::default());
do_something(foo.into_reflect());
```

---

## Changelog

- Added `Reflect::into_reflect`
This commit is contained in:
Gino Valente 2022-11-07 02:11:16 +00:00
parent 33299f0bad
commit 02fbf16c80
17 changed files with 109 additions and 2 deletions

View File

@ -202,6 +202,11 @@ pub(crate) fn impl_enum(reflect_enum: &ReflectEnum) -> TokenStream {
self
}
#[inline]
fn into_reflect(self: Box<Self>) -> Box<dyn #bevy_reflect_path::Reflect> {
self
}
#[inline]
fn as_reflect(&self) -> &dyn #bevy_reflect_path::Reflect {
self

View File

@ -183,6 +183,11 @@ pub(crate) fn impl_struct(reflect_struct: &ReflectStruct) -> TokenStream {
self
}
#[inline]
fn into_reflect(self: Box<Self>) -> Box<dyn #bevy_reflect_path::Reflect> {
self
}
#[inline]
fn as_reflect(&self) -> &dyn #bevy_reflect_path::Reflect {
self

View File

@ -145,6 +145,11 @@ pub(crate) fn impl_tuple_struct(reflect_struct: &ReflectStruct) -> TokenStream {
self
}
#[inline]
fn into_reflect(self: Box<Self>) -> Box<dyn #bevy_reflect_path::Reflect> {
self
}
#[inline]
fn as_reflect(&self) -> &dyn #bevy_reflect_path::Reflect {
self

View File

@ -64,6 +64,11 @@ pub(crate) fn impl_value(meta: &ReflectMeta) -> TokenStream {
self
}
#[inline]
fn into_reflect(self: Box<Self>) -> Box<dyn #bevy_reflect_path::Reflect> {
self
}
#[inline]
fn as_reflect(&self) -> &dyn #bevy_reflect_path::Reflect {
self

View File

@ -197,6 +197,11 @@ impl Reflect for DynamicArray {
self
}
#[inline]
fn into_reflect(self: Box<Self>) -> Box<dyn Reflect> {
self
}
#[inline]
fn as_reflect(&self) -> &dyn Reflect {
self

View File

@ -315,6 +315,11 @@ impl Reflect for DynamicEnum {
self
}
#[inline]
fn into_reflect(self: Box<Self>) -> Box<dyn Reflect> {
self
}
#[inline]
fn as_reflect(&self) -> &dyn Reflect {
self

View File

@ -90,6 +90,10 @@ where
self
}
fn into_reflect(self: Box<Self>) -> Box<dyn Reflect> {
self
}
fn as_reflect(&self) -> &dyn Reflect {
self
}

View File

@ -245,6 +245,10 @@ impl<T: FromReflect> Reflect for Vec<T> {
self
}
fn into_reflect(self: Box<Self>) -> Box<dyn Reflect> {
self
}
fn as_reflect(&self) -> &dyn Reflect {
self
}
@ -413,6 +417,11 @@ impl<K: FromReflect + Eq + Hash, V: FromReflect> Reflect for HashMap<K, V> {
self
}
#[inline]
fn into_reflect(self: Box<Self>) -> Box<dyn Reflect> {
self
}
fn as_reflect(&self) -> &dyn Reflect {
self
}
@ -543,6 +552,11 @@ impl<T: Reflect, const N: usize> Reflect for [T; N] {
self
}
#[inline]
fn into_reflect(self: Box<Self>) -> Box<dyn Reflect> {
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<Self>) -> Box<dyn Reflect> {
self
}
fn as_reflect(&self) -> &dyn Reflect {
self
}
@ -819,6 +837,11 @@ impl<T: FromReflect> Reflect for Option<T> {
self
}
#[inline]
fn into_reflect(self: Box<Self>) -> Box<dyn Reflect> {
self
}
fn as_reflect(&self) -> &dyn Reflect {
self
}

View File

@ -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<dyn TestTrait> = Box::new(TestStruct);
// Should compile:
let _ = trait_object.into_reflect();
}
#[test]
fn as_reflect() {
trait TestTrait: Reflect {}

View File

@ -216,6 +216,11 @@ impl Reflect for DynamicList {
self
}
#[inline]
fn into_reflect(self: Box<Self>) -> Box<dyn Reflect> {
self
}
#[inline]
fn as_reflect(&self) -> &dyn Reflect {
self

View File

@ -273,6 +273,11 @@ impl Reflect for DynamicMap {
self
}
#[inline]
fn into_reflect(self: Box<Self>) -> Box<dyn Reflect> {
self
}
#[inline]
fn as_reflect(&self) -> &dyn Reflect {
self

View File

@ -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<Self>) -> Box<dyn Reflect>;
/// 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.

View File

@ -404,6 +404,11 @@ impl Reflect for DynamicStruct {
self
}
#[inline]
fn into_reflect(self: Box<Self>) -> Box<dyn Reflect> {
self
}
#[inline]
fn as_reflect(&self) -> &dyn Reflect {
self

View File

@ -316,6 +316,11 @@ impl Reflect for DynamicTuple {
self
}
#[inline]
fn into_reflect(self: Box<Self>) -> Box<dyn Reflect> {
self
}
#[inline]
fn as_reflect(&self) -> &dyn Reflect {
self
@ -520,6 +525,10 @@ macro_rules! impl_reflect_tuple {
self
}
fn into_reflect(self: Box<Self>) -> Box<dyn Reflect> {
self
}
fn as_reflect(&self) -> &dyn Reflect {
self
}

View File

@ -307,6 +307,11 @@ impl Reflect for DynamicTupleStruct {
self
}
#[inline]
fn into_reflect(self: Box<Self>) -> Box<dyn Reflect> {
self
}
#[inline]
fn as_reflect(&self) -> &dyn Reflect {
self

View File

@ -53,6 +53,7 @@ use std::any::{Any, TypeId};
/// # fn into_any(self: Box<Self>) -> Box<dyn Any> { todo!() }
/// # fn as_any(&self) -> &dyn Any { todo!() }
/// # fn as_any_mut(&mut self) -> &mut dyn Any { todo!() }
/// # fn into_reflect(self: Box<Self>) -> Box<dyn Reflect> { 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!() }

View File

@ -40,6 +40,7 @@ use std::any::{Any, TypeId};
/// # fn into_any(self: Box<Self>) -> Box<dyn Any> { todo!() }
/// # fn as_any(&self) -> &dyn Any { todo!() }
/// # fn as_any_mut(&mut self) -> &mut dyn Any { todo!() }
/// # fn into_reflect(self: Box<Self>) -> Box<dyn Reflect> { 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<Self>) -> Box<dyn Any> { todo!() }
/// # fn as_any(&self) -> &dyn Any { todo!() }
/// # fn as_any_mut(&mut self) -> &mut dyn Any { todo!() }
/// # fn into_reflect(self: Box<Self>) -> Box<dyn Reflect> { 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!() }