1use crate as bevy_reflect;
2use crate::{std_traits::ReflectDefault, ReflectDeserialize, ReflectSerialize};
3use assert_type_match::assert_type_match;
4use bevy_reflect_derive::{impl_reflect, impl_reflect_opaque};
5use glam::*;
6
7macro_rules! reflect_enum {
9 ($(#[$meta:meta])* enum $ident:ident { $($ty:tt)* } ) => {
10 impl_reflect!($(#[$meta])* enum $ident { $($ty)* });
11
12 #[assert_type_match($ident, test_only)]
13 #[allow(clippy::upper_case_acronyms)]
14 enum $ident { $($ty)* }
15 };
16}
17
18impl_reflect!(
19 #[reflect(Debug, Hash, PartialEq, Default, Deserialize, Serialize)]
20 #[type_path = "glam"]
21 struct IVec2 {
22 x: i32,
23 y: i32,
24 }
25);
26impl_reflect!(
27 #[reflect(Debug, Hash, PartialEq, Default, Deserialize, Serialize)]
28 #[type_path = "glam"]
29 struct IVec3 {
30 x: i32,
31 y: i32,
32 z: i32,
33 }
34);
35impl_reflect!(
36 #[reflect(Debug, Hash, PartialEq, Default, Deserialize, Serialize)]
37 #[type_path = "glam"]
38 struct IVec4 {
39 x: i32,
40 y: i32,
41 z: i32,
42 w: i32,
43 }
44);
45
46impl_reflect!(
47 #[reflect(Debug, Hash, PartialEq, Default, Deserialize, Serialize)]
48 #[type_path = "glam"]
49 struct I64Vec2 {
50 x: i64,
51 y: i64,
52 }
53);
54
55impl_reflect!(
56 #[reflect(Debug, Hash, PartialEq, Default, Deserialize, Serialize)]
57 #[type_path = "glam"]
58 struct I64Vec3 {
59 x: i64,
60 y: i64,
61 z: i64,
62 }
63);
64
65impl_reflect!(
66 #[reflect(Debug, Hash, PartialEq, Default, Deserialize, Serialize)]
67 #[type_path = "glam"]
68 struct I64Vec4 {
69 x: i64,
70 y: i64,
71 z: i64,
72 w: i64,
73 }
74);
75
76impl_reflect!(
77 #[reflect(Debug, Hash, PartialEq, Default, Deserialize, Serialize)]
78 #[type_path = "glam"]
79 struct UVec2 {
80 x: u32,
81 y: u32,
82 }
83);
84impl_reflect!(
85 #[reflect(Debug, Hash, PartialEq, Default, Deserialize, Serialize)]
86 #[type_path = "glam"]
87 struct UVec3 {
88 x: u32,
89 y: u32,
90 z: u32,
91 }
92);
93impl_reflect!(
94 #[reflect(Debug, Hash, PartialEq, Default, Deserialize, Serialize)]
95 #[type_path = "glam"]
96 struct UVec4 {
97 x: u32,
98 y: u32,
99 z: u32,
100 w: u32,
101 }
102);
103
104impl_reflect!(
105 #[reflect(Debug, Hash, PartialEq, Default, Deserialize, Serialize)]
106 #[type_path = "glam"]
107 struct U64Vec2 {
108 x: u64,
109 y: u64,
110 }
111);
112impl_reflect!(
113 #[reflect(Debug, Hash, PartialEq, Default, Deserialize, Serialize)]
114 #[type_path = "glam"]
115 struct U64Vec3 {
116 x: u64,
117 y: u64,
118 z: u64,
119 }
120);
121impl_reflect!(
122 #[reflect(Debug, Hash, PartialEq, Default, Deserialize, Serialize)]
123 #[type_path = "glam"]
124 struct U64Vec4 {
125 x: u64,
126 y: u64,
127 z: u64,
128 w: u64,
129 }
130);
131
132impl_reflect!(
133 #[reflect(Debug, PartialEq, Default, Deserialize, Serialize)]
134 #[type_path = "glam"]
135 struct Vec2 {
136 x: f32,
137 y: f32,
138 }
139);
140impl_reflect!(
141 #[reflect(Debug, PartialEq, Default, Deserialize, Serialize)]
142 #[type_path = "glam"]
143 struct Vec3 {
144 x: f32,
145 y: f32,
146 z: f32,
147 }
148);
149impl_reflect!(
150 #[reflect(Debug, PartialEq, Default, Deserialize, Serialize)]
151 #[type_path = "glam"]
152 struct Vec3A {
153 x: f32,
154 y: f32,
155 z: f32,
156 }
157);
158impl_reflect!(
159 #[reflect(Debug, PartialEq, Default, Deserialize, Serialize)]
160 #[type_path = "glam"]
161 struct Vec4 {
162 x: f32,
163 y: f32,
164 z: f32,
165 w: f32,
166 }
167);
168
169impl_reflect!(
170 #[reflect(Debug, PartialEq, Default, Deserialize, Serialize)]
171 #[type_path = "glam"]
172 struct BVec2 {
173 x: bool,
174 y: bool,
175 }
176);
177impl_reflect!(
178 #[reflect(Debug, PartialEq, Default, Deserialize, Serialize)]
179 #[type_path = "glam"]
180 struct BVec3 {
181 x: bool,
182 y: bool,
183 z: bool,
184 }
185);
186impl_reflect!(
187 #[reflect(Debug, PartialEq, Default, Deserialize, Serialize)]
188 #[type_path = "glam"]
189 struct BVec4 {
190 x: bool,
191 y: bool,
192 z: bool,
193 w: bool,
194 }
195);
196
197impl_reflect!(
198 #[reflect(Debug, PartialEq, Default, Deserialize, Serialize)]
199 #[type_path = "glam"]
200 struct DVec2 {
201 x: f64,
202 y: f64,
203 }
204);
205impl_reflect!(
206 #[reflect(Debug, PartialEq, Default, Deserialize, Serialize)]
207 #[type_path = "glam"]
208 struct DVec3 {
209 x: f64,
210 y: f64,
211 z: f64,
212 }
213);
214impl_reflect!(
215 #[reflect(Debug, PartialEq, Default, Deserialize, Serialize)]
216 #[type_path = "glam"]
217 struct DVec4 {
218 x: f64,
219 y: f64,
220 z: f64,
221 w: f64,
222 }
223);
224
225impl_reflect!(
226 #[reflect(Debug, PartialEq, Default, Deserialize, Serialize)]
227 #[type_path = "glam"]
228 struct Mat2 {
229 x_axis: Vec2,
230 y_axis: Vec2,
231 }
232);
233impl_reflect!(
234 #[reflect(Debug, PartialEq, Default, Deserialize, Serialize)]
235 #[type_path = "glam"]
236 struct Mat3 {
237 x_axis: Vec3,
238 y_axis: Vec3,
239 z_axis: Vec3,
240 }
241);
242impl_reflect!(
243 #[reflect(Debug, PartialEq, Default, Deserialize, Serialize)]
244 #[type_path = "glam"]
245 struct Mat3A {
246 x_axis: Vec3A,
247 y_axis: Vec3A,
248 z_axis: Vec3A,
249 }
250);
251impl_reflect!(
252 #[reflect(Debug, PartialEq, Default, Deserialize, Serialize)]
253 #[type_path = "glam"]
254 struct Mat4 {
255 x_axis: Vec4,
256 y_axis: Vec4,
257 z_axis: Vec4,
258 w_axis: Vec4,
259 }
260);
261
262impl_reflect!(
263 #[reflect(Debug, PartialEq, Default, Deserialize, Serialize)]
264 #[type_path = "glam"]
265 struct DMat2 {
266 x_axis: DVec2,
267 y_axis: DVec2,
268 }
269);
270impl_reflect!(
271 #[reflect(Debug, PartialEq, Default, Deserialize, Serialize)]
272 #[type_path = "glam"]
273 struct DMat3 {
274 x_axis: DVec3,
275 y_axis: DVec3,
276 z_axis: DVec3,
277 }
278);
279impl_reflect!(
280 #[reflect(Debug, PartialEq, Default, Deserialize, Serialize)]
281 #[type_path = "glam"]
282 struct DMat4 {
283 x_axis: DVec4,
284 y_axis: DVec4,
285 z_axis: DVec4,
286 w_axis: DVec4,
287 }
288);
289
290impl_reflect!(
291 #[reflect(Debug, PartialEq, Default, Deserialize, Serialize)]
292 #[type_path = "glam"]
293 struct Affine2 {
294 matrix2: Mat2,
295 translation: Vec2,
296 }
297);
298impl_reflect!(
299 #[reflect(Debug, PartialEq, Default, Deserialize, Serialize)]
300 #[type_path = "glam"]
301 struct Affine3A {
302 matrix3: Mat3A,
303 translation: Vec3A,
304 }
305);
306
307impl_reflect!(
308 #[reflect(Debug, PartialEq, Default, Deserialize, Serialize)]
309 #[type_path = "glam"]
310 struct DAffine2 {
311 matrix2: DMat2,
312 translation: DVec2,
313 }
314);
315impl_reflect!(
316 #[reflect(Debug, PartialEq, Default, Deserialize, Serialize)]
317 #[type_path = "glam"]
318 struct DAffine3 {
319 matrix3: DMat3,
320 translation: DVec3,
321 }
322);
323
324impl_reflect!(
325 #[reflect(Debug, PartialEq, Default, Deserialize, Serialize)]
326 #[type_path = "glam"]
327 struct Quat {
328 x: f32,
329 y: f32,
330 z: f32,
331 w: f32,
332 }
333);
334impl_reflect!(
335 #[reflect(Debug, PartialEq, Default, Deserialize, Serialize)]
336 #[type_path = "glam"]
337 struct DQuat {
338 x: f64,
339 y: f64,
340 z: f64,
341 w: f64,
342 }
343);
344
345reflect_enum!(
346 #[reflect(Debug, PartialEq, Default, Deserialize, Serialize)]
347 #[type_path = "glam"]
348 enum EulerRot {
349 ZYX,
350 ZXY,
351 YXZ,
352 YZX,
353 XYZ,
354 XZY,
355 ZYZ,
356 ZXZ,
357 YXY,
358 YZY,
359 XYX,
360 XZX,
361 ZYXEx,
362 ZXYEx,
363 YXZEx,
364 YZXEx,
365 XYZEx,
366 XZYEx,
367 ZYZEx,
368 ZXZEx,
369 YXYEx,
370 YZYEx,
371 XYXEx,
372 XZXEx,
373 }
374);
375
376impl_reflect_opaque!(::glam::BVec3A(Debug, Default, Deserialize, Serialize));
377impl_reflect_opaque!(::glam::BVec4A(Debug, Default, Deserialize, Serialize));
378
379#[cfg(test)]
380mod tests {
381 use ron::{
382 ser::{to_string_pretty, PrettyConfig},
383 Deserializer,
384 };
385 use serde::de::DeserializeSeed;
386 use static_assertions::assert_impl_all;
387
388 use crate::{
389 prelude::*,
390 serde::{ReflectDeserializer, ReflectSerializer},
391 Enum, GetTypeRegistration, TypeRegistry,
392 };
393
394 use super::*;
395
396 assert_impl_all!(EulerRot: Enum);
397
398 #[test]
399 fn euler_rot_serialization() {
400 let v = EulerRot::YXZ;
401
402 let mut registry = TypeRegistry::default();
403 registry.register::<EulerRot>();
404
405 let ser = ReflectSerializer::new(&v, ®istry);
406
407 let config = PrettyConfig::default()
408 .new_line(String::from("\n"))
409 .indentor(String::from(" "));
410 let output = to_string_pretty(&ser, config).unwrap();
411 let expected = r#"
412{
413 "glam::EulerRot": YXZ,
414}"#;
415
416 assert_eq!(expected, format!("\n{output}"));
417 }
418
419 #[test]
420 fn euler_rot_deserialization() {
421 let data = r#"
422{
423 "glam::EulerRot": XZY,
424}"#;
425
426 let mut registry = TypeRegistry::default();
427 registry.add_registration(EulerRot::get_type_registration());
428
429 let de = ReflectDeserializer::new(®istry);
430
431 let mut deserializer =
432 Deserializer::from_str(data).expect("Failed to acquire deserializer");
433
434 let dynamic_struct = de
435 .deserialize(&mut deserializer)
436 .expect("Failed to deserialize");
437
438 let mut result = EulerRot::default();
439
440 result.apply(dynamic_struct.as_partial_reflect());
441
442 assert_eq!(result, EulerRot::XZY);
443 }
444}