bevy/crates/bevy_reflect/src
Gino Valente 63f1a9dec8 bevy_reflect: Add ReflectFromReflect (v2) (#6245)
# Objective

Resolves #4597 (based on the work from #6056 and a refresh of #4147)

When using reflection, we may often end up in a scenario where we have a Dynamic representing a certain type. Unfortunately, we can't just call `MyType::from_reflect` as we do not have knowledge of the concrete type (`MyType`) at runtime.

Such scenarios happen when we call `Reflect::clone_value`, use the reflection deserializers, or create the Dynamic type ourselves.

## Solution

Add a `ReflectFromReflect` type data struct.

This struct allows us to easily convert Dynamic representations of our types into their respective concrete instances.

```rust
#[derive(Reflect, FromReflect)]
#[reflect(FromReflect)] // <- Register `ReflectFromReflect`
struct MyStruct(String);

let type_id = TypeId::of::<MyStruct>();

// Register our type
let mut registry = TypeRegistry::default();
registry.register::<MyStruct>();

// Create a concrete instance
let my_struct = MyStruct("Hello world".to_string());

// `Reflect::clone_value` will generate a `DynamicTupleStruct` for tuple struct types
let dynamic_value: Box<dyn Reflect> = my_struct.clone_value();
assert!(!dynamic_value.is::<MyStruct>());

// Get the `ReflectFromReflect` type data from the registry
let rfr: &ReflectFromReflect = registry
  .get_type_data::<ReflectFromReflect>(type_id)
  .unwrap();

// Call `FromReflect::from_reflect` on our Dynamic value
let concrete_value: Box<dyn Reflect> = rfr.from_reflect(&dynamic_value);
assert!(concrete_value.is::<MyStruct>());
```

### Why this PR?

###### Why now?

The three main reasons I closed #4147 were that:

1. Registering `ReflectFromReflect` is clunky (deriving `FromReflect` *and* registering `ReflectFromReflect`)
2. The ecosystem and Bevy itself didn't seem to pay much attention to deriving `FromReflect`
3. I didn't see a lot of desire from the community for such a feature

However, as time has passed it seems 2 and 3 are not really true anymore. Bevy is internally adding lots more `FromReflect` derives, which should make this feature all the more useful. Additionally, I have seen a growing number of people look for something like `ReflectFromReflect`.

I think 1 is still an issue, but not a horrible one. Plus it could be made much, much better using #6056. And I think splitting this feature out of #6056 could lead to #6056 being adopted sooner (or at least make the need more clear to users).

###### Why not just re-open #4147?

The main reason is so that this PR can garner more attention than simply re-opening the old one. This helps bring fresh eyes to the PR for potentially more perspectives/reviews.

---

## Changelog

* Added `ReflectFromReflect`

Co-authored-by: Gino Valente <49806985+MrGVSV@users.noreply.github.com>
2022-12-11 17:52:48 +00:00
..
enums bevy_reflect: Add Reflect::into_reflect (#6502) 2022-11-07 02:11:16 +00:00
impls Make proc macros hygienic in bevy_reflect_derive (#6752) 2022-12-05 23:39:44 +00:00
serde bevy_reflect: Fix binary deserialization not working for unit structs (#6722) 2022-11-23 00:01:36 +00:00
array.rs bevy_reflect: Add Reflect::into_reflect (#6502) 2022-11-07 02:11:16 +00:00
fields.rs bevy_reflect: Reflect doc comments (#6234) 2022-10-18 13:49:57 +00:00
from_reflect.rs bevy_reflect: Add ReflectFromReflect (v2) (#6245) 2022-12-11 17:52:48 +00:00
lib.rs bevy_reflect: Add ReflectFromReflect (v2) (#6245) 2022-12-11 17:52:48 +00:00
list.rs Updated docs for `List Trait in bevy_reflect` (#6872) 2022-12-07 23:10:25 +00:00
map.rs Add remove method to Map reflection trait. (#6564) 2022-11-14 21:03:39 +00:00
path.rs Make arrays behave like lists in reflection (#5987) 2022-09-27 18:11:38 +00:00
reflect.rs bevy_reflect: Add ReflectFromReflect (v2) (#6245) 2022-12-11 17:52:48 +00:00
std_traits.rs fix nightly clippy warnings (#6395) 2022-10-28 21:03:01 +00:00
struct_trait.rs bevy_reflect: Add Reflect::into_reflect (#6502) 2022-11-07 02:11:16 +00:00
tuple_struct.rs bevy_reflect: Add Reflect::into_reflect (#6502) 2022-11-07 02:11:16 +00:00
tuple.rs bevy_reflect: Add Reflect::into_reflect (#6502) 2022-11-07 02:11:16 +00:00
type_info.rs bevy_reflect: Add Reflect::into_reflect (#6502) 2022-11-07 02:11:16 +00:00
type_registry.rs Add safe constructors for untyped pointers Ptr and PtrMut (#6539) 2022-11-14 22:53:50 +00:00
type_uuid.rs
utility.rs bevy_reflect: Add Reflect::into_reflect (#6502) 2022-11-07 02:11:16 +00:00