@@ -59,6 +59,9 @@ pub(crate) static REFLECT_VALUE_ATTRIBUTE_NAME: &str = "reflect_value";
59
59
/// one for `ReflectFoo` and another for `ReflectBar`.
60
60
/// This assumes these types are indeed in-scope wherever this macro is called.
61
61
///
62
+ /// This is often used with traits that have been marked by the [`reflect_trait`] macro
63
+ /// in order to register the type's implementation of that trait.
64
+ ///
62
65
/// ### Special Identifiers
63
66
///
64
67
/// There are a few "special" identifiers that work a bit differently:
@@ -116,6 +119,8 @@ pub(crate) static REFLECT_VALUE_ATTRIBUTE_NAME: &str = "reflect_value";
116
119
///
117
120
/// What this does is register the `SerializationData` type within the `GetTypeRegistration` implementation,
118
121
/// which will be used by the reflection serializers to determine whether or not the field is serializable.
122
+ ///
123
+ /// [`reflect_trait`]: macro@reflect_trait
119
124
#[ proc_macro_derive( Reflect , attributes( reflect, reflect_value) ) ]
120
125
pub fn derive_reflect ( input : TokenStream ) -> TokenStream {
121
126
let ast = parse_macro_input ! ( input as DeriveInput ) ;
@@ -167,6 +172,55 @@ pub fn derive_type_uuid(input: TokenStream) -> TokenStream {
167
172
type_uuid:: type_uuid_derive ( input)
168
173
}
169
174
175
+ /// A macro that automatically generates type data for traits, which their implementors can then register.
176
+ ///
177
+ /// The output of this macro is a struct that takes reflected instances of the implementor's type
178
+ /// and returns the value as a trait object.
179
+ /// Because of this, **it can only be used on [object-safe] traits.**
180
+ ///
181
+ /// For a trait named `MyTrait`, this will generate the struct `ReflectMyTrait`.
182
+ /// The generated struct can be created using `FromType` with any type that implements the trait.
183
+ /// The creation and registration of this generated struct as type data can be automatically handled
184
+ /// by the [`Reflect` derive macro].
185
+ ///
186
+ /// # Example
187
+ ///
188
+ /// ```ignore
189
+ /// # use std::any::TypeId;
190
+ /// # use bevy_reflect_derive::{Reflect, reflect_trait};
191
+ /// #[reflect_trait] // Generates `ReflectMyTrait`
192
+ /// trait MyTrait {
193
+ /// fn print(&self) -> &str;
194
+ /// }
195
+ ///
196
+ /// #[derive(Reflect)]
197
+ /// #[reflect(MyTrait)] // Automatically registers `ReflectMyTrait`
198
+ /// struct SomeStruct;
199
+ ///
200
+ /// impl MyTrait for SomeStruct {
201
+ /// fn print(&self) -> &str {
202
+ /// "Hello, World!"
203
+ /// }
204
+ /// }
205
+ ///
206
+ /// // We can create the type data manually if we wanted:
207
+ /// let my_trait: ReflectMyTrait = FromType::<SomeStruct>::from_type();
208
+ ///
209
+ /// // Or we can simply get it from the registry:
210
+ /// let mut registry = TypeRegistry::default();
211
+ /// registry.register::<SomeStruct>();
212
+ /// let my_trait = registry
213
+ /// .get_type_data::<ReflectMyTrait>(TypeId::of::<SomeStruct>())
214
+ /// .unwrap();
215
+ ///
216
+ /// // Then use it on reflected data
217
+ /// let reflected: Box<dyn Reflect> = Box::new(SomeStruct);
218
+ /// let reflected_my_trait: &dyn MyTrait = my_trait.get(&*reflected).unwrap();
219
+ /// assert_eq!("Hello, World!", reflected_my_trait.print());
220
+ /// ```
221
+ ///
222
+ /// [object-safe]: https://doc.rust-lang.org/reference/items/traits.html#object-safety
223
+ /// [`Reflect` derive macro]: Reflect
170
224
#[ proc_macro_attribute]
171
225
pub fn reflect_trait ( args : TokenStream , input : TokenStream ) -> TokenStream {
172
226
trait_reflection:: reflect_trait ( & args, input)
0 commit comments