1use bevy::reflect::{
4 reflect_trait, serde::TypedReflectDeserializer, std_traits::ReflectDefault, DynamicArray,
5 DynamicEnum, DynamicList, DynamicMap, DynamicSet, DynamicStruct, DynamicTuple,
6 DynamicTupleStruct, DynamicVariant, FromReflect, PartialReflect, Reflect, ReflectFromReflect,
7 Set, TypeRegistry, Typed,
8};
9use serde::de::DeserializeSeed;
10use std::collections::{HashMap, HashSet};
11
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 let player: Player = Player { id: 123 };
34
35 let reflected: Box<dyn Reflect> = Box::new(player);
41
42 assert!(reflected.downcast_ref::<Player>().is_some());
44
45 let cloned: Box<dyn Reflect> = reflected.reflect_clone().unwrap();
49 assert_eq!(cloned.downcast_ref::<Player>(), Some(&Player { id: 123 }));
50
51 let dynamic: Box<dyn PartialReflect> = reflected.to_dynamic();
56 assert!(dynamic.is_dynamic());
57
58 assert!(dynamic.try_as_reflect().is_none());
61
62 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 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 assert!(deserialized.represents::<Player>());
82
83 let reflect_identifiable = registration
88 .data::<ReflectIdentifiable>()
89 .expect("`ReflectIdentifiable` should be registered");
90
91 assert!(deserialized
96 .try_as_reflect()
97 .and_then(|reflect_trait_obj| reflect_identifiable.get(reflect_trait_obj))
98 .is_none());
99
100 {
105 let mut value = Player::default();
108 value.apply(deserialized.as_ref());
109 assert_eq!(value.id, 123);
110
111 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 {
126 let value: Player = Player::from_reflect(deserialized.as_ref()).unwrap();
129 assert_eq!(value.id, 123);
130
131 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 let mut my_dynamic_list = DynamicList::from_iter([1u32, 2u32, 3u32]);
148
149 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 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 {
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 {
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 {
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 {
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 {
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 {
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 {
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 {
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}