pub trait Reflect:
PartialReflect
+ DynamicTyped
+ Any {
// Required methods
fn into_any(self: Box<Self>) -> Box<dyn Any>;
fn as_any(&self) -> &(dyn Any + 'static);
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static);
fn into_reflect(self: Box<Self>) -> Box<dyn Reflect>;
fn as_reflect(&self) -> &(dyn Reflect + 'static);
fn as_reflect_mut(&mut self) -> &mut (dyn Reflect + 'static);
fn set(&mut self, value: Box<dyn Reflect>) -> Result<(), Box<dyn Reflect>>;
}
Expand description
A core trait of bevy_reflect
, used for downcasting to concrete types.
This is a subtrait of PartialReflect
,
meaning any type which implements Reflect
implements PartialReflect
by definition.
It’s recommended to use the derive macro rather than manually implementing this trait.
Doing so will automatically implement this trait, PartialReflect
, and many other useful traits for reflection,
including one of the appropriate subtraits: Struct
, TupleStruct
or Enum
.
If you need to use this trait as a generic bound along with other reflection traits,
for your convenience, consider using Reflectable
instead.
See the crate-level documentation to see how this trait can be used.
Required Methods§
Sourcefn into_any(self: Box<Self>) -> Box<dyn Any>
fn into_any(self: Box<Self>) -> Box<dyn Any>
Returns the value as a Box<dyn Any>
.
For remote wrapper types, this will return the remote type instead.
Sourcefn as_any(&self) -> &(dyn Any + 'static)
fn as_any(&self) -> &(dyn Any + 'static)
Returns the value as a &dyn Any
.
For remote wrapper types, this will return the remote type instead.
Sourcefn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
Returns the value as a &mut dyn Any
.
For remote wrapper types, this will return the remote type instead.
Sourcefn into_reflect(self: Box<Self>) -> Box<dyn Reflect>
fn into_reflect(self: Box<Self>) -> Box<dyn Reflect>
Casts this type to a boxed, fully-reflected value.
Sourcefn as_reflect(&self) -> &(dyn Reflect + 'static)
fn as_reflect(&self) -> &(dyn Reflect + 'static)
Casts this type to a fully-reflected value.
Sourcefn as_reflect_mut(&mut self) -> &mut (dyn Reflect + 'static)
fn as_reflect_mut(&mut self) -> &mut (dyn Reflect + 'static)
Casts this type to a mutable, fully-reflected value.
Implementations§
Source§impl dyn Reflect
impl dyn Reflect
Sourcepub fn downcast<T>(self: Box<dyn Reflect>) -> Result<Box<T>, Box<dyn Reflect>>where
T: Any,
pub fn downcast<T>(self: Box<dyn Reflect>) -> Result<Box<T>, Box<dyn Reflect>>where
T: Any,
Downcasts the value to type T
, consuming the trait object.
If the underlying value is not of type T
, returns Err(self)
.
For remote types, T
should be the type itself rather than the wrapper type.
Sourcepub fn take<T>(self: Box<dyn Reflect>) -> Result<T, Box<dyn Reflect>>where
T: Any,
pub fn take<T>(self: Box<dyn Reflect>) -> Result<T, Box<dyn Reflect>>where
T: Any,
Downcasts the value to type T
, unboxing and consuming the trait object.
If the underlying value is not of type T
, returns Err(self)
.
For remote types, T
should be the type itself rather than the wrapper type.
Examples found in repository?
10fn main() {
11 trait Damageable {
12 type Health;
13 fn damage(&mut self, damage: Self::Health);
14 }
15
16 #[derive(Reflect, PartialEq, Debug)]
17 struct Zombie {
18 health: u32,
19 }
20
21 impl Damageable for Zombie {
22 type Health = u32;
23 fn damage(&mut self, damage: Self::Health) {
24 self.health -= damage;
25 }
26 }
27
28 // Let's say we have a reflected value.
29 // Here we know it's a `Zombie`, but for demonstration purposes let's pretend we don't.
30 // Pretend it's just some `Box<dyn Reflect>` value.
31 let mut value: Box<dyn Reflect> = Box::new(Zombie { health: 100 });
32
33 // We think `value` might contain a type that implements `Damageable`
34 // and now we want to call `Damageable::damage` on it.
35 // How can we do this without knowing in advance the concrete type is `Zombie`?
36
37 // This is where type data comes in.
38 // Type data is a way of associating type-specific data with a type for use in dynamic contexts.
39 // This type data can then be used at runtime to perform type-specific operations.
40
41 // Let's create a type data struct for `Damageable` that we can associate with `Zombie`!
42
43 // Firstly, type data must be cloneable.
44 #[derive(Clone)]
45 // Next, they are usually named with the `Reflect` prefix (we'll see why in a bit).
46 struct ReflectDamageable {
47 // Type data can contain whatever you want, but it's common to include function pointers
48 // to the type-specific operations you want to perform (such as trait methods).
49 // Just remember that we're working with `Reflect` data,
50 // so we can't use `Self`, generics, or associated types.
51 // In those cases, we'll have to use `dyn Reflect` trait objects.
52 damage: fn(&mut dyn Reflect, damage: Box<dyn Reflect>),
53 }
54
55 // Now, we can create a blanket implementation of the `FromType` trait to construct our type data
56 // for any type that implements `Reflect` and `Damageable`.
57 impl<T: Reflect + Damageable<Health: Reflect>> FromType<T> for ReflectDamageable {
58 fn from_type() -> Self {
59 Self {
60 damage: |reflect, damage| {
61 // This requires that `reflect` is `T` and not a dynamic representation like `DynamicStruct`.
62 // We could have the function pointer return a `Result`, but we'll just `unwrap` for simplicity.
63 let damageable = reflect.downcast_mut::<T>().unwrap();
64 let damage = damage.take::<T::Health>().unwrap();
65 damageable.damage(damage);
66 },
67 }
68 }
69 }
70
71 // It's also common to provide convenience methods for calling the type-specific operations.
72 impl ReflectDamageable {
73 pub fn damage(&self, reflect: &mut dyn Reflect, damage: Box<dyn Reflect>) {
74 (self.damage)(reflect, damage);
75 }
76 }
77
78 // With all this done, we're ready to make use of `ReflectDamageable`!
79 // It starts with registering our type along with its type data:
80 let mut registry = TypeRegistry::default();
81 registry.register::<Zombie>();
82 registry.register_type_data::<Zombie, ReflectDamageable>();
83
84 // Then at any point we can retrieve the type data from the registry:
85 let type_id = value.reflect_type_info().type_id();
86 let reflect_damageable = registry
87 .get_type_data::<ReflectDamageable>(type_id)
88 .unwrap();
89
90 // And call our method:
91 reflect_damageable.damage(value.as_reflect_mut(), Box::new(25u32));
92 assert_eq!(value.take::<Zombie>().unwrap(), Zombie { health: 75 });
93
94 // This is a simple example, but type data can be used for much more complex operations.
95 // Bevy also provides some useful shorthand for working with type data.
96
97 // For example, we can have the type data be automatically registered when we register the type
98 // by using the `#[reflect(MyTrait)]` attribute when defining our type.
99 #[derive(Reflect)]
100 // Notice that we don't need to type out `ReflectDamageable`.
101 // This is why we named it with the `Reflect` prefix:
102 // the derive macro will automatically look for a type named `ReflectDamageable` in the current scope.
103 #[reflect(Damageable)]
104 struct Skeleton {
105 health: u32,
106 }
107
108 impl Damageable for Skeleton {
109 type Health = u32;
110 fn damage(&mut self, damage: Self::Health) {
111 self.health -= damage;
112 }
113 }
114
115 // This will now register `Skeleton` along with its `ReflectDamageable` type data.
116 registry.register::<Skeleton>();
117
118 // And for object-safe traits (see https://doc.rust-lang.org/reference/items/traits.html#object-safety),
119 // Bevy provides a convenience macro for generating type data that converts `dyn Reflect` into `dyn MyTrait`.
120 #[reflect_trait]
121 trait Health {
122 fn health(&self) -> u32;
123 }
124
125 impl Health for Skeleton {
126 fn health(&self) -> u32 {
127 self.health
128 }
129 }
130
131 // Using the `#[reflect_trait]` macro we're able to automatically generate a `ReflectHealth` type data struct,
132 // which can then be registered like any other type data:
133 registry.register_type_data::<Skeleton, ReflectHealth>();
134
135 // Now we can use `ReflectHealth` to convert `dyn Reflect` into `dyn Health`:
136 let value: Box<dyn Reflect> = Box::new(Skeleton { health: 50 });
137
138 let type_id = value.reflect_type_info().type_id();
139 let reflect_health = registry.get_type_data::<ReflectHealth>(type_id).unwrap();
140
141 // Type data generated by `#[reflect_trait]` comes with a `get`, `get_mut`, and `get_boxed` method,
142 // which convert `&dyn Reflect` into `&dyn MyTrait`, `&mut dyn Reflect` into `&mut dyn MyTrait`,
143 // and `Box<dyn Reflect>` into `Box<dyn MyTrait>`, respectively.
144 let value: &dyn Health = reflect_health.get(value.as_reflect()).unwrap();
145 assert_eq!(value.health(), 50);
146
147 // Lastly, here's a list of some useful type data provided by Bevy that you might want to register for your types:
148 // - `ReflectDefault` for types that implement `Default`
149 // - `ReflectFromWorld` for types that implement `FromWorld`
150 // - `ReflectComponent` for types that implement `Component`
151 // - `ReflectResource` for types that implement `Resource`
152 // - `ReflectSerialize` for types that implement `Serialize`
153 // - `ReflectDeserialize` for types that implement `Deserialize`
154 //
155 // And here are some that are automatically registered by the `Reflect` derive macro:
156 // - `ReflectFromPtr`
157 // - `ReflectFromReflect` (if not `#[reflect(from_reflect = false)]`)
158}
More examples
67fn setup() {
68 let mut z = <HashMap<_, _>>::default();
69 z.insert("Hello".to_string(), 1.0);
70 let value: Box<dyn Reflect> = Box::new(A {
71 x: 1,
72 y: vec![1, 2],
73 z,
74 });
75
76 // There are a number of different "reflect traits", which each expose different operations on
77 // the underlying type
78 match value.reflect_ref() {
79 // `Struct` is a trait automatically implemented for structs that derive Reflect. This trait
80 // allows you to interact with fields via their string names or indices
81 ReflectRef::Struct(value) => {
82 info!(
83 "This is a 'struct' type with an 'x' value of {}",
84 value.get_field::<usize>("x").unwrap()
85 );
86 }
87 // `TupleStruct` is a trait automatically implemented for tuple structs that derive Reflect.
88 // This trait allows you to interact with fields via their indices
89 ReflectRef::TupleStruct(_) => {}
90 // `Tuple` is a special trait that can be manually implemented (instead of deriving
91 // Reflect). This exposes "tuple" operations on your type, allowing you to interact
92 // with fields via their indices. Tuple is automatically implemented for tuples of
93 // arity 12 or less.
94 ReflectRef::Tuple(_) => {}
95 // `Enum` is a trait automatically implemented for enums that derive Reflect. This trait allows you
96 // to interact with the current variant and its fields (if it has any)
97 ReflectRef::Enum(_) => {}
98 // `List` is a special trait that can be manually implemented (instead of deriving Reflect).
99 // This exposes "list" operations on your type, such as insertion. `List` is automatically
100 // implemented for relevant core types like Vec<T>.
101 ReflectRef::List(_) => {}
102 // `Array` is a special trait that can be manually implemented (instead of deriving Reflect).
103 // This exposes "array" operations on your type, such as indexing. `Array`
104 // is automatically implemented for relevant core types like [T; N].
105 ReflectRef::Array(_) => {}
106 // `Map` is a special trait that can be manually implemented (instead of deriving Reflect).
107 // This exposes "map" operations on your type, such as getting / inserting by key.
108 // Map is automatically implemented for relevant core types like HashMap<K, V>
109 ReflectRef::Map(_) => {}
110 // `Set` is a special trait that can be manually implemented (instead of deriving Reflect).
111 // This exposes "set" operations on your type, such as getting / inserting by value.
112 // Set is automatically implemented for relevant core types like HashSet<T>
113 ReflectRef::Set(_) => {}
114 // `Function` is a special trait that can be manually implemented (instead of deriving Reflect).
115 // This exposes "function" operations on your type, such as calling it with arguments.
116 // This trait is automatically implemented for types like DynamicFunction.
117 // This variant only exists if the `reflect_functions` feature is enabled.
118 #[cfg(feature = "reflect_functions")]
119 ReflectRef::Function(_) => {}
120 // `Opaque` types do not implement any of the other traits above. They are simply a Reflect
121 // implementation. Opaque is implemented for opaque types like String and Instant,
122 // but also include primitive types like i32, usize, and f32 (despite not technically being opaque).
123 ReflectRef::Opaque(_) => {}
124 #[expect(
125 clippy::allow_attributes,
126 reason = "`unreachable_patterns` is not always linted"
127 )]
128 #[allow(
129 unreachable_patterns,
130 reason = "This example cannot always detect when `bevy_reflect/functions` is enabled."
131 )]
132 _ => {}
133 }
134
135 let mut dynamic_list = DynamicList::default();
136 dynamic_list.push(3u32);
137 dynamic_list.push(4u32);
138 dynamic_list.push(5u32);
139
140 let mut value: A = value.take::<A>().unwrap();
141 value.y.apply(&dynamic_list);
142 assert_eq!(value.y, vec![3u32, 4u32, 5u32]);
143}
Sourcepub fn is<T>(&self) -> boolwhere
T: Any,
pub fn is<T>(&self) -> boolwhere
T: Any,
Returns true
if the underlying value is of type T
, or false
otherwise.
The underlying value is the concrete type that is stored in this dyn
object;
it can be downcasted to. In the case that this underlying value “represents”
a different type, like the Dynamic*** types do, you can call represents
to determine what type they represent. Represented types cannot be downcasted
to, but you can use FromReflect
to create a value of the represented type from them.
For remote types, T
should be the type itself rather than the wrapper type.
Sourcepub fn downcast_ref<T>(&self) -> Option<&T>where
T: Any,
pub fn downcast_ref<T>(&self) -> Option<&T>where
T: Any,
Downcasts the value to type T
by reference.
If the underlying value is not of type T
, returns None
.
For remote types, T
should be the type itself rather than the wrapper type.
Examples found in repository?
6fn main() {
7 // Bevy supports statically registering custom attribute data on reflected types,
8 // which can then be accessed at runtime via the type's `TypeInfo`.
9 // Attributes are registered using the `#[reflect(@...)]` syntax,
10 // where the `...` is any expression that resolves to a value which implements `Reflect`.
11 // Note that these attributes are stored based on their type:
12 // if two attributes have the same type, the second one will overwrite the first.
13
14 // Here is an example of registering custom attributes on a type:
15 #[derive(Reflect)]
16 struct Slider {
17 #[reflect(@RangeInclusive::<f32>::new(0.0, 1.0))]
18 // Alternatively, we could have used the `0.0..=1.0` syntax,
19 // but remember to ensure the type is the one you want!
20 #[reflect(@0.0..=1.0_f32)]
21 value: f32,
22 }
23
24 // Now, we can access the custom attributes at runtime:
25 let TypeInfo::Struct(type_info) = Slider::type_info() else {
26 panic!("expected struct");
27 };
28
29 let field = type_info.field("value").unwrap();
30
31 let range = field.get_attribute::<RangeInclusive<f32>>().unwrap();
32 assert_eq!(*range, 0.0..=1.0);
33
34 // And remember that our attributes can be any type that implements `Reflect`:
35 #[derive(Reflect)]
36 struct Required;
37
38 #[derive(Reflect, PartialEq, Debug)]
39 struct Tooltip(String);
40
41 impl Tooltip {
42 fn new(text: &str) -> Self {
43 Self(text.to_string())
44 }
45 }
46
47 #[derive(Reflect)]
48 #[reflect(@Required, @Tooltip::new("An ID is required!"))]
49 struct Id(u8);
50
51 let TypeInfo::TupleStruct(type_info) = Id::type_info() else {
52 panic!("expected struct");
53 };
54
55 // We can check if an attribute simply exists on our type:
56 assert!(type_info.has_attribute::<Required>());
57
58 // We can also get attribute data dynamically:
59 let some_type_id = TypeId::of::<Tooltip>();
60
61 let tooltip: &dyn Reflect = type_info.get_attribute_by_id(some_type_id).unwrap();
62 assert_eq!(
63 tooltip.downcast_ref::<Tooltip>(),
64 Some(&Tooltip::new("An ID is required!"))
65 );
66
67 // And again, attributes of the same type will overwrite each other:
68 #[derive(Reflect)]
69 enum Status {
70 // This will result in `false` being stored:
71 #[reflect(@true)]
72 #[reflect(@false)]
73 Disabled,
74 // This will result in `true` being stored:
75 #[reflect(@false)]
76 #[reflect(@true)]
77 Enabled,
78 }
79
80 let TypeInfo::Enum(type_info) = Status::type_info() else {
81 panic!("expected enum");
82 };
83
84 let disabled = type_info.variant("Disabled").unwrap();
85 assert!(!disabled.get_attribute::<bool>().unwrap());
86
87 let enabled = type_info.variant("Enabled").unwrap();
88 assert!(enabled.get_attribute::<bool>().unwrap());
89}
More examples
56fn setup(type_registry: Res<AppTypeRegistry>) {
57 let mut value = Foo {
58 a: 1,
59 _ignored: NonReflectedValue { _a: 10 },
60 nested: Bar { b: 8 },
61 };
62
63 // You can set field values like this. The type must match exactly or this will fail.
64 *value.get_field_mut("a").unwrap() = 2usize;
65 assert_eq!(value.a, 2);
66 assert_eq!(*value.get_field::<usize>("a").unwrap(), 2);
67
68 // You can also get the `&dyn PartialReflect` value of a field like this
69 let field = value.field("a").unwrap();
70
71 // But values introspected via `PartialReflect` will not return `dyn Reflect` trait objects
72 // (even if the containing type does implement `Reflect`), so we need to convert them:
73 let fully_reflected_field = field.try_as_reflect().unwrap();
74
75 // Now, you can downcast your `Reflect` value like this:
76 assert_eq!(*fully_reflected_field.downcast_ref::<usize>().unwrap(), 2);
77
78 // For this specific case, we also support the shortcut `try_downcast_ref`:
79 assert_eq!(*field.try_downcast_ref::<usize>().unwrap(), 2);
80
81 // `DynamicStruct` also implements the `Struct` and `Reflect` traits.
82 let mut patch = DynamicStruct::default();
83 patch.insert("a", 4usize);
84
85 // You can "apply" Reflect implementations on top of other Reflect implementations.
86 // This will only set fields with the same name, and it will fail if the types don't match.
87 // You can use this to "patch" your types with new values.
88 value.apply(&patch);
89 assert_eq!(value.a, 4);
90
91 let type_registry = type_registry.read();
92 // By default, all derived `Reflect` types can be Serialized using serde. No need to derive
93 // Serialize!
94 let serializer = ReflectSerializer::new(&value, &type_registry);
95 let ron_string =
96 ron::ser::to_string_pretty(&serializer, ron::ser::PrettyConfig::default()).unwrap();
97 info!("{}\n", ron_string);
98
99 // Dynamic properties can be deserialized
100 let reflect_deserializer = ReflectDeserializer::new(&type_registry);
101 let mut deserializer = ron::de::Deserializer::from_str(&ron_string).unwrap();
102 let reflect_value = reflect_deserializer.deserialize(&mut deserializer).unwrap();
103
104 // Deserializing returns a `Box<dyn PartialReflect>` value.
105 // Generally, deserializing a value will return the "dynamic" variant of a type.
106 // For example, deserializing a struct will return the DynamicStruct type.
107 // "Opaque types" will be deserialized as themselves.
108 assert_eq!(
109 reflect_value.reflect_type_path(),
110 DynamicStruct::type_path(),
111 );
112
113 // Reflect has its own `partial_eq` implementation, named `reflect_partial_eq`. This behaves
114 // like normal `partial_eq`, but it treats "dynamic" and "non-dynamic" types the same. The
115 // `Foo` struct and deserialized `DynamicStruct` are considered equal for this reason:
116 assert!(reflect_value.reflect_partial_eq(&value).unwrap());
117
118 // By "patching" `Foo` with the deserialized DynamicStruct, we can "Deserialize" Foo.
119 // This means we can serialize and deserialize with a single `Reflect` derive!
120 value.apply(&*reflect_value);
121}
12fn main() {
13 #[derive(Reflect, Default, PartialEq, Debug)]
14 #[reflect(Identifiable, Default)]
15 struct Player {
16 id: u32,
17 }
18
19 #[reflect_trait]
20 trait Identifiable {
21 fn id(&self) -> u32;
22 }
23
24 impl Identifiable for Player {
25 fn id(&self) -> u32 {
26 self.id
27 }
28 }
29
30 // Normally, when instantiating a type, you get back exactly that type.
31 // This is because the type is known at compile time.
32 // We call this the "concrete" or "canonical" type.
33 let player: Player = Player { id: 123 };
34
35 // When working with reflected types, however, we often "erase" this type information
36 // using the `Reflect` trait object.
37 // This trait object also gives us access to all the methods in the `PartialReflect` trait too.
38 // The underlying type is still the same (in this case, `Player`),
39 // but now we've hidden that information from the compiler.
40 let reflected: Box<dyn Reflect> = Box::new(player);
41
42 // Because it's the same type under the hood, we can still downcast it back to the original type.
43 assert!(reflected.downcast_ref::<Player>().is_some());
44
45 // We can attempt to clone our value using `PartialReflect::reflect_clone`.
46 // This will recursively call `PartialReflect::reflect_clone` on all fields of the type.
47 // Or, if we had registered `ReflectClone` using `#[reflect(Clone)]`, it would simply call `Clone::clone` directly.
48 let cloned: Box<dyn Reflect> = reflected.reflect_clone().unwrap();
49 assert_eq!(cloned.downcast_ref::<Player>(), Some(&Player { id: 123 }));
50
51 // Another way we can "clone" our data is by converting it to a dynamic type.
52 // Notice here we bind it as a `dyn PartialReflect` instead of `dyn Reflect`.
53 // This is because it returns a dynamic type that simply represents the original type.
54 // In this case, because `Player` is a struct, it will return a `DynamicStruct`.
55 let dynamic: Box<dyn PartialReflect> = reflected.to_dynamic();
56 assert!(dynamic.is_dynamic());
57
58 // And if we try to convert it back to a `dyn Reflect` trait object, we'll get `None`.
59 // Dynamic types cannot be directly cast to `dyn Reflect` trait objects.
60 assert!(dynamic.try_as_reflect().is_none());
61
62 // Generally dynamic types are used to represent (or "proxy") the original type,
63 // so that we can continue to access its fields and overall structure.
64 let dynamic_ref = dynamic.reflect_ref().as_struct().unwrap();
65 let id = dynamic_ref.field("id").unwrap().try_downcast_ref::<u32>();
66 assert_eq!(id, Some(&123));
67
68 // It also enables us to create a representation of a type without having compile-time
69 // access to the actual type. This is how the reflection deserializers work.
70 // They generally can't know how to construct a type ahead of time,
71 // so they instead build and return these dynamic representations.
72 let input = "(id: 123)";
73 let mut registry = TypeRegistry::default();
74 registry.register::<Player>();
75 let registration = registry.get(std::any::TypeId::of::<Player>()).unwrap();
76 let deserialized = TypedReflectDeserializer::new(registration, ®istry)
77 .deserialize(&mut ron::Deserializer::from_str(input).unwrap())
78 .unwrap();
79
80 // Our deserialized output is a `DynamicStruct` that proxies/represents a `Player`.
81 assert!(deserialized.represents::<Player>());
82
83 // And while this does allow us to access the fields and structure of the type,
84 // there may be instances where we need the actual type.
85 // For example, if we want to convert our `dyn Reflect` into a `dyn Identifiable`,
86 // we can't use the `DynamicStruct` proxy.
87 let reflect_identifiable = registration
88 .data::<ReflectIdentifiable>()
89 .expect("`ReflectIdentifiable` should be registered");
90
91 // Trying to access the registry with our `deserialized` will give a compile error
92 // since it doesn't implement `Reflect`, only `PartialReflect`.
93 // Similarly, trying to force the operation will fail.
94 // This fails since the underlying type of `deserialized` is `DynamicStruct` and not `Player`.
95 assert!(deserialized
96 .try_as_reflect()
97 .and_then(|reflect_trait_obj| reflect_identifiable.get(reflect_trait_obj))
98 .is_none());
99
100 // So how can we go from a dynamic type to a concrete type?
101 // There are two ways:
102
103 // 1. Using `PartialReflect::apply`.
104 {
105 // If you know the type at compile time, you can construct a new value and apply the dynamic
106 // value to it.
107 let mut value = Player::default();
108 value.apply(deserialized.as_ref());
109 assert_eq!(value.id, 123);
110
111 // If you don't know the type at compile time, you need a dynamic way of constructing
112 // an instance of the type. One such way is to use the `ReflectDefault` type data.
113 let reflect_default = registration
114 .data::<ReflectDefault>()
115 .expect("`ReflectDefault` should be registered");
116
117 let mut value: Box<dyn Reflect> = reflect_default.default();
118 value.apply(deserialized.as_ref());
119
120 let identifiable: &dyn Identifiable = reflect_identifiable.get(value.as_reflect()).unwrap();
121 assert_eq!(identifiable.id(), 123);
122 }
123
124 // 2. Using `FromReflect`
125 {
126 // If you know the type at compile time, you can use the `FromReflect` trait to convert the
127 // dynamic value into the concrete type directly.
128 let value: Player = Player::from_reflect(deserialized.as_ref()).unwrap();
129 assert_eq!(value.id, 123);
130
131 // If you don't know the type at compile time, you can use the `ReflectFromReflect` type data
132 // to perform the conversion dynamically.
133 let reflect_from_reflect = registration
134 .data::<ReflectFromReflect>()
135 .expect("`ReflectFromReflect` should be registered");
136
137 let value: Box<dyn Reflect> = reflect_from_reflect
138 .from_reflect(deserialized.as_ref())
139 .unwrap();
140 let identifiable: &dyn Identifiable = reflect_identifiable.get(value.as_reflect()).unwrap();
141 assert_eq!(identifiable.id(), 123);
142 }
143
144 // Lastly, while dynamic types are commonly generated via reflection methods like
145 // `PartialReflect::to_dynamic` or via the reflection deserializers,
146 // you can also construct them manually.
147 let mut my_dynamic_list = DynamicList::from_iter([1u32, 2u32, 3u32]);
148
149 // This is useful when you just need to apply some subset of changes to a type.
150 let mut my_list: Vec<u32> = Vec::new();
151 my_list.apply(&my_dynamic_list);
152 assert_eq!(my_list, vec![1, 2, 3]);
153
154 // And if you want it to actually proxy a type, you can configure it to do that as well:
155 assert!(!my_dynamic_list
156 .as_partial_reflect()
157 .represents::<Vec<u32>>());
158 my_dynamic_list.set_represented_type(Some(<Vec<u32>>::type_info()));
159 assert!(my_dynamic_list
160 .as_partial_reflect()
161 .represents::<Vec<u32>>());
162
163 // ============================= REFERENCE ============================= //
164 // For reference, here are all the available dynamic types:
165
166 // 1. `DynamicTuple`
167 {
168 let mut dynamic_tuple = DynamicTuple::default();
169 dynamic_tuple.insert(1u32);
170 dynamic_tuple.insert(2u32);
171 dynamic_tuple.insert(3u32);
172
173 let mut my_tuple: (u32, u32, u32) = (0, 0, 0);
174 my_tuple.apply(&dynamic_tuple);
175 assert_eq!(my_tuple, (1, 2, 3));
176 }
177
178 // 2. `DynamicArray`
179 {
180 let dynamic_array = DynamicArray::from_iter([1u32, 2u32, 3u32]);
181
182 let mut my_array = [0u32; 3];
183 my_array.apply(&dynamic_array);
184 assert_eq!(my_array, [1, 2, 3]);
185 }
186
187 // 3. `DynamicList`
188 {
189 let dynamic_list = DynamicList::from_iter([1u32, 2u32, 3u32]);
190
191 let mut my_list: Vec<u32> = Vec::new();
192 my_list.apply(&dynamic_list);
193 assert_eq!(my_list, vec![1, 2, 3]);
194 }
195
196 // 4. `DynamicSet`
197 {
198 let mut dynamic_set = DynamicSet::from_iter(["x", "y", "z"]);
199 assert!(dynamic_set.contains(&"x"));
200
201 dynamic_set.remove(&"y");
202
203 let mut my_set: HashSet<&str> = HashSet::default();
204 my_set.apply(&dynamic_set);
205 assert_eq!(my_set, HashSet::from_iter(["x", "z"]));
206 }
207
208 // 5. `DynamicMap`
209 {
210 let dynamic_map = DynamicMap::from_iter([("x", 1u32), ("y", 2u32), ("z", 3u32)]);
211
212 let mut my_map: HashMap<&str, u32> = HashMap::default();
213 my_map.apply(&dynamic_map);
214 assert_eq!(my_map.get("x"), Some(&1));
215 assert_eq!(my_map.get("y"), Some(&2));
216 assert_eq!(my_map.get("z"), Some(&3));
217 }
218
219 // 6. `DynamicStruct`
220 {
221 #[derive(Reflect, Default, Debug, PartialEq)]
222 struct MyStruct {
223 x: u32,
224 y: u32,
225 z: u32,
226 }
227
228 let mut dynamic_struct = DynamicStruct::default();
229 dynamic_struct.insert("x", 1u32);
230 dynamic_struct.insert("y", 2u32);
231 dynamic_struct.insert("z", 3u32);
232
233 let mut my_struct = MyStruct::default();
234 my_struct.apply(&dynamic_struct);
235 assert_eq!(my_struct, MyStruct { x: 1, y: 2, z: 3 });
236 }
237
238 // 7. `DynamicTupleStruct`
239 {
240 #[derive(Reflect, Default, Debug, PartialEq)]
241 struct MyTupleStruct(u32, u32, u32);
242
243 let mut dynamic_tuple_struct = DynamicTupleStruct::default();
244 dynamic_tuple_struct.insert(1u32);
245 dynamic_tuple_struct.insert(2u32);
246 dynamic_tuple_struct.insert(3u32);
247
248 let mut my_tuple_struct = MyTupleStruct::default();
249 my_tuple_struct.apply(&dynamic_tuple_struct);
250 assert_eq!(my_tuple_struct, MyTupleStruct(1, 2, 3));
251 }
252
253 // 8. `DynamicEnum`
254 {
255 #[derive(Reflect, Default, Debug, PartialEq)]
256 enum MyEnum {
257 #[default]
258 Empty,
259 Xyz(u32, u32, u32),
260 }
261
262 let mut values = DynamicTuple::default();
263 values.insert(1u32);
264 values.insert(2u32);
265 values.insert(3u32);
266
267 let dynamic_variant = DynamicVariant::Tuple(values);
268 let dynamic_enum = DynamicEnum::new("Xyz", dynamic_variant);
269
270 let mut my_enum = MyEnum::default();
271 my_enum.apply(&dynamic_enum);
272 assert_eq!(my_enum, MyEnum::Xyz(1, 2, 3));
273 }
274}
Sourcepub fn downcast_mut<T>(&mut self) -> Option<&mut T>where
T: Any,
pub fn downcast_mut<T>(&mut self) -> Option<&mut T>where
T: Any,
Downcasts the value to type T
by mutable reference.
If the underlying value is not of type T
, returns None
.
For remote types, T
should be the type itself rather than the wrapper type.