bevy/crates/bevy_reflect/src
Gino Valente 95242fad72 bevy_reflect: Opt-out attribute for TypePath (#9140)
Fixes #9094

Takes a bit from
[this](https://github.com/bevyengine/bevy/issues/9094#issuecomment-1629333851)
comment as well as a
[comment](https://discord.com/channels/691052431525675048/1002362493634629796/1128024873260810271)
from @soqb.

This allows users to opt-out of the `TypePath` implementation that is
automatically generated by the `Reflect` derive macro, allowing custom
`TypePath` implementations.

```rust
struct Foo<T> {
    #[reflect(ignore)]
    _marker: PhantomData<T>,
}

struct NotTypePath;

impl<T: 'static> TypePath for Foo<T> {
    fn type_path() -> &'static str {
        std::any::type_name::<Self>()
    }

    fn short_type_path() -> &'static str {
        static CELL: GenericTypePathCell = GenericTypePathCell::new();
        CELL.get_or_insert::<Self, _>(|| {
            bevy_utils::get_short_name(std::any::type_name::<Self>())
        })
    }

    fn crate_name() -> Option<&'static str> {
        Some("my_crate")
    }

    fn module_path() -> Option<&'static str> {
        Some("my_crate::foo")
    }

    fn type_ident() -> Option<&'static str> {
        Some("Foo")
    }
}

// Can use `TypePath`
let _ = <Foo<NotTypePath> as TypePath>::type_path();

// Can register the type
let mut registry = TypeRegistry::default();
registry.register::<Foo<NotTypePath>>();
```

The stability of type paths mainly come into play during serialization.
If a type is moved between builds, an unstable type path may become
invalid.

Users that opt-out of `TypePath` and rely on something like
`std::any::type_name` as in the example above, should be aware that this
solution removes the stability guarantees. Deserialization thus expects
that type to never move. If it does, then the serialized type paths will
need to be updated accordingly.

If a user depends on stability, they will need to implement that
stability logic manually (probably by looking at the expanded output of
a typical `Reflect`/`TypePath` derive). This could be difficult for type
parameters that don't/can't implement `TypePath`, and will need to make
heavy use of string parsing and manipulation to achieve the same effect
(alternatively, they can choose to simply exclude any type parameter
that doesn't implement `TypePath`).

---

- Added the `#[reflect(type_path = false)]` attribute to opt out of the
`TypePath` impl when deriving `Reflect`

---------

Co-authored-by: Carter Anderson <mcanders1@gmail.com>
2023-08-09 18:11:07 -07:00
..
enums bevy_reflect: FromReflect Ergonomics Implementation (#6056) 2023-06-29 01:31:34 +00:00
impls bevy_reflect: FromReflect Ergonomics Implementation (#6056) 2023-06-29 01:31:34 +00:00
serde bevy_reflect: FromReflect Ergonomics Implementation (#6056) 2023-06-29 01:31:34 +00:00
array.rs Reflect now requires DynamicTypePath. Remove Reflect::get_type_path() (#8764) 2023-06-06 17:23:58 +00:00
fields.rs bevy_reflect: Reflect doc comments (#6234) 2022-10-18 13:49:57 +00:00
from_reflect.rs bevy_reflect: FromReflect Ergonomics Implementation (#6056) 2023-06-29 01:31:34 +00:00
lib.rs bevy_reflect: Opt-out attribute for TypePath (#9140) 2023-08-09 18:11:07 -07:00
list.rs Reflect now requires DynamicTypePath. Remove Reflect::get_type_path() (#8764) 2023-06-06 17:23:58 +00:00
map.rs Reflect now requires DynamicTypePath. Remove Reflect::get_type_path() (#8764) 2023-06-06 17:23:58 +00:00
path.rs bevy_reflect: FromReflect Ergonomics Implementation (#6056) 2023-06-29 01:31:34 +00:00
reflect.rs Reflect now requires DynamicTypePath. Remove Reflect::get_type_path() (#8764) 2023-06-06 17:23:58 +00:00
std_traits.rs fix nightly clippy warnings (#6395) 2022-10-28 21:03:01 +00:00
struct_trait.rs Reflect now requires DynamicTypePath. Remove Reflect::get_type_path() (#8764) 2023-06-06 17:23:58 +00:00
tuple_struct.rs Reflect now requires DynamicTypePath. Remove Reflect::get_type_path() (#8764) 2023-06-06 17:23:58 +00:00
tuple.rs Reflect now requires DynamicTypePath. Remove Reflect::get_type_path() (#8764) 2023-06-06 17:23:58 +00:00
type_info.rs Reflect now requires DynamicTypePath. Remove Reflect::get_type_path() (#8764) 2023-06-06 17:23:58 +00:00
type_path.rs Reflect now requires DynamicTypePath. Remove Reflect::get_type_path() (#8764) 2023-06-06 17:23:58 +00:00
type_registry.rs Fixed several missing links in docs. (#8117) 2023-04-23 17:28:36 +00:00
type_uuid_impl.rs implement TypeUuid for primitives and fix multiple-parameter generics having the same TypeUuid (#6633) 2023-02-16 17:09:44 +00:00
type_uuid.rs implement TypeUuid for primitives and fix multiple-parameter generics having the same TypeUuid (#6633) 2023-02-16 17:09:44 +00:00
utility.rs reflect: avoid deadlock in GenericTypeCell (#8957) 2023-06-27 18:07:49 +00:00