Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
bevyengine
GitHub Repository: bevyengine/bevy
Path: blob/main/crates/bevy_reflect/src/reflect.rs
6598 views
1
use crate::{
2
array_debug, enum_debug, list_debug, map_debug, set_debug, struct_debug, tuple_debug,
3
tuple_struct_debug, DynamicTypePath, DynamicTyped, OpaqueInfo, ReflectCloneError, ReflectKind,
4
ReflectKindMismatchError, ReflectMut, ReflectOwned, ReflectRef, TypeInfo, TypePath, Typed,
5
};
6
use alloc::borrow::Cow;
7
use alloc::boxed::Box;
8
use alloc::string::ToString;
9
use core::{
10
any::{Any, TypeId},
11
fmt::Debug,
12
};
13
14
use thiserror::Error;
15
16
use crate::utility::NonGenericTypeInfoCell;
17
18
/// A enumeration of all error outcomes that might happen when running [`try_apply`](PartialReflect::try_apply).
19
#[derive(Error, Debug)]
20
pub enum ApplyError {
21
#[error("attempted to apply `{from_kind}` to `{to_kind}`")]
22
/// Attempted to apply the wrong [kind](ReflectKind) to a type, e.g. a struct to an enum.
23
MismatchedKinds {
24
/// Kind of the value we attempted to apply.
25
from_kind: ReflectKind,
26
/// Kind of the type we attempted to apply the value to.
27
to_kind: ReflectKind,
28
},
29
30
#[error("enum variant `{variant_name}` doesn't have a field named `{field_name}`")]
31
/// Enum variant that we tried to apply to was missing a field.
32
MissingEnumField {
33
/// Name of the enum variant.
34
variant_name: Box<str>,
35
/// Name of the missing field.
36
field_name: Box<str>,
37
},
38
39
#[error("`{from_type}` is not `{to_type}`")]
40
/// Tried to apply incompatible types.
41
MismatchedTypes {
42
/// Type of the value we attempted to apply.
43
from_type: Box<str>,
44
/// Type we attempted to apply the value to.
45
to_type: Box<str>,
46
},
47
48
#[error("attempted to apply type with {from_size} size to a type with {to_size} size")]
49
/// Attempted to apply an [array-like] type to another of different size, e.g. a [u8; 4] to [u8; 3].
50
///
51
/// [array-like]: crate::Array
52
DifferentSize {
53
/// Size of the value we attempted to apply, in elements.
54
from_size: usize,
55
/// Size of the type we attempted to apply the value to, in elements.
56
to_size: usize,
57
},
58
59
#[error("variant with name `{variant_name}` does not exist on enum `{enum_name}`")]
60
/// The enum we tried to apply to didn't contain a variant with the give name.
61
UnknownVariant {
62
/// Name of the enum.
63
enum_name: Box<str>,
64
/// Name of the missing variant.
65
variant_name: Box<str>,
66
},
67
}
68
69
impl From<ReflectKindMismatchError> for ApplyError {
70
fn from(value: ReflectKindMismatchError) -> Self {
71
Self::MismatchedKinds {
72
from_kind: value.received,
73
to_kind: value.expected,
74
}
75
}
76
}
77
78
/// The foundational trait of [`bevy_reflect`], used for accessing and modifying data dynamically.
79
///
80
/// This is a supertrait of [`Reflect`],
81
/// meaning any type which implements `Reflect` implements `PartialReflect` by definition.
82
///
83
/// It's recommended to use [the derive macro for `Reflect`] rather than manually implementing this trait.
84
/// Doing so will automatically implement this trait as well as many other useful traits for reflection,
85
/// including one of the appropriate subtraits: [`Struct`], [`TupleStruct`] or [`Enum`].
86
///
87
/// See the [crate-level documentation] to see how this trait and its subtraits can be used.
88
///
89
/// [`bevy_reflect`]: crate
90
/// [the derive macro for `Reflect`]: bevy_reflect_derive::Reflect
91
/// [`Struct`]: crate::Struct
92
/// [`TupleStruct`]: crate::TupleStruct
93
/// [`Enum`]: crate::Enum
94
/// [crate-level documentation]: crate
95
#[diagnostic::on_unimplemented(
96
message = "`{Self}` does not implement `PartialReflect` so cannot be introspected",
97
note = "consider annotating `{Self}` with `#[derive(Reflect)]`"
98
)]
99
pub trait PartialReflect: DynamicTypePath + Send + Sync
100
where
101
// NB: we don't use `Self: Any` since for downcasting, `Reflect` should be used.
102
Self: 'static,
103
{
104
/// Returns the [`TypeInfo`] of the type _represented_ by this value.
105
///
106
/// For most types, this will simply return their own `TypeInfo`.
107
/// However, for dynamic types, such as [`DynamicStruct`] or [`DynamicList`],
108
/// this will return the type they represent
109
/// (or `None` if they don't represent any particular type).
110
///
111
/// This method is great if you have an instance of a type or a `dyn Reflect`,
112
/// and want to access its [`TypeInfo`]. However, if this method is to be called
113
/// frequently, consider using [`TypeRegistry::get_type_info`] as it can be more
114
/// performant for such use cases.
115
///
116
/// [`DynamicStruct`]: crate::DynamicStruct
117
/// [`DynamicList`]: crate::DynamicList
118
/// [`TypeRegistry::get_type_info`]: crate::TypeRegistry::get_type_info
119
fn get_represented_type_info(&self) -> Option<&'static TypeInfo>;
120
121
/// Casts this type to a boxed, reflected value.
122
///
123
/// This is useful for coercing trait objects.
124
fn into_partial_reflect(self: Box<Self>) -> Box<dyn PartialReflect>;
125
126
/// Casts this type to a reflected value.
127
///
128
/// This is useful for coercing trait objects.
129
fn as_partial_reflect(&self) -> &dyn PartialReflect;
130
131
/// Casts this type to a mutable, reflected value.
132
///
133
/// This is useful for coercing trait objects.
134
fn as_partial_reflect_mut(&mut self) -> &mut dyn PartialReflect;
135
136
/// Attempts to cast this type to a boxed, [fully-reflected] value.
137
///
138
/// [fully-reflected]: Reflect
139
fn try_into_reflect(self: Box<Self>) -> Result<Box<dyn Reflect>, Box<dyn PartialReflect>>;
140
141
/// Attempts to cast this type to a [fully-reflected] value.
142
///
143
/// [fully-reflected]: Reflect
144
fn try_as_reflect(&self) -> Option<&dyn Reflect>;
145
146
/// Attempts to cast this type to a mutable, [fully-reflected] value.
147
///
148
/// [fully-reflected]: Reflect
149
fn try_as_reflect_mut(&mut self) -> Option<&mut dyn Reflect>;
150
151
/// Applies a reflected value to this value.
152
///
153
/// If `Self` implements a [reflection subtrait], then the semantics of this
154
/// method are as follows:
155
/// - If `Self` is a [`Struct`], then the value of each named field of `value` is
156
/// applied to the corresponding named field of `self`. Fields which are
157
/// not present in both structs are ignored.
158
/// - If `Self` is a [`TupleStruct`] or [`Tuple`], then the value of each
159
/// numbered field is applied to the corresponding numbered field of
160
/// `self.` Fields which are not present in both values are ignored.
161
/// - If `Self` is an [`Enum`], then the variant of `self` is `updated` to match
162
/// the variant of `value`. The corresponding fields of that variant are
163
/// applied from `value` onto `self`. Fields which are not present in both
164
/// values are ignored.
165
/// - If `Self` is a [`List`] or [`Array`], then each element of `value` is applied
166
/// to the corresponding element of `self`. Up to `self.len()` items are applied,
167
/// and excess elements in `value` are appended to `self`.
168
/// - If `Self` is a [`Map`], then for each key in `value`, the associated
169
/// value is applied to the value associated with the same key in `self`.
170
/// Keys which are not present in `self` are inserted, and keys from `self` which are not present in `value` are removed.
171
/// - If `Self` is a [`Set`], then each element of `value` is applied to the corresponding
172
/// element of `Self`. If an element of `value` does not exist in `Self` then it is
173
/// cloned and inserted. If an element from `self` is not present in `value` then it is removed.
174
/// - If `Self` is none of these, then `value` is downcast to `Self`, cloned, and
175
/// assigned to `self`.
176
///
177
/// Note that `Reflect` must be implemented manually for [`List`]s,
178
/// [`Map`]s, and [`Set`]s in order to achieve the correct semantics, as derived
179
/// implementations will have the semantics for [`Struct`], [`TupleStruct`], [`Enum`]
180
/// or none of the above depending on the kind of type. For lists, maps, and sets, use the
181
/// [`list_apply`], [`map_apply`], and [`set_apply`] helper functions when implementing this method.
182
///
183
/// [reflection subtrait]: crate#the-reflection-subtraits
184
/// [`Struct`]: crate::Struct
185
/// [`TupleStruct`]: crate::TupleStruct
186
/// [`Tuple`]: crate::Tuple
187
/// [`Enum`]: crate::Enum
188
/// [`List`]: crate::List
189
/// [`Array`]: crate::Array
190
/// [`Map`]: crate::Map
191
/// [`Set`]: crate::Set
192
/// [`list_apply`]: crate::list_apply
193
/// [`map_apply`]: crate::map_apply
194
/// [`set_apply`]: crate::set_apply
195
///
196
/// # Panics
197
///
198
/// Derived implementations of this method will panic:
199
/// - If the type of `value` is not of the same kind as `Self` (e.g. if `Self` is
200
/// a `List`, while `value` is a `Struct`).
201
/// - If `Self` is any complex type and the corresponding fields or elements of
202
/// `self` and `value` are not of the same type.
203
/// - If `Self` is an opaque type and `value` cannot be downcast to `Self`
204
fn apply(&mut self, value: &dyn PartialReflect) {
205
PartialReflect::try_apply(self, value).unwrap();
206
}
207
208
/// Tries to [`apply`](PartialReflect::apply) a reflected value to this value.
209
///
210
/// Functions the same as the [`apply`](PartialReflect::apply) function but returns an error instead of
211
/// panicking.
212
///
213
/// # Handling Errors
214
///
215
/// This function may leave `self` in a partially mutated state if a error was encountered on the way.
216
/// consider maintaining a cloned instance of this data you can switch to if a error is encountered.
217
fn try_apply(&mut self, value: &dyn PartialReflect) -> Result<(), ApplyError>;
218
219
/// Returns a zero-sized enumeration of "kinds" of type.
220
///
221
/// See [`ReflectKind`].
222
fn reflect_kind(&self) -> ReflectKind {
223
self.reflect_ref().kind()
224
}
225
226
/// Returns an immutable enumeration of "kinds" of type.
227
///
228
/// See [`ReflectRef`].
229
fn reflect_ref(&self) -> ReflectRef<'_>;
230
231
/// Returns a mutable enumeration of "kinds" of type.
232
///
233
/// See [`ReflectMut`].
234
fn reflect_mut(&mut self) -> ReflectMut<'_>;
235
236
/// Returns an owned enumeration of "kinds" of type.
237
///
238
/// See [`ReflectOwned`].
239
fn reflect_owned(self: Box<Self>) -> ReflectOwned;
240
241
/// Converts this reflected value into its dynamic representation based on its [kind].
242
///
243
/// For example, a [`List`] type will internally invoke [`List::to_dynamic_list`], returning [`DynamicList`].
244
/// A [`Struct`] type will invoke [`Struct::to_dynamic_struct`], returning [`DynamicStruct`].
245
/// And so on.
246
///
247
/// If the [kind] is [opaque], then the value will attempt to be cloned directly via [`reflect_clone`],
248
/// since opaque types do not have any standard dynamic representation.
249
///
250
/// To attempt to clone the value directly such that it returns a concrete instance of this type,
251
/// use [`reflect_clone`].
252
///
253
/// # Panics
254
///
255
/// This method will panic if the [kind] is [opaque] and the call to [`reflect_clone`] fails.
256
///
257
/// # Example
258
///
259
/// ```
260
/// # use bevy_reflect::{PartialReflect};
261
/// let value = (1, true, 3.14);
262
/// let dynamic_value = value.to_dynamic();
263
/// assert!(dynamic_value.is_dynamic())
264
/// ```
265
///
266
/// [kind]: PartialReflect::reflect_kind
267
/// [`List`]: crate::List
268
/// [`List::to_dynamic_list`]: crate::List::to_dynamic_list
269
/// [`DynamicList`]: crate::DynamicList
270
/// [`Struct`]: crate::Struct
271
/// [`Struct::to_dynamic_struct`]: crate::Struct::to_dynamic_struct
272
/// [`DynamicStruct`]: crate::DynamicStruct
273
/// [opaque]: crate::ReflectKind::Opaque
274
/// [`reflect_clone`]: PartialReflect::reflect_clone
275
fn to_dynamic(&self) -> Box<dyn PartialReflect> {
276
match self.reflect_ref() {
277
ReflectRef::Struct(dyn_struct) => Box::new(dyn_struct.to_dynamic_struct()),
278
ReflectRef::TupleStruct(dyn_tuple_struct) => {
279
Box::new(dyn_tuple_struct.to_dynamic_tuple_struct())
280
}
281
ReflectRef::Tuple(dyn_tuple) => Box::new(dyn_tuple.to_dynamic_tuple()),
282
ReflectRef::List(dyn_list) => Box::new(dyn_list.to_dynamic_list()),
283
ReflectRef::Array(dyn_array) => Box::new(dyn_array.to_dynamic_array()),
284
ReflectRef::Map(dyn_map) => Box::new(dyn_map.to_dynamic_map()),
285
ReflectRef::Set(dyn_set) => Box::new(dyn_set.to_dynamic_set()),
286
ReflectRef::Enum(dyn_enum) => Box::new(dyn_enum.to_dynamic_enum()),
287
#[cfg(feature = "functions")]
288
ReflectRef::Function(dyn_function) => Box::new(dyn_function.to_dynamic_function()),
289
ReflectRef::Opaque(value) => value.reflect_clone().unwrap().into_partial_reflect(),
290
}
291
}
292
293
/// Attempts to clone `Self` using reflection.
294
///
295
/// Unlike [`to_dynamic`], which generally returns a dynamic representation of `Self`,
296
/// this method attempts create a clone of `Self` directly, if possible.
297
///
298
/// If the clone cannot be performed, an appropriate [`ReflectCloneError`] is returned.
299
///
300
/// # Example
301
///
302
/// ```
303
/// # use bevy_reflect::PartialReflect;
304
/// let value = (1, true, 3.14);
305
/// let cloned = value.reflect_clone().unwrap();
306
/// assert!(cloned.is::<(i32, bool, f64)>())
307
/// ```
308
///
309
/// [`to_dynamic`]: PartialReflect::to_dynamic
310
fn reflect_clone(&self) -> Result<Box<dyn Reflect>, ReflectCloneError> {
311
Err(ReflectCloneError::NotImplemented {
312
type_path: Cow::Owned(self.reflect_type_path().to_string()),
313
})
314
}
315
316
/// For a type implementing [`PartialReflect`], combines `reflect_clone` and
317
/// `take` in a useful fashion, automatically constructing an appropriate
318
/// [`ReflectCloneError`] if the downcast fails.
319
///
320
/// This is an associated function, rather than a method, because methods
321
/// with generic types prevent dyn-compatibility.
322
fn reflect_clone_and_take<T: 'static>(&self) -> Result<T, ReflectCloneError>
323
where
324
Self: TypePath + Sized,
325
{
326
self.reflect_clone()?
327
.take()
328
.map_err(|_| ReflectCloneError::FailedDowncast {
329
expected: Cow::Borrowed(<Self as TypePath>::type_path()),
330
received: Cow::Owned(self.reflect_type_path().to_string()),
331
})
332
}
333
334
/// Returns a hash of the value (which includes the type).
335
///
336
/// If the underlying type does not support hashing, returns `None`.
337
fn reflect_hash(&self) -> Option<u64> {
338
None
339
}
340
341
/// Returns a "partial equality" comparison result.
342
///
343
/// If the underlying type does not support equality testing, returns `None`.
344
fn reflect_partial_eq(&self, _value: &dyn PartialReflect) -> Option<bool> {
345
None
346
}
347
348
/// Debug formatter for the value.
349
///
350
/// Any value that is not an implementor of other `Reflect` subtraits
351
/// (e.g. [`List`], [`Map`]), will default to the format: `"Reflect(type_path)"`,
352
/// where `type_path` is the [type path] of the underlying type.
353
///
354
/// [`List`]: crate::List
355
/// [`Map`]: crate::Map
356
/// [type path]: TypePath::type_path
357
fn debug(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
358
match self.reflect_ref() {
359
ReflectRef::Struct(dyn_struct) => struct_debug(dyn_struct, f),
360
ReflectRef::TupleStruct(dyn_tuple_struct) => tuple_struct_debug(dyn_tuple_struct, f),
361
ReflectRef::Tuple(dyn_tuple) => tuple_debug(dyn_tuple, f),
362
ReflectRef::List(dyn_list) => list_debug(dyn_list, f),
363
ReflectRef::Array(dyn_array) => array_debug(dyn_array, f),
364
ReflectRef::Map(dyn_map) => map_debug(dyn_map, f),
365
ReflectRef::Set(dyn_set) => set_debug(dyn_set, f),
366
ReflectRef::Enum(dyn_enum) => enum_debug(dyn_enum, f),
367
#[cfg(feature = "functions")]
368
ReflectRef::Function(dyn_function) => dyn_function.fmt(f),
369
ReflectRef::Opaque(_) => write!(f, "Reflect({})", self.reflect_type_path()),
370
}
371
}
372
373
/// Indicates whether or not this type is a _dynamic_ type.
374
///
375
/// Dynamic types include the ones built-in to this [crate],
376
/// such as [`DynamicStruct`], [`DynamicList`], and [`DynamicTuple`].
377
/// However, they may be custom types used as proxies for other types
378
/// or to facilitate scripting capabilities.
379
///
380
/// By default, this method will return `false`.
381
///
382
/// [`DynamicStruct`]: crate::DynamicStruct
383
/// [`DynamicList`]: crate::DynamicList
384
/// [`DynamicTuple`]: crate::DynamicTuple
385
fn is_dynamic(&self) -> bool {
386
false
387
}
388
}
389
390
/// A core trait of [`bevy_reflect`], used for downcasting to concrete types.
391
///
392
/// This is a subtrait of [`PartialReflect`],
393
/// meaning any type which implements `Reflect` implements `PartialReflect` by definition.
394
///
395
/// It's recommended to use [the derive macro] rather than manually implementing this trait.
396
/// Doing so will automatically implement this trait, [`PartialReflect`], and many other useful traits for reflection,
397
/// including one of the appropriate subtraits: [`Struct`], [`TupleStruct`] or [`Enum`].
398
///
399
/// If you need to use this trait as a generic bound along with other reflection traits,
400
/// for your convenience, consider using [`Reflectable`] instead.
401
///
402
/// See the [crate-level documentation] to see how this trait can be used.
403
///
404
/// [`bevy_reflect`]: crate
405
/// [the derive macro]: bevy_reflect_derive::Reflect
406
/// [`Struct`]: crate::Struct
407
/// [`TupleStruct`]: crate::TupleStruct
408
/// [`Enum`]: crate::Enum
409
/// [`Reflectable`]: crate::Reflectable
410
/// [crate-level documentation]: crate
411
#[diagnostic::on_unimplemented(
412
message = "`{Self}` does not implement `Reflect` so cannot be fully reflected",
413
note = "consider annotating `{Self}` with `#[derive(Reflect)]`"
414
)]
415
pub trait Reflect: PartialReflect + DynamicTyped + Any {
416
/// Returns the value as a [`Box<dyn Any>`][core::any::Any].
417
///
418
/// For remote wrapper types, this will return the remote type instead.
419
fn into_any(self: Box<Self>) -> Box<dyn Any>;
420
421
/// Returns the value as a [`&dyn Any`][core::any::Any].
422
///
423
/// For remote wrapper types, this will return the remote type instead.
424
fn as_any(&self) -> &dyn Any;
425
426
/// Returns the value as a [`&mut dyn Any`][core::any::Any].
427
///
428
/// For remote wrapper types, this will return the remote type instead.
429
fn as_any_mut(&mut self) -> &mut dyn Any;
430
431
/// Casts this type to a boxed, fully-reflected value.
432
fn into_reflect(self: Box<Self>) -> Box<dyn Reflect>;
433
434
/// Casts this type to a fully-reflected value.
435
fn as_reflect(&self) -> &dyn Reflect;
436
437
/// Casts this type to a mutable, fully-reflected value.
438
fn as_reflect_mut(&mut self) -> &mut dyn Reflect;
439
440
/// Performs a type-checked assignment of a reflected value to this value.
441
///
442
/// If `value` does not contain a value of type `T`, returns an `Err`
443
/// containing the trait object.
444
fn set(&mut self, value: Box<dyn Reflect>) -> Result<(), Box<dyn Reflect>>;
445
}
446
447
impl dyn PartialReflect {
448
/// Returns `true` if the underlying value represents a value of type `T`, or `false`
449
/// otherwise.
450
///
451
/// Read `is` for more information on underlying values and represented types.
452
#[inline]
453
pub fn represents<T: Reflect + TypePath>(&self) -> bool {
454
self.get_represented_type_info()
455
.is_some_and(|t| t.type_path() == T::type_path())
456
}
457
458
/// Downcasts the value to type `T`, consuming the trait object.
459
///
460
/// If the underlying value does not implement [`Reflect`]
461
/// or is not of type `T`, returns `Err(self)`.
462
///
463
/// For remote types, `T` should be the type itself rather than the wrapper type.
464
pub fn try_downcast<T: Any>(
465
self: Box<dyn PartialReflect>,
466
) -> Result<Box<T>, Box<dyn PartialReflect>> {
467
self.try_into_reflect()?
468
.downcast()
469
.map_err(PartialReflect::into_partial_reflect)
470
}
471
472
/// Downcasts the value to type `T`, unboxing and consuming the trait object.
473
///
474
/// If the underlying value does not implement [`Reflect`]
475
/// or is not of type `T`, returns `Err(self)`.
476
///
477
/// For remote types, `T` should be the type itself rather than the wrapper type.
478
pub fn try_take<T: Any>(self: Box<dyn PartialReflect>) -> Result<T, Box<dyn PartialReflect>> {
479
self.try_downcast().map(|value| *value)
480
}
481
482
/// Downcasts the value to type `T` by reference.
483
///
484
/// If the underlying value does not implement [`Reflect`]
485
/// or is not of type `T`, returns [`None`].
486
///
487
/// For remote types, `T` should be the type itself rather than the wrapper type.
488
pub fn try_downcast_ref<T: Any>(&self) -> Option<&T> {
489
self.try_as_reflect()?.downcast_ref()
490
}
491
492
/// Downcasts the value to type `T` by mutable reference.
493
///
494
/// If the underlying value does not implement [`Reflect`]
495
/// or is not of type `T`, returns [`None`].
496
///
497
/// For remote types, `T` should be the type itself rather than the wrapper type.
498
pub fn try_downcast_mut<T: Any>(&mut self) -> Option<&mut T> {
499
self.try_as_reflect_mut()?.downcast_mut()
500
}
501
}
502
503
impl Debug for dyn PartialReflect {
504
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
505
self.debug(f)
506
}
507
}
508
509
// The following implementation never actually shadows the concrete TypePath implementation.
510
// See the comment on `dyn Reflect`'s `TypePath` implementation.
511
impl TypePath for dyn PartialReflect {
512
fn type_path() -> &'static str {
513
"dyn bevy_reflect::PartialReflect"
514
}
515
516
fn short_type_path() -> &'static str {
517
"dyn PartialReflect"
518
}
519
}
520
521
#[deny(rustdoc::broken_intra_doc_links)]
522
impl dyn Reflect {
523
/// Downcasts the value to type `T`, consuming the trait object.
524
///
525
/// If the underlying value is not of type `T`, returns `Err(self)`.
526
///
527
/// For remote types, `T` should be the type itself rather than the wrapper type.
528
pub fn downcast<T: Any>(self: Box<dyn Reflect>) -> Result<Box<T>, Box<dyn Reflect>> {
529
if self.is::<T>() {
530
Ok(self.into_any().downcast().unwrap())
531
} else {
532
Err(self)
533
}
534
}
535
536
/// Downcasts the value to type `T`, unboxing and consuming the trait object.
537
///
538
/// If the underlying value is not of type `T`, returns `Err(self)`.
539
///
540
/// For remote types, `T` should be the type itself rather than the wrapper type.
541
pub fn take<T: Any>(self: Box<dyn Reflect>) -> Result<T, Box<dyn Reflect>> {
542
self.downcast::<T>().map(|value| *value)
543
}
544
545
/// Returns `true` if the underlying value is of type `T`, or `false`
546
/// otherwise.
547
///
548
/// The underlying value is the concrete type that is stored in this `dyn` object;
549
/// it can be downcast to. In the case that this underlying value "represents"
550
/// a different type, like the Dynamic\*\*\* types do, you can call `represents`
551
/// to determine what type they represent. Represented types cannot be downcast
552
/// to, but you can use [`FromReflect`] to create a value of the represented type from them.
553
///
554
/// For remote types, `T` should be the type itself rather than the wrapper type.
555
///
556
/// [`FromReflect`]: crate::FromReflect
557
#[inline]
558
pub fn is<T: Any>(&self) -> bool {
559
self.as_any().type_id() == TypeId::of::<T>()
560
}
561
562
/// Downcasts the value to type `T` by reference.
563
///
564
/// If the underlying value is not of type `T`, returns `None`.
565
///
566
/// For remote types, `T` should be the type itself rather than the wrapper type.
567
#[inline]
568
pub fn downcast_ref<T: Any>(&self) -> Option<&T> {
569
self.as_any().downcast_ref::<T>()
570
}
571
572
/// Downcasts the value to type `T` by mutable reference.
573
///
574
/// If the underlying value is not of type `T`, returns `None`.
575
///
576
/// For remote types, `T` should be the type itself rather than the wrapper type.
577
#[inline]
578
pub fn downcast_mut<T: Any>(&mut self) -> Option<&mut T> {
579
self.as_any_mut().downcast_mut::<T>()
580
}
581
}
582
583
impl Debug for dyn Reflect {
584
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
585
self.debug(f)
586
}
587
}
588
589
impl Typed for dyn Reflect {
590
fn type_info() -> &'static TypeInfo {
591
static CELL: NonGenericTypeInfoCell = NonGenericTypeInfoCell::new();
592
CELL.get_or_set(|| TypeInfo::Opaque(OpaqueInfo::new::<Self>()))
593
}
594
}
595
596
// The following implementation never actually shadows the concrete `TypePath` implementation.
597
// See this playground (https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=589064053f27bc100d90da89c6a860aa).
598
impl TypePath for dyn Reflect {
599
fn type_path() -> &'static str {
600
"dyn bevy_reflect::Reflect"
601
}
602
603
fn short_type_path() -> &'static str {
604
"dyn Reflect"
605
}
606
}
607
608
macro_rules! impl_full_reflect {
609
($(<$($id:ident),* $(,)?>)? for $ty:ty $(where $($tt:tt)*)?) => {
610
impl $(<$($id),*>)? $crate::Reflect for $ty $(where $($tt)*)? {
611
fn into_any(self: bevy_platform::prelude::Box<Self>) -> bevy_platform::prelude::Box<dyn ::core::any::Any> {
612
self
613
}
614
615
fn as_any(&self) -> &dyn ::core::any::Any {
616
self
617
}
618
619
fn as_any_mut(&mut self) -> &mut dyn ::core::any::Any {
620
self
621
}
622
623
fn into_reflect(self: bevy_platform::prelude::Box<Self>) -> bevy_platform::prelude::Box<dyn $crate::Reflect> {
624
self
625
}
626
627
fn as_reflect(&self) -> &dyn $crate::Reflect {
628
self
629
}
630
631
fn as_reflect_mut(&mut self) -> &mut dyn $crate::Reflect {
632
self
633
}
634
635
fn set(
636
&mut self,
637
value: bevy_platform::prelude::Box<dyn $crate::Reflect>,
638
) -> Result<(), bevy_platform::prelude::Box<dyn $crate::Reflect>> {
639
*self = <dyn $crate::Reflect>::take(value)?;
640
Ok(())
641
}
642
}
643
};
644
}
645
646
pub(crate) use impl_full_reflect;
647
648