pub trait Reflect: DynamicTypePath + Any + Send + Sync {
Show 19 methods
// Required methods
fn get_represented_type_info(&self) -> Option<&'static TypeInfo>;
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 apply(&mut self, value: &(dyn Reflect + 'static));
fn set(&mut self, value: Box<dyn Reflect>) -> Result<(), Box<dyn Reflect>>;
fn reflect_ref(&self) -> ReflectRef<'_>;
fn reflect_mut(&mut self) -> ReflectMut<'_>;
fn reflect_owned(self: Box<Self>) -> ReflectOwned;
fn clone_value(&self) -> Box<dyn Reflect>;
// Provided methods
fn reflect_kind(&self) -> ReflectKind { ... }
fn reflect_hash(&self) -> Option<u64> { ... }
fn reflect_partial_eq(
&self,
_value: &(dyn Reflect + 'static)
) -> Option<bool> { ... }
fn debug(&self, f: &mut Formatter<'_>) -> Result<(), Error> { ... }
fn serializable(&self) -> Option<Serializable<'_>> { ... }
fn is_dynamic(&self) -> bool { ... }
}
Expand description
The core trait of bevy_reflect
, used for accessing and modifying data dynamically.
It’s recommended to use the derive macro rather than manually implementing this trait.
Doing so will automatically implement many other useful traits for reflection,
including one of the appropriate subtraits: Struct
, TupleStruct
or Enum
.
See the crate-level documentation to see how this trait and its subtraits can be used.
Required Methods§
fn get_represented_type_info(&self) -> Option<&'static TypeInfo>
fn get_represented_type_info(&self) -> Option<&'static TypeInfo>
Returns the TypeInfo
of the type represented by this value.
For most types, this will simply return their own TypeInfo
.
However, for dynamic types, such as DynamicStruct
or DynamicList
,
this will return the type they represent
(or None
if they don’t represent any particular type).
This method is great if you have an instance of a type or a dyn Reflect
,
and want to access its TypeInfo
. However, if this method is to be called
frequently, consider using TypeRegistry::get_type_info
as it can be more
performant for such use cases.
fn 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>
.
fn 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
.
fn into_reflect(self: Box<Self>) -> Box<dyn Reflect>
fn into_reflect(self: Box<Self>) -> Box<dyn Reflect>
Casts this type to a boxed reflected value.
fn as_reflect(&self) -> &(dyn Reflect + 'static)
fn as_reflect(&self) -> &(dyn Reflect + 'static)
Casts this type to a reflected value.
fn 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 reflected value.
fn apply(&mut self, value: &(dyn Reflect + 'static))
fn apply(&mut self, value: &(dyn Reflect + 'static))
Applies a reflected value to this value.
If a type implements a subtrait of Reflect
, then the semantics of this
method are as follows:
- If
T
is aStruct
, then the value of each named field ofvalue
is applied to the corresponding named field ofself
. Fields which are not present in both structs are ignored. - If
T
is aTupleStruct
orTuple
, then the value of each numbered field is applied to the corresponding numbered field ofself.
Fields which are not present in both values are ignored. - If
T
is anEnum
, then the variant ofself
isupdated
to match the variant ofvalue
. The corresponding fields of that variant are applied fromvalue
ontoself
. Fields which are not present in both values are ignored. - If
T
is aList
orArray
, then each element ofvalue
is applied to the corresponding element ofself
. Up toself.len()
items are applied, and excess elements invalue
are appended toself
. - If
T
is aMap
, then for each key invalue
, the associated value is applied to the value associated with the same key inself
. Keys which are not present inself
are inserted. - If
T
is none of these, thenvalue
is downcast toT
, cloned, and assigned toself
.
Note that Reflect
must be implemented manually for List
s and
Map
s in order to achieve the correct semantics, as derived
implementations will have the semantics for Struct
, TupleStruct
, Enum
or none of the above depending on the kind of type. For lists and maps, use the
list_apply
and map_apply
helper functions when implementing this method.
§Panics
Derived implementations of this method will panic:
- If the type of
value
is not of the same kind asT
(e.g. ifT
is aList
, whilevalue
is aStruct
). - If
T
is any complex type and the corresponding fields or elements ofself
andvalue
are not of the same type. - If
T
is a value type andself
cannot be downcast toT
fn set(&mut self, value: Box<dyn Reflect>) -> Result<(), Box<dyn Reflect>>
fn set(&mut self, value: Box<dyn Reflect>) -> Result<(), Box<dyn Reflect>>
Performs a type-checked assignment of a reflected value to this value.
If value
does not contain a value of type T
, returns an Err
containing the trait object.
fn reflect_ref(&self) -> ReflectRef<'_>
fn reflect_ref(&self) -> ReflectRef<'_>
Returns an immutable enumeration of “kinds” of type.
See ReflectRef
.
fn reflect_mut(&mut self) -> ReflectMut<'_>
fn reflect_mut(&mut self) -> ReflectMut<'_>
Returns a mutable enumeration of “kinds” of type.
See ReflectMut
.
fn reflect_owned(self: Box<Self>) -> ReflectOwned
fn reflect_owned(self: Box<Self>) -> ReflectOwned
Returns an owned enumeration of “kinds” of type.
See ReflectOwned
.
fn clone_value(&self) -> Box<dyn Reflect>
fn clone_value(&self) -> Box<dyn Reflect>
Clones the value as a Reflect
trait object.
When deriving Reflect
for a struct, tuple struct or enum, the value is
cloned via Struct::clone_dynamic
, TupleStruct::clone_dynamic
,
or Enum::clone_dynamic
, respectively.
Implementors of other Reflect
subtraits (e.g. List
, Map
) should
use those subtraits’ respective clone_dynamic
methods.
Provided Methods§
fn reflect_kind(&self) -> ReflectKind
fn reflect_kind(&self) -> ReflectKind
Returns a zero-sized enumeration of “kinds” of type.
See ReflectKind
.
fn reflect_hash(&self) -> Option<u64>
fn reflect_hash(&self) -> Option<u64>
Returns a hash of the value (which includes the type).
If the underlying type does not support hashing, returns None
.
fn reflect_partial_eq(&self, _value: &(dyn Reflect + 'static)) -> Option<bool>
fn reflect_partial_eq(&self, _value: &(dyn Reflect + 'static)) -> Option<bool>
Returns a “partial equality” comparison result.
If the underlying type does not support equality testing, returns None
.
Examples found in repository?
56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110
fn setup(type_registry: Res<AppTypeRegistry>) {
let mut value = Foo {
a: 1,
_ignored: NonReflectedValue { _a: 10 },
nested: Bar { b: 8 },
};
// You can set field values like this. The type must match exactly or this will fail.
*value.get_field_mut("a").unwrap() = 2usize;
assert_eq!(value.a, 2);
assert_eq!(*value.get_field::<usize>("a").unwrap(), 2);
// You can also get the &dyn Reflect value of a field like this
let field = value.field("a").unwrap();
// you can downcast Reflect values like this:
assert_eq!(*field.downcast_ref::<usize>().unwrap(), 2);
// DynamicStruct also implements the `Struct` and `Reflect` traits.
let mut patch = DynamicStruct::default();
patch.insert("a", 4usize);
// You can "apply" Reflect implementations on top of other Reflect implementations.
// This will only set fields with the same name, and it will fail if the types don't match.
// You can use this to "patch" your types with new values.
value.apply(&patch);
assert_eq!(value.a, 4);
let type_registry = type_registry.read();
// By default, all derived `Reflect` types can be Serialized using serde. No need to derive
// Serialize!
let serializer = ReflectSerializer::new(&value, &type_registry);
let ron_string =
ron::ser::to_string_pretty(&serializer, ron::ser::PrettyConfig::default()).unwrap();
info!("{}\n", ron_string);
// Dynamic properties can be deserialized
let reflect_deserializer = UntypedReflectDeserializer::new(&type_registry);
let mut deserializer = ron::de::Deserializer::from_str(&ron_string).unwrap();
let reflect_value = reflect_deserializer.deserialize(&mut deserializer).unwrap();
// Deserializing returns a Box<dyn Reflect> value. Generally, deserializing a value will return
// the "dynamic" variant of a type. For example, deserializing a struct will return the
// DynamicStruct type. "Value types" will be deserialized as themselves.
let _deserialized_struct = reflect_value.downcast_ref::<DynamicStruct>();
// Reflect has its own `partial_eq` implementation, named `reflect_partial_eq`. This behaves
// like normal `partial_eq`, but it treats "dynamic" and "non-dynamic" types the same. The
// `Foo` struct and deserialized `DynamicStruct` are considered equal for this reason:
assert!(reflect_value.reflect_partial_eq(&value).unwrap());
// By "patching" `Foo` with the deserialized DynamicStruct, we can "Deserialize" Foo.
// This means we can serialize and deserialize with a single `Reflect` derive!
value.apply(&*reflect_value);
}
fn serializable(&self) -> Option<Serializable<'_>>
fn serializable(&self) -> Option<Serializable<'_>>
Returns a serializable version of the value.
If the underlying type does not support serialization, returns None
.
fn is_dynamic(&self) -> bool
fn is_dynamic(&self) -> bool
Indicates whether or not this type is a dynamic type.
Dynamic types include the ones built-in to this [crate],
such as DynamicStruct
, DynamicList
, and DynamicTuple
.
However, they may be custom types used as proxies for other types
or to facilitate scripting capabilities.
By default, this method will return false
.
Implementations§
§impl dyn Reflect
impl dyn Reflect
pub fn downcast<T>(self: Box<dyn Reflect>) -> Result<Box<T>, Box<dyn Reflect>>where
T: Reflect,
pub fn downcast<T>(self: Box<dyn Reflect>) -> Result<Box<T>, Box<dyn Reflect>>where
T: Reflect,
Downcasts the value to type T
, consuming the trait object.
If the underlying value is not of type T
, returns Err(self)
.
pub fn take<T>(self: Box<dyn Reflect>) -> Result<T, Box<dyn Reflect>>where
T: Reflect,
pub fn take<T>(self: Box<dyn Reflect>) -> Result<T, Box<dyn Reflect>>where
T: Reflect,
Downcasts the value to type T
, unboxing and consuming the trait object.
If the underlying value is not of type T
, returns Err(self)
.
Examples found in repository?
65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122
fn setup() {
let mut z = HashMap::default();
z.insert("Hello".to_string(), 1.0);
let value: Box<dyn Reflect> = Box::new(A {
x: 1,
y: vec![1, 2],
z,
});
// There are a number of different "reflect traits", which each expose different operations on
// the underlying type
match value.reflect_ref() {
// `Struct` is a trait automatically implemented for structs that derive Reflect. This trait
// allows you to interact with fields via their string names or indices
ReflectRef::Struct(value) => {
info!(
"This is a 'struct' type with an 'x' value of {}",
value.get_field::<usize>("x").unwrap()
);
}
// `TupleStruct` is a trait automatically implemented for tuple structs that derive Reflect.
// This trait allows you to interact with fields via their indices
ReflectRef::TupleStruct(_) => {}
// `Tuple` is a special trait that can be manually implemented (instead of deriving
// Reflect). This exposes "tuple" operations on your type, allowing you to interact
// with fields via their indices. Tuple is automatically implemented for tuples of
// arity 12 or less.
ReflectRef::Tuple(_) => {}
// `Enum` is a trait automatically implemented for enums that derive Reflect. This trait allows you
// to interact with the current variant and its fields (if it has any)
ReflectRef::Enum(_) => {}
// `List` is a special trait that can be manually implemented (instead of deriving Reflect).
// This exposes "list" operations on your type, such as insertion. `List` is automatically
// implemented for relevant core types like Vec<T>.
ReflectRef::List(_) => {}
// `Array` is a special trait that can be manually implemented (instead of deriving Reflect).
// This exposes "array" operations on your type, such as indexing. `Array`
// is automatically implemented for relevant core types like [T; N].
ReflectRef::Array(_) => {}
// `Map` is a special trait that can be manually implemented (instead of deriving Reflect).
// This exposes "map" operations on your type, such as getting / inserting by key.
// Map is automatically implemented for relevant core types like HashMap<K, V>
ReflectRef::Map(_) => {}
// `Value` types do not implement any of the other traits above. They are simply a Reflect
// implementation. Value is implemented for core types like i32, usize, f32, and
// String.
ReflectRef::Value(_) => {}
}
let mut dynamic_list = DynamicList::default();
dynamic_list.push(3u32);
dynamic_list.push(4u32);
dynamic_list.push(5u32);
let mut value: A = value.take::<A>().unwrap();
value.y.apply(&dynamic_list);
assert_eq!(value.y, vec![3u32, 4u32, 5u32]);
}
pub fn represents<T>(&self) -> bool
pub fn represents<T>(&self) -> bool
Returns true
if the underlying value represents a value of type T
, or false
otherwise.
Read is
for more information on underlying values and represented types.
pub fn is<T>(&self) -> boolwhere
T: Reflect,
pub fn is<T>(&self) -> boolwhere
T: Reflect,
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.
pub fn downcast_ref<T>(&self) -> Option<&T>where
T: Reflect,
pub fn downcast_ref<T>(&self) -> Option<&T>where
T: Reflect,
Downcasts the value to type T
by reference.
If the underlying value is not of type T
, returns None
.
Examples found in repository?
56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110
fn setup(type_registry: Res<AppTypeRegistry>) {
let mut value = Foo {
a: 1,
_ignored: NonReflectedValue { _a: 10 },
nested: Bar { b: 8 },
};
// You can set field values like this. The type must match exactly or this will fail.
*value.get_field_mut("a").unwrap() = 2usize;
assert_eq!(value.a, 2);
assert_eq!(*value.get_field::<usize>("a").unwrap(), 2);
// You can also get the &dyn Reflect value of a field like this
let field = value.field("a").unwrap();
// you can downcast Reflect values like this:
assert_eq!(*field.downcast_ref::<usize>().unwrap(), 2);
// DynamicStruct also implements the `Struct` and `Reflect` traits.
let mut patch = DynamicStruct::default();
patch.insert("a", 4usize);
// You can "apply" Reflect implementations on top of other Reflect implementations.
// This will only set fields with the same name, and it will fail if the types don't match.
// You can use this to "patch" your types with new values.
value.apply(&patch);
assert_eq!(value.a, 4);
let type_registry = type_registry.read();
// By default, all derived `Reflect` types can be Serialized using serde. No need to derive
// Serialize!
let serializer = ReflectSerializer::new(&value, &type_registry);
let ron_string =
ron::ser::to_string_pretty(&serializer, ron::ser::PrettyConfig::default()).unwrap();
info!("{}\n", ron_string);
// Dynamic properties can be deserialized
let reflect_deserializer = UntypedReflectDeserializer::new(&type_registry);
let mut deserializer = ron::de::Deserializer::from_str(&ron_string).unwrap();
let reflect_value = reflect_deserializer.deserialize(&mut deserializer).unwrap();
// Deserializing returns a Box<dyn Reflect> value. Generally, deserializing a value will return
// the "dynamic" variant of a type. For example, deserializing a struct will return the
// DynamicStruct type. "Value types" will be deserialized as themselves.
let _deserialized_struct = reflect_value.downcast_ref::<DynamicStruct>();
// Reflect has its own `partial_eq` implementation, named `reflect_partial_eq`. This behaves
// like normal `partial_eq`, but it treats "dynamic" and "non-dynamic" types the same. The
// `Foo` struct and deserialized `DynamicStruct` are considered equal for this reason:
assert!(reflect_value.reflect_partial_eq(&value).unwrap());
// By "patching" `Foo` with the deserialized DynamicStruct, we can "Deserialize" Foo.
// This means we can serialize and deserialize with a single `Reflect` derive!
value.apply(&*reflect_value);
}
pub fn downcast_mut<T>(&mut self) -> Option<&mut T>where
T: Reflect,
pub fn downcast_mut<T>(&mut self) -> Option<&mut T>where
T: Reflect,
Downcasts the value to type T
by mutable reference.
If the underlying value is not of type T
, returns None
.