bevy/crates/bevy_reflect/src
Jakob Hellermann 7dcfaaef67 bevy_reflect: ReflectFromPtr to create &dyn Reflect from a *const () (#4475)
# Objective

https://github.com/bevyengine/bevy/pull/4447 adds functions that can fetch resources/components as `*const ()` ptr by providing the `ComponentId`. This alone is not enough for them to be usable safely with reflection, because there is no general way to go from the raw pointer to a `&dyn Reflect` which is the pointer + a pointer to the VTable of the `Reflect` impl.

By adding a `ReflectFromPtr` type that is included in the type type registration when deriving `Reflect`, safe functions can be implemented in scripting languages that don't assume a type layout and can access the component data via reflection:

```rust
#[derive(Reflect)]
struct StringResource {
    value: String
}
```

```lua
local res_id = world:resource_id_by_name("example::StringResource")
local res = world:resource(res_id)

print(res.value)
```

## Solution

1. add a `ReflectFromPtr` type with a `FromType<T: Reflect>` implementation and the following methods:
- `     pub unsafe fn as_reflect_ptr<'a>(&self, val: Ptr<'a>) -> &'a dyn Reflect`
- `     pub unsafe fn as_reflect_ptr_mut<'a>(&self, val: PtrMut<'a>) -> &'a mud dyn Reflect`

Safety requirements of the methods are that you need to check that the `ReflectFromPtr` was constructed for the correct type.

2. add that type to the `TypeRegistration` in the `GetTypeRegistration` impl generated by `#[derive(Reflect)]`.
This is different to other reflected traits because it doesn't need `#[reflect(ReflectReflectFromPtr)]` which IMO should be there by default.

Co-authored-by: Jakob Hellermann <hellermann@sipgate.de>
Co-authored-by: Carter Anderson <mcanders1@gmail.com>
2022-07-19 23:00:34 +00:00
..
impls bevy_reflect: ReflectFromPtr to create &dyn Reflect from a *const () (#4475) 2022-07-19 23:00:34 +00:00
serde bevy_reflect: support map insertion (#5173) 2022-07-04 13:04:19 +00:00
array.rs Make reflect_partial_eq return more accurate results (#5210) 2022-07-05 17:41:54 +00:00
fields.rs bevy_reflect: Add statically available type info for reflected types (#4042) 2022-06-09 21:18:15 +00:00
lib.rs bevy_reflect: remove glam from a test which is active without the glam feature (#5195) 2022-07-04 14:17:46 +00:00
list.rs Make reflect_partial_eq return more accurate results (#5210) 2022-07-05 17:41:54 +00:00
map.rs Make reflect_partial_eq return more accurate results (#5210) 2022-07-05 17:41:54 +00:00
path.rs document more of bevy_reflect (#3655) 2022-01-14 19:09:44 +00:00
reflect.rs bevy_reflect: support map insertion (#5173) 2022-07-04 13:04:19 +00:00
std_traits.rs add #[reflect(Default)] to create default value for reflected types (#3733) 2022-05-03 19:20:13 +00:00
struct_trait.rs Make reflect_partial_eq return more accurate results (#5210) 2022-07-05 17:41:54 +00:00
tuple.rs Make reflect_partial_eq return more accurate results (#5210) 2022-07-05 17:41:54 +00:00
tuple_struct.rs Make reflect_partial_eq return more accurate results (#5210) 2022-07-05 17:41:54 +00:00
type_info.rs Make Reflect safe to implement (#5010) 2022-06-27 16:52:25 +00:00
type_registry.rs bevy_reflect: ReflectFromPtr to create &dyn Reflect from a *const () (#4475) 2022-07-19 23:00:34 +00:00
type_uuid.rs re-enable #[derive(TypeUuid)] for generics (#4118) 2022-04-26 19:41:25 +00:00
utility.rs Make Reflect safe to implement (#5010) 2022-06-27 16:52:25 +00:00