Skip to content

Commit 4a62390

Browse files
committed
Document reflect_trait
1 parent 546f3b1 commit 4a62390

File tree

1 file changed

+52
-0
lines changed
  • crates/bevy_reflect/bevy_reflect_derive/src

1 file changed

+52
-0
lines changed

crates/bevy_reflect/bevy_reflect_derive/src/lib.rs

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,9 @@ pub(crate) static REFLECT_VALUE_ATTRIBUTE_NAME: &str = "reflect_value";
5959
/// one for `ReflectFoo` and another for `ReflectBar`.
6060
/// This assumes these types are indeed in-scope wherever this macro is called.
6161
///
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+
///
6265
/// ### Special Identifiers
6366
///
6467
/// There are a few "special" identifiers that work a bit differently:
@@ -167,6 +170,55 @@ pub fn derive_type_uuid(input: TokenStream) -> TokenStream {
167170
type_uuid::type_uuid_derive(input)
168171
}
169172

173+
/// A macro that automatically generates type data for traits, which their implementors can then register.
174+
///
175+
/// The output of this macro is a struct that takes reflected instances of the implementor's type
176+
/// and returns the value as a trait object.
177+
/// Because of this, **it can only be used on [object-safe] traits.**
178+
///
179+
/// For a trait named `MyTrait`, this will generate the struct `ReflectMyTrait`.
180+
/// The generated struct can be created using `FromType` with any type that implements the trait.
181+
/// The creation and registration of this generated struct as type data can be automatically handled
182+
/// by the [`Reflect` derive macro].
183+
///
184+
/// # Example
185+
///
186+
/// ```ignore
187+
/// # use std::any::TypeId;
188+
/// # use bevy_reflect_derive::{Reflect, reflect_trait};
189+
/// #[reflect_trait] // Generates `ReflectMyTrait`
190+
/// trait MyTrait {
191+
/// fn print(&self) -> &str;
192+
/// }
193+
///
194+
/// #[derive(Reflect)]
195+
/// #[reflect(MyTrait)] // Automatically registers `ReflectMyTrait`
196+
/// struct SomeStruct;
197+
///
198+
/// impl MyTrait for SomeStruct {
199+
/// fn print(&self) -> &str {
200+
/// "Hello, World!"
201+
/// }
202+
/// }
203+
///
204+
/// // We can create the type data manually if we wanted:
205+
/// let my_trait: ReflectMyTrait = FromType::<SomeStruct>::from_type();
206+
///
207+
/// // Or we can simply get it from the registry:
208+
/// let mut registry = TypeRegistry::default();
209+
/// registry.register::<SomeStruct>();
210+
/// let my_trait = registry
211+
/// .get_type_data::<ReflectMyTrait>(TypeId::of::<SomeStruct>())
212+
/// .unwrap();
213+
///
214+
/// // Then use it on reflected data
215+
/// let reflected: Box<dyn Reflect> = Box::new(SomeStruct);
216+
/// let reflected_my_trait: &dyn MyTrait = my_trait.get(&*reflected).unwrap();
217+
/// assert_eq!("Hello, World!", reflected_my_trait.print());
218+
/// ```
219+
///
220+
/// [object-safe]: https://doc.rust-lang.org/reference/items/traits.html#object-safety
221+
/// [`Reflect` derive macro]: Reflect
170222
#[proc_macro_attribute]
171223
pub fn reflect_trait(args: TokenStream, input: TokenStream) -> TokenStream {
172224
trait_reflection::reflect_trait(&args, input)

0 commit comments

Comments
 (0)