Skip to main content

leafwing_input_manager/user_input/
trait_reflection.rs

1//! Implementations of the various [`bevy::reflect`] traits required to make our types reflectable.
2//!
3//! Note that [bevy #3392](https://github.com/bevyengine/bevy/issues/3392) would eliminate the need for this.
4
5use std::any::Any;
6
7use bevy::reflect::{
8    CreateTypeData, FromReflect, GetTypeRegistration, OpaqueInfo, Reflect, ReflectDeserialize,
9    ReflectFromPtr, ReflectKind, ReflectMut, ReflectOwned, ReflectRef, ReflectSerialize, TypeInfo,
10    TypePath, TypeRegistration, Typed,
11    utility::{GenericTypePathCell, NonGenericTypeInfoCell},
12};
13
14use dyn_eq::DynEq;
15
16mod buttonlike {
17    use bevy::reflect::PartialReflect;
18
19    use super::*;
20
21    use crate::user_input::Buttonlike;
22
23    dyn_clone::clone_trait_object!(Buttonlike);
24    dyn_eq::eq_trait_object!(Buttonlike);
25    dyn_hash::hash_trait_object!(Buttonlike);
26
27    impl PartialReflect for Box<dyn Buttonlike> {
28        fn get_represented_type_info(&self) -> Option<&'static TypeInfo> {
29            Some(Self::type_info())
30        }
31
32        fn reflect_kind(&self) -> ReflectKind {
33            ReflectKind::Opaque
34        }
35
36        fn reflect_ref(&self) -> ReflectRef<'_> {
37            ReflectRef::Opaque(self)
38        }
39
40        fn reflect_mut(&mut self) -> ReflectMut<'_> {
41            ReflectMut::Opaque(self)
42        }
43
44        fn reflect_owned(self: Box<Self>) -> ReflectOwned {
45            ReflectOwned::Opaque(self)
46        }
47
48        fn try_apply(
49            &mut self,
50            value: &dyn PartialReflect,
51        ) -> Result<(), bevy::reflect::ApplyError> {
52            if let Some(value) = value.try_downcast_ref::<Self>() {
53                *self = value.clone();
54                Ok(())
55            } else {
56                Err(bevy::reflect::ApplyError::MismatchedTypes {
57                    from_type: self
58                        .reflect_type_ident()
59                        .unwrap_or_default()
60                        .to_string()
61                        .into_boxed_str(),
62                    to_type: self
63                        .reflect_type_ident()
64                        .unwrap_or_default()
65                        .to_string()
66                        .into_boxed_str(),
67                })
68            }
69        }
70
71        fn into_partial_reflect(self: Box<Self>) -> Box<dyn PartialReflect> {
72            self
73        }
74
75        fn as_partial_reflect(&self) -> &dyn PartialReflect {
76            self
77        }
78
79        fn as_partial_reflect_mut(&mut self) -> &mut dyn PartialReflect {
80            self
81        }
82
83        fn try_into_reflect(self: Box<Self>) -> Result<Box<dyn Reflect>, Box<dyn PartialReflect>> {
84            Ok(self)
85        }
86
87        fn try_as_reflect(&self) -> Option<&dyn Reflect> {
88            Some(self)
89        }
90
91        fn try_as_reflect_mut(&mut self) -> Option<&mut dyn Reflect> {
92            Some(self)
93        }
94    }
95
96    impl Reflect for Box<dyn Buttonlike> {
97        fn into_any(self: Box<Self>) -> Box<dyn Any> {
98            self
99        }
100
101        fn as_any(&self) -> &dyn Any {
102            self
103        }
104
105        fn as_any_mut(&mut self) -> &mut dyn Any {
106            self
107        }
108
109        fn into_reflect(self: Box<Self>) -> Box<dyn Reflect> {
110            self
111        }
112
113        fn as_reflect(&self) -> &dyn Reflect {
114            self
115        }
116
117        fn as_reflect_mut(&mut self) -> &mut dyn Reflect {
118            self
119        }
120
121        fn set(&mut self, value: Box<dyn Reflect>) -> Result<(), Box<dyn Reflect>> {
122            *self = value.take()?;
123            Ok(())
124        }
125    }
126
127    impl Typed for Box<dyn Buttonlike> {
128        fn type_info() -> &'static TypeInfo {
129            static CELL: NonGenericTypeInfoCell = NonGenericTypeInfoCell::new();
130            CELL.get_or_set(|| TypeInfo::Opaque(OpaqueInfo::new::<Self>()))
131        }
132    }
133
134    impl TypePath for Box<dyn Buttonlike> {
135        fn type_path() -> &'static str {
136            static CELL: GenericTypePathCell = GenericTypePathCell::new();
137            CELL.get_or_insert::<Self, _>(|| {
138                format!("std::boxed::Box<dyn {}::Buttonlike>", module_path!())
139            })
140        }
141
142        fn short_type_path() -> &'static str {
143            static CELL: GenericTypePathCell = GenericTypePathCell::new();
144            CELL.get_or_insert::<Self, _>(|| "Box<dyn Buttonlike>".to_string())
145        }
146
147        fn type_ident() -> Option<&'static str> {
148            Some("Box<dyn Buttonlike>")
149        }
150
151        fn crate_name() -> Option<&'static str> {
152            module_path!().split(':').next()
153        }
154
155        fn module_path() -> Option<&'static str> {
156            Some(module_path!())
157        }
158    }
159
160    impl GetTypeRegistration for Box<dyn Buttonlike> {
161        fn get_type_registration() -> TypeRegistration {
162            let mut registration = TypeRegistration::of::<Self>();
163            registration
164                .insert::<ReflectDeserialize>(CreateTypeData::<Self, ()>::create_type_data(()));
165            registration.insert::<ReflectFromPtr>(CreateTypeData::<Self, ()>::create_type_data(()));
166            registration
167                .insert::<ReflectSerialize>(CreateTypeData::<Self, ()>::create_type_data(()));
168            registration
169        }
170    }
171
172    impl FromReflect for Box<dyn Buttonlike> {
173        fn from_reflect(reflect: &dyn PartialReflect) -> Option<Self> {
174            Some(reflect.try_downcast_ref::<Self>()?.clone())
175        }
176    }
177}
178
179mod axislike {
180    use bevy::reflect::PartialReflect;
181
182    use super::*;
183
184    use crate::user_input::Axislike;
185
186    dyn_clone::clone_trait_object!(Axislike);
187    dyn_eq::eq_trait_object!(Axislike);
188    dyn_hash::hash_trait_object!(Axislike);
189
190    impl PartialReflect for Box<dyn Axislike> {
191        fn get_represented_type_info(&self) -> Option<&'static TypeInfo> {
192            Some(Self::type_info())
193        }
194
195        fn reflect_kind(&self) -> ReflectKind {
196            ReflectKind::Opaque
197        }
198
199        fn reflect_ref(&self) -> ReflectRef<'_> {
200            ReflectRef::Opaque(self)
201        }
202
203        fn reflect_mut(&mut self) -> ReflectMut<'_> {
204            ReflectMut::Opaque(self)
205        }
206
207        fn reflect_owned(self: Box<Self>) -> ReflectOwned {
208            ReflectOwned::Opaque(self)
209        }
210
211        fn try_apply(
212            &mut self,
213            value: &dyn PartialReflect,
214        ) -> Result<(), bevy::reflect::ApplyError> {
215            if let Some(value) = value.try_downcast_ref::<Self>() {
216                *self = value.clone();
217                Ok(())
218            } else {
219                Err(bevy::reflect::ApplyError::MismatchedTypes {
220                    from_type: self
221                        .reflect_type_ident()
222                        .unwrap_or_default()
223                        .to_string()
224                        .into_boxed_str(),
225                    to_type: self
226                        .reflect_type_ident()
227                        .unwrap_or_default()
228                        .to_string()
229                        .into_boxed_str(),
230                })
231            }
232        }
233
234        fn into_partial_reflect(self: Box<Self>) -> Box<dyn PartialReflect> {
235            self
236        }
237
238        fn as_partial_reflect(&self) -> &dyn PartialReflect {
239            self
240        }
241
242        fn as_partial_reflect_mut(&mut self) -> &mut dyn PartialReflect {
243            self
244        }
245
246        fn try_into_reflect(self: Box<Self>) -> Result<Box<dyn Reflect>, Box<dyn PartialReflect>> {
247            Ok(self)
248        }
249
250        fn try_as_reflect(&self) -> Option<&dyn Reflect> {
251            Some(self)
252        }
253
254        fn try_as_reflect_mut(&mut self) -> Option<&mut dyn Reflect> {
255            Some(self)
256        }
257    }
258
259    impl Reflect for Box<dyn Axislike> {
260        fn into_any(self: Box<Self>) -> Box<dyn Any> {
261            self
262        }
263
264        fn as_any(&self) -> &dyn Any {
265            self
266        }
267
268        fn as_any_mut(&mut self) -> &mut dyn Any {
269            self
270        }
271
272        fn into_reflect(self: Box<Self>) -> Box<dyn Reflect> {
273            self
274        }
275
276        fn as_reflect(&self) -> &dyn Reflect {
277            self
278        }
279
280        fn as_reflect_mut(&mut self) -> &mut dyn Reflect {
281            self
282        }
283
284        fn set(&mut self, value: Box<dyn Reflect>) -> Result<(), Box<dyn Reflect>> {
285            *self = value.take()?;
286            Ok(())
287        }
288    }
289
290    impl Typed for Box<dyn Axislike> {
291        fn type_info() -> &'static TypeInfo {
292            static CELL: NonGenericTypeInfoCell = NonGenericTypeInfoCell::new();
293            CELL.get_or_set(|| TypeInfo::Opaque(OpaqueInfo::new::<Self>()))
294        }
295    }
296
297    impl TypePath for Box<dyn Axislike> {
298        fn type_path() -> &'static str {
299            static CELL: GenericTypePathCell = GenericTypePathCell::new();
300            CELL.get_or_insert::<Self, _>(|| {
301                format!("std::boxed::Box<dyn {}::Axislike>", module_path!())
302            })
303        }
304
305        fn short_type_path() -> &'static str {
306            static CELL: GenericTypePathCell = GenericTypePathCell::new();
307            CELL.get_or_insert::<Self, _>(|| "Box<dyn Axislike>".to_string())
308        }
309
310        fn type_ident() -> Option<&'static str> {
311            Some("Box<dyn Axislike>")
312        }
313
314        fn crate_name() -> Option<&'static str> {
315            module_path!().split(':').next()
316        }
317
318        fn module_path() -> Option<&'static str> {
319            Some(module_path!())
320        }
321    }
322
323    impl GetTypeRegistration for Box<dyn Axislike> {
324        fn get_type_registration() -> TypeRegistration {
325            let mut registration = TypeRegistration::of::<Self>();
326            registration
327                .insert::<ReflectDeserialize>(CreateTypeData::<Self, ()>::create_type_data(()));
328            registration.insert::<ReflectFromPtr>(CreateTypeData::<Self, ()>::create_type_data(()));
329            registration
330                .insert::<ReflectSerialize>(CreateTypeData::<Self, ()>::create_type_data(()));
331            registration
332        }
333    }
334
335    impl FromReflect for Box<dyn Axislike> {
336        fn from_reflect(reflect: &dyn PartialReflect) -> Option<Self> {
337            Some(reflect.try_downcast_ref::<Self>()?.clone())
338        }
339    }
340}
341
342mod dualaxislike {
343    use bevy::reflect::{OpaqueInfo, PartialReflect};
344
345    use super::*;
346
347    use crate::user_input::DualAxislike;
348
349    dyn_clone::clone_trait_object!(DualAxislike);
350    dyn_eq::eq_trait_object!(DualAxislike);
351    dyn_hash::hash_trait_object!(DualAxislike);
352
353    impl PartialReflect for Box<dyn DualAxislike> {
354        fn get_represented_type_info(&self) -> Option<&'static TypeInfo> {
355            Some(Self::type_info())
356        }
357
358        fn try_apply(
359            &mut self,
360            value: &dyn PartialReflect,
361        ) -> Result<(), bevy::reflect::ApplyError> {
362            if let Some(value) = value.try_downcast_ref::<Self>() {
363                *self = value.clone();
364                Ok(())
365            } else {
366                Err(bevy::reflect::ApplyError::MismatchedTypes {
367                    from_type: self
368                        .reflect_type_ident()
369                        .unwrap_or_default()
370                        .to_string()
371                        .into_boxed_str(),
372                    to_type: self
373                        .reflect_type_ident()
374                        .unwrap_or_default()
375                        .to_string()
376                        .into_boxed_str(),
377                })
378            }
379        }
380
381        fn reflect_kind(&self) -> ReflectKind {
382            ReflectKind::Opaque
383        }
384
385        fn reflect_ref(&self) -> ReflectRef<'_> {
386            ReflectRef::Opaque(self)
387        }
388
389        fn reflect_mut(&mut self) -> ReflectMut<'_> {
390            ReflectMut::Opaque(self)
391        }
392
393        fn reflect_owned(self: Box<Self>) -> ReflectOwned {
394            ReflectOwned::Opaque(self)
395        }
396
397        fn into_partial_reflect(self: Box<Self>) -> Box<dyn PartialReflect> {
398            self
399        }
400
401        fn as_partial_reflect(&self) -> &dyn PartialReflect {
402            self
403        }
404
405        fn as_partial_reflect_mut(&mut self) -> &mut dyn PartialReflect {
406            self
407        }
408
409        fn try_into_reflect(self: Box<Self>) -> Result<Box<dyn Reflect>, Box<dyn PartialReflect>> {
410            Ok(self)
411        }
412
413        fn try_as_reflect(&self) -> Option<&dyn Reflect> {
414            Some(self)
415        }
416
417        fn try_as_reflect_mut(&mut self) -> Option<&mut dyn Reflect> {
418            Some(self)
419        }
420    }
421
422    impl Reflect for Box<dyn DualAxislike> {
423        fn into_any(self: Box<Self>) -> Box<dyn Any> {
424            self
425        }
426
427        fn as_any(&self) -> &dyn Any {
428            self
429        }
430
431        fn as_any_mut(&mut self) -> &mut dyn Any {
432            self
433        }
434
435        fn into_reflect(self: Box<Self>) -> Box<dyn Reflect> {
436            self
437        }
438
439        fn as_reflect(&self) -> &dyn Reflect {
440            self
441        }
442
443        fn as_reflect_mut(&mut self) -> &mut dyn Reflect {
444            self
445        }
446
447        fn set(&mut self, value: Box<dyn Reflect>) -> Result<(), Box<dyn Reflect>> {
448            *self = value.take()?;
449            Ok(())
450        }
451    }
452
453    impl Typed for Box<dyn DualAxislike> {
454        fn type_info() -> &'static TypeInfo {
455            static CELL: NonGenericTypeInfoCell = NonGenericTypeInfoCell::new();
456            CELL.get_or_set(|| TypeInfo::Opaque(OpaqueInfo::new::<Self>()))
457        }
458    }
459
460    impl TypePath for Box<dyn DualAxislike> {
461        fn type_path() -> &'static str {
462            static CELL: GenericTypePathCell = GenericTypePathCell::new();
463            CELL.get_or_insert::<Self, _>(|| {
464                format!("std::boxed::Box<dyn {}::DualAxislike>", module_path!())
465            })
466        }
467
468        fn short_type_path() -> &'static str {
469            static CELL: GenericTypePathCell = GenericTypePathCell::new();
470            CELL.get_or_insert::<Self, _>(|| "Box<dyn DualAxislike>".to_string())
471        }
472
473        fn type_ident() -> Option<&'static str> {
474            Some("Box<dyn DualAxislike>")
475        }
476
477        fn crate_name() -> Option<&'static str> {
478            module_path!().split(':').next()
479        }
480
481        fn module_path() -> Option<&'static str> {
482            Some(module_path!())
483        }
484    }
485
486    impl GetTypeRegistration for Box<dyn DualAxislike> {
487        fn get_type_registration() -> TypeRegistration {
488            let mut registration = TypeRegistration::of::<Self>();
489            registration
490                .insert::<ReflectDeserialize>(CreateTypeData::<Self, ()>::create_type_data(()));
491            registration.insert::<ReflectFromPtr>(CreateTypeData::<Self, ()>::create_type_data(()));
492            registration
493                .insert::<ReflectSerialize>(CreateTypeData::<Self, ()>::create_type_data(()));
494            registration
495        }
496    }
497
498    impl FromReflect for Box<dyn DualAxislike> {
499        fn from_reflect(reflect: &dyn PartialReflect) -> Option<Self> {
500            Some(reflect.try_downcast_ref::<Self>()?.clone())
501        }
502    }
503}
504
505mod tripleaxislike {
506    use bevy::reflect::{OpaqueInfo, PartialReflect};
507
508    use super::*;
509
510    use crate::user_input::TripleAxislike;
511
512    dyn_clone::clone_trait_object!(TripleAxislike);
513    dyn_eq::eq_trait_object!(TripleAxislike);
514    dyn_hash::hash_trait_object!(TripleAxislike);
515
516    impl PartialReflect for Box<dyn TripleAxislike> {
517        fn get_represented_type_info(&self) -> Option<&'static TypeInfo> {
518            Some(Self::type_info())
519        }
520
521        fn try_apply(
522            &mut self,
523            value: &dyn PartialReflect,
524        ) -> Result<(), bevy::reflect::ApplyError> {
525            if let Some(value) = value.try_downcast_ref::<Self>() {
526                *self = value.clone();
527                Ok(())
528            } else {
529                Err(bevy::reflect::ApplyError::MismatchedTypes {
530                    from_type: self
531                        .reflect_type_ident()
532                        .unwrap_or_default()
533                        .to_string()
534                        .into_boxed_str(),
535                    to_type: self
536                        .reflect_type_ident()
537                        .unwrap_or_default()
538                        .to_string()
539                        .into_boxed_str(),
540                })
541            }
542        }
543
544        fn reflect_kind(&self) -> ReflectKind {
545            ReflectKind::Opaque
546        }
547
548        fn reflect_ref(&self) -> ReflectRef<'_> {
549            ReflectRef::Opaque(self)
550        }
551
552        fn reflect_mut(&mut self) -> ReflectMut<'_> {
553            ReflectMut::Opaque(self)
554        }
555
556        fn reflect_owned(self: Box<Self>) -> ReflectOwned {
557            ReflectOwned::Opaque(self)
558        }
559
560        fn into_partial_reflect(self: Box<Self>) -> Box<dyn PartialReflect> {
561            self
562        }
563
564        fn as_partial_reflect(&self) -> &dyn PartialReflect {
565            self
566        }
567
568        fn as_partial_reflect_mut(&mut self) -> &mut dyn PartialReflect {
569            self
570        }
571
572        fn try_into_reflect(self: Box<Self>) -> Result<Box<dyn Reflect>, Box<dyn PartialReflect>> {
573            Ok(self)
574        }
575
576        fn try_as_reflect(&self) -> Option<&dyn Reflect> {
577            Some(self)
578        }
579
580        fn try_as_reflect_mut(&mut self) -> Option<&mut dyn Reflect> {
581            Some(self)
582        }
583    }
584
585    impl Reflect for Box<dyn TripleAxislike> {
586        fn into_any(self: Box<Self>) -> Box<dyn Any> {
587            self
588        }
589
590        fn as_any(&self) -> &dyn Any {
591            self
592        }
593
594        fn as_any_mut(&mut self) -> &mut dyn Any {
595            self
596        }
597
598        fn into_reflect(self: Box<Self>) -> Box<dyn Reflect> {
599            self
600        }
601
602        fn as_reflect(&self) -> &dyn Reflect {
603            self
604        }
605
606        fn as_reflect_mut(&mut self) -> &mut dyn Reflect {
607            self
608        }
609
610        fn set(&mut self, value: Box<dyn Reflect>) -> Result<(), Box<dyn Reflect>> {
611            *self = value.take()?;
612            Ok(())
613        }
614    }
615
616    impl Typed for Box<dyn TripleAxislike> {
617        fn type_info() -> &'static TypeInfo {
618            static CELL: NonGenericTypeInfoCell = NonGenericTypeInfoCell::new();
619            CELL.get_or_set(|| TypeInfo::Opaque(OpaqueInfo::new::<Self>()))
620        }
621    }
622
623    impl TypePath for Box<dyn TripleAxislike> {
624        fn type_path() -> &'static str {
625            static CELL: GenericTypePathCell = GenericTypePathCell::new();
626            CELL.get_or_insert::<Self, _>(|| {
627                format!("std::boxed::Box<dyn {}::TripleAxislike>", module_path!())
628            })
629        }
630
631        fn short_type_path() -> &'static str {
632            static CELL: GenericTypePathCell = GenericTypePathCell::new();
633            CELL.get_or_insert::<Self, _>(|| "Box<dyn TripleAxislike>".to_string())
634        }
635
636        fn type_ident() -> Option<&'static str> {
637            Some("Box<dyn TripleAxislike>")
638        }
639
640        fn crate_name() -> Option<&'static str> {
641            module_path!().split(':').next()
642        }
643
644        fn module_path() -> Option<&'static str> {
645            Some(module_path!())
646        }
647    }
648
649    impl GetTypeRegistration for Box<dyn TripleAxislike> {
650        fn get_type_registration() -> TypeRegistration {
651            let mut registration = TypeRegistration::of::<Self>();
652            registration
653                .insert::<ReflectDeserialize>(CreateTypeData::<Self, ()>::create_type_data(()));
654            registration.insert::<ReflectFromPtr>(CreateTypeData::<Self, ()>::create_type_data(()));
655            registration
656                .insert::<ReflectSerialize>(CreateTypeData::<Self, ()>::create_type_data(()));
657            registration
658        }
659    }
660
661    impl FromReflect for Box<dyn TripleAxislike> {
662        fn from_reflect(reflect: &dyn PartialReflect) -> Option<Self> {
663            Some(reflect.try_downcast_ref::<Self>()?.clone())
664        }
665    }
666}