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