1use bevy_reflect_derive::impl_type_path;
5use variadics_please::all_tuples;
6
7use crate::generics::impl_generic_info_methods;
8use crate::{
9 type_info::impl_type_methods, utility::GenericTypePathCell, ApplyError, FromReflect, Generics,
10 GetTypeRegistration, MaybeTyped, PartialReflect, Reflect, ReflectCloneError, ReflectKind,
11 ReflectMut, ReflectOwned, ReflectRef, Type, TypeInfo, TypePath, TypeRegistration, TypeRegistry,
12 Typed, UnnamedField,
13};
14use alloc::{boxed::Box, vec, vec::Vec};
15use core::{
16 any::Any,
17 fmt::{Debug, Formatter},
18 slice::Iter,
19};
20
21pub trait Tuple: PartialReflect {
44 fn field(&self, index: usize) -> Option<&dyn PartialReflect>;
47
48 fn field_mut(&mut self, index: usize) -> Option<&mut dyn PartialReflect>;
51
52 fn field_len(&self) -> usize;
54
55 fn iter_fields(&self) -> TupleFieldIter<'_>;
57
58 fn drain(self: Box<Self>) -> Vec<Box<dyn PartialReflect>>;
60
61 fn to_dynamic_tuple(&self) -> DynamicTuple {
63 DynamicTuple {
64 represented_type: self.get_represented_type_info(),
65 fields: self.iter_fields().map(PartialReflect::to_dynamic).collect(),
66 }
67 }
68
69 fn get_represented_tuple_info(&self) -> Option<&'static TupleInfo> {
71 self.get_represented_type_info()?.as_tuple().ok()
72 }
73}
74
75pub struct TupleFieldIter<'a> {
77 pub(crate) tuple: &'a dyn Tuple,
78 pub(crate) index: usize,
79}
80
81impl<'a> TupleFieldIter<'a> {
82 pub fn new(value: &'a dyn Tuple) -> Self {
84 TupleFieldIter {
85 tuple: value,
86 index: 0,
87 }
88 }
89}
90
91impl<'a> Iterator for TupleFieldIter<'a> {
92 type Item = &'a dyn PartialReflect;
93
94 fn next(&mut self) -> Option<Self::Item> {
95 let value = self.tuple.field(self.index);
96 self.index += value.is_some() as usize;
97 value
98 }
99
100 fn size_hint(&self) -> (usize, Option<usize>) {
101 let size = self.tuple.field_len();
102 (size, Some(size))
103 }
104}
105
106impl<'a> ExactSizeIterator for TupleFieldIter<'a> {}
107
108pub trait GetTupleField {
124 fn get_field<T: Reflect>(&self, index: usize) -> Option<&T>;
127
128 fn get_field_mut<T: Reflect>(&mut self, index: usize) -> Option<&mut T>;
131}
132
133impl<S: Tuple> GetTupleField for S {
134 fn get_field<T: Reflect>(&self, index: usize) -> Option<&T> {
135 self.field(index)
136 .and_then(|value| value.try_downcast_ref::<T>())
137 }
138
139 fn get_field_mut<T: Reflect>(&mut self, index: usize) -> Option<&mut T> {
140 self.field_mut(index)
141 .and_then(|value| value.try_downcast_mut::<T>())
142 }
143}
144
145impl GetTupleField for dyn Tuple {
146 fn get_field<T: Reflect>(&self, index: usize) -> Option<&T> {
147 self.field(index)
148 .and_then(|value| value.try_downcast_ref::<T>())
149 }
150
151 fn get_field_mut<T: Reflect>(&mut self, index: usize) -> Option<&mut T> {
152 self.field_mut(index)
153 .and_then(|value| value.try_downcast_mut::<T>())
154 }
155}
156
157#[derive(Clone, Debug)]
159pub struct TupleInfo {
160 ty: Type,
161 generics: Generics,
162 fields: Box<[UnnamedField]>,
163 #[cfg(feature = "reflect_documentation")]
164 docs: Option<&'static str>,
165}
166
167impl TupleInfo {
168 pub fn new<T: Reflect + TypePath>(fields: &[UnnamedField]) -> Self {
174 Self {
175 ty: Type::of::<T>(),
176 generics: Generics::new(),
177 fields: fields.to_vec().into_boxed_slice(),
178 #[cfg(feature = "reflect_documentation")]
179 docs: None,
180 }
181 }
182
183 #[cfg(feature = "reflect_documentation")]
185 pub fn with_docs(self, docs: Option<&'static str>) -> Self {
186 Self { docs, ..self }
187 }
188
189 pub fn field_at(&self, index: usize) -> Option<&UnnamedField> {
191 self.fields.get(index)
192 }
193
194 pub fn iter(&self) -> Iter<'_, UnnamedField> {
196 self.fields.iter()
197 }
198
199 pub fn field_len(&self) -> usize {
201 self.fields.len()
202 }
203
204 impl_type_methods!(ty);
205
206 #[cfg(feature = "reflect_documentation")]
208 pub fn docs(&self) -> Option<&'static str> {
209 self.docs
210 }
211
212 impl_generic_info_methods!(generics);
213}
214
215#[derive(Default, Debug)]
217pub struct DynamicTuple {
218 represented_type: Option<&'static TypeInfo>,
219 fields: Vec<Box<dyn PartialReflect>>,
220}
221
222impl DynamicTuple {
223 pub fn set_represented_type(&mut self, represented_type: Option<&'static TypeInfo>) {
231 if let Some(represented_type) = represented_type {
232 assert!(
233 matches!(represented_type, TypeInfo::Tuple(_)),
234 "expected TypeInfo::Tuple but received: {represented_type:?}"
235 );
236 }
237 self.represented_type = represented_type;
238 }
239
240 pub fn insert_boxed(&mut self, value: Box<dyn PartialReflect>) {
242 self.represented_type = None;
243 self.fields.push(value);
244 }
245
246 pub fn insert<T: PartialReflect>(&mut self, value: T) {
248 self.represented_type = None;
249 self.insert_boxed(Box::new(value));
250 }
251}
252
253impl Tuple for DynamicTuple {
254 #[inline]
255 fn field(&self, index: usize) -> Option<&dyn PartialReflect> {
256 self.fields.get(index).map(|field| &**field)
257 }
258
259 #[inline]
260 fn field_mut(&mut self, index: usize) -> Option<&mut dyn PartialReflect> {
261 self.fields.get_mut(index).map(|field| &mut **field)
262 }
263
264 #[inline]
265 fn field_len(&self) -> usize {
266 self.fields.len()
267 }
268
269 #[inline]
270 fn iter_fields(&self) -> TupleFieldIter<'_> {
271 TupleFieldIter {
272 tuple: self,
273 index: 0,
274 }
275 }
276
277 #[inline]
278 fn drain(self: Box<Self>) -> Vec<Box<dyn PartialReflect>> {
279 self.fields
280 }
281}
282
283impl PartialReflect for DynamicTuple {
284 #[inline]
285 fn get_represented_type_info(&self) -> Option<&'static TypeInfo> {
286 self.represented_type
287 }
288
289 #[inline]
290 fn into_partial_reflect(self: Box<Self>) -> Box<dyn PartialReflect> {
291 self
292 }
293
294 fn as_partial_reflect(&self) -> &dyn PartialReflect {
295 self
296 }
297
298 fn as_partial_reflect_mut(&mut self) -> &mut dyn PartialReflect {
299 self
300 }
301
302 fn try_into_reflect(self: Box<Self>) -> Result<Box<dyn Reflect>, Box<dyn PartialReflect>> {
303 Err(self)
304 }
305
306 fn try_as_reflect(&self) -> Option<&dyn Reflect> {
307 None
308 }
309
310 fn try_as_reflect_mut(&mut self) -> Option<&mut dyn Reflect> {
311 None
312 }
313
314 fn apply(&mut self, value: &dyn PartialReflect) {
315 tuple_apply(self, value);
316 }
317
318 #[inline]
319 fn reflect_kind(&self) -> ReflectKind {
320 ReflectKind::Tuple
321 }
322
323 #[inline]
324 fn reflect_ref(&self) -> ReflectRef<'_> {
325 ReflectRef::Tuple(self)
326 }
327
328 #[inline]
329 fn reflect_mut(&mut self) -> ReflectMut<'_> {
330 ReflectMut::Tuple(self)
331 }
332
333 #[inline]
334 fn reflect_owned(self: Box<Self>) -> ReflectOwned {
335 ReflectOwned::Tuple(self)
336 }
337
338 fn try_apply(&mut self, value: &dyn PartialReflect) -> Result<(), ApplyError> {
339 tuple_try_apply(self, value)
340 }
341
342 fn reflect_partial_eq(&self, value: &dyn PartialReflect) -> Option<bool> {
343 tuple_partial_eq(self, value)
344 }
345
346 fn reflect_partial_cmp(&self, value: &dyn PartialReflect) -> Option<::core::cmp::Ordering> {
347 tuple_partial_cmp(self, value)
348 }
349
350 fn debug(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
351 write!(f, "DynamicTuple(")?;
352 tuple_debug(self, f)?;
353 write!(f, ")")
354 }
355
356 #[inline]
357 fn is_dynamic(&self) -> bool {
358 true
359 }
360}
361
362impl_type_path!((in bevy_reflect) DynamicTuple);
363
364impl FromIterator<Box<dyn PartialReflect>> for DynamicTuple {
365 fn from_iter<I: IntoIterator<Item = Box<dyn PartialReflect>>>(fields: I) -> Self {
366 Self {
367 represented_type: None,
368 fields: fields.into_iter().collect(),
369 }
370 }
371}
372
373impl IntoIterator for DynamicTuple {
374 type Item = Box<dyn PartialReflect>;
375 type IntoIter = vec::IntoIter<Self::Item>;
376
377 fn into_iter(self) -> Self::IntoIter {
378 self.fields.into_iter()
379 }
380}
381
382impl<'a> IntoIterator for &'a DynamicTuple {
383 type Item = &'a dyn PartialReflect;
384 type IntoIter = TupleFieldIter<'a>;
385
386 fn into_iter(self) -> Self::IntoIter {
387 self.iter_fields()
388 }
389}
390
391#[inline]
397pub fn tuple_apply<T: Tuple>(a: &mut T, b: &dyn PartialReflect) {
398 if let Err(err) = tuple_try_apply(a, b) {
399 panic!("{err}");
400 }
401}
402
403#[inline]
411pub fn tuple_try_apply<T: Tuple>(a: &mut T, b: &dyn PartialReflect) -> Result<(), ApplyError> {
412 let tuple = b.reflect_ref().as_tuple()?;
413
414 for (i, value) in tuple.iter_fields().enumerate() {
415 if let Some(v) = a.field_mut(i) {
416 v.try_apply(value)?;
417 }
418 }
419
420 Ok(())
421}
422
423#[inline]
432pub fn tuple_partial_eq<T: Tuple + ?Sized>(a: &T, b: &dyn PartialReflect) -> Option<bool> {
433 let ReflectRef::Tuple(b) = b.reflect_ref() else {
434 return Some(false);
435 };
436
437 if a.field_len() != b.field_len() {
438 return Some(false);
439 }
440
441 for (a_field, b_field) in a.iter_fields().zip(b.iter_fields()) {
442 let eq_result = a_field.reflect_partial_eq(b_field);
443 if let failed @ (Some(false) | None) = eq_result {
444 return failed;
445 }
446 }
447
448 Some(true)
449}
450
451#[inline]
456pub fn tuple_partial_cmp<T: Tuple + ?Sized>(
457 a: &T,
458 b: &dyn PartialReflect,
459) -> Option<::core::cmp::Ordering> {
460 let ReflectRef::Tuple(b) = b.reflect_ref() else {
461 return None;
462 };
463 if a.field_len() != b.field_len() {
464 return None;
465 }
466
467 for (a_field, b_field) in a.iter_fields().zip(b.iter_fields()) {
468 match a_field.reflect_partial_cmp(b_field) {
469 None => return None,
470 Some(core::cmp::Ordering::Equal) => continue,
471 Some(ord) => return Some(ord),
472 }
473 }
474
475 Some(core::cmp::Ordering::Equal)
476}
477
478#[inline]
496pub fn tuple_debug(dyn_tuple: &dyn Tuple, f: &mut Formatter<'_>) -> core::fmt::Result {
497 let mut debug = f.debug_tuple("");
498 for field in dyn_tuple.iter_fields() {
499 debug.field(&field as &dyn Debug);
500 }
501 debug.finish()
502}
503
504macro_rules! impl_reflect_tuple {
505 {$($index:tt : $name:tt),*} => {
506 impl<$($name: Reflect + MaybeTyped + TypePath + GetTypeRegistration),*> Tuple for ($($name,)*) {
507 #[inline]
508 fn field(&self, index: usize) -> Option<&dyn PartialReflect> {
509 match index {
510 $($index => Some(&self.$index as &dyn PartialReflect),)*
511 _ => None,
512 }
513 }
514
515 #[inline]
516 fn field_mut(&mut self, index: usize) -> Option<&mut dyn PartialReflect> {
517 match index {
518 $($index => Some(&mut self.$index as &mut dyn PartialReflect),)*
519 _ => None,
520 }
521 }
522
523 #[inline]
524 fn field_len(&self) -> usize {
525 let indices: &[usize] = &[$($index as usize),*];
526 indices.len()
527 }
528
529 #[inline]
530 fn iter_fields(&self) -> TupleFieldIter<'_> {
531 TupleFieldIter {
532 tuple: self,
533 index: 0,
534 }
535 }
536
537 #[inline]
538 fn drain(self: Box<Self>) -> Vec<Box<dyn PartialReflect>> {
539 vec![
540 $(Box::new(self.$index),)*
541 ]
542 }
543 }
544
545 impl<$($name: Reflect + MaybeTyped + TypePath + GetTypeRegistration),*> PartialReflect for ($($name,)*) {
546 fn get_represented_type_info(&self) -> Option<&'static TypeInfo> {
547 Some(<Self as Typed>::type_info())
548 }
549
550 #[inline]
551 fn into_partial_reflect(self: Box<Self>) -> Box<dyn PartialReflect> {
552 self
553 }
554
555 fn as_partial_reflect(&self) -> &dyn PartialReflect {
556 self
557 }
558
559 fn as_partial_reflect_mut(&mut self) -> &mut dyn PartialReflect {
560 self
561 }
562
563 fn try_into_reflect(self: Box<Self>) -> Result<Box<dyn Reflect>, Box<dyn PartialReflect>> {
564 Ok(self)
565 }
566
567 fn try_as_reflect(&self) -> Option<&dyn Reflect> {
568 Some(self)
569 }
570
571 fn try_as_reflect_mut(&mut self) -> Option<&mut dyn Reflect> {
572 Some(self)
573 }
574
575 fn reflect_kind(&self) -> ReflectKind {
576 ReflectKind::Tuple
577 }
578
579 fn reflect_ref(&self) -> ReflectRef <'_> {
580 ReflectRef::Tuple(self)
581 }
582
583 fn reflect_mut(&mut self) -> ReflectMut <'_> {
584 ReflectMut::Tuple(self)
585 }
586
587 fn reflect_owned(self: Box<Self>) -> ReflectOwned {
588 ReflectOwned::Tuple(self)
589 }
590
591 fn reflect_partial_eq(&self, value: &dyn PartialReflect) -> Option<bool> {
592 crate::tuple::tuple_partial_eq(self, value)
593 }
594 fn reflect_partial_cmp(&self, value: &dyn PartialReflect) -> Option<::core::cmp::Ordering> {
595 crate::tuple::tuple_partial_cmp(self, value)
596 }
597
598 fn apply(&mut self, value: &dyn PartialReflect) {
599 crate::tuple::tuple_apply(self, value);
600 }
601
602 fn try_apply(&mut self, value: &dyn PartialReflect) -> Result<(), ApplyError> {
603 crate::tuple::tuple_try_apply(self, value)
604 }
605
606 fn reflect_clone(&self) -> Result<Box<dyn Reflect>, ReflectCloneError> {
607 Ok(Box::new((
608 $(
609 self.$index.reflect_clone()?
610 .take::<$name>()
611 .expect("`Reflect::reflect_clone` should return the same type"),
612 )*
613 )))
614 }
615 }
616
617 impl<$($name: Reflect + MaybeTyped + TypePath + GetTypeRegistration),*> Reflect for ($($name,)*) {
618 fn into_any(self: Box<Self>) -> Box<dyn Any> {
619 self
620 }
621
622 fn as_any(&self) -> &dyn Any {
623 self
624 }
625
626 fn as_any_mut(&mut self) -> &mut dyn Any {
627 self
628 }
629
630 fn into_reflect(self: Box<Self>) -> Box<dyn Reflect> {
631 self
632 }
633
634 fn as_reflect(&self) -> &dyn Reflect {
635 self
636 }
637
638 fn as_reflect_mut(&mut self) -> &mut dyn Reflect {
639 self
640 }
641
642 fn set(&mut self, value: Box<dyn Reflect>) -> Result<(), Box<dyn Reflect>> {
643 *self = value.take()?;
644 Ok(())
645 }
646 }
647
648 impl <$($name: Reflect + MaybeTyped + TypePath + GetTypeRegistration),*> Typed for ($($name,)*) {
649 fn type_info() -> &'static TypeInfo {
650 static CELL: $crate::utility::GenericTypeInfoCell = $crate::utility::GenericTypeInfoCell::new();
651 CELL.get_or_insert::<Self, _>(|| {
652 let fields = [
653 $(UnnamedField::new::<$name>($index),)*
654 ];
655 let info = TupleInfo::new::<Self>(&fields);
656 TypeInfo::Tuple(info)
657 })
658 }
659 }
660
661 impl<$($name: Reflect + MaybeTyped + TypePath + GetTypeRegistration),*> GetTypeRegistration for ($($name,)*) {
662 fn get_type_registration() -> TypeRegistration {
663 TypeRegistration::of::<($($name,)*)>()
664 }
665
666 fn register_type_dependencies(_registry: &mut TypeRegistry) {
667 $(_registry.register::<$name>();)*
668 }
669 }
670
671 impl<$($name: FromReflect + MaybeTyped + TypePath + GetTypeRegistration),*> FromReflect for ($($name,)*)
672 {
673 fn from_reflect(reflect: &dyn PartialReflect) -> Option<Self> {
674 let _ref_tuple = reflect.reflect_ref().as_tuple().ok()?;
675
676 Some(
677 (
678 $(
679 <$name as FromReflect>::from_reflect(_ref_tuple.field($index)?)?,
680 )*
681 )
682 )
683 }
684 }
685 }
686}
687
688impl_reflect_tuple! {}
689
690impl_reflect_tuple! {0: A}
691
692impl_reflect_tuple! {0: A, 1: B}
693
694impl_reflect_tuple! {0: A, 1: B, 2: C}
695
696impl_reflect_tuple! {0: A, 1: B, 2: C, 3: D}
697
698impl_reflect_tuple! {0: A, 1: B, 2: C, 3: D, 4: E}
699
700impl_reflect_tuple! {0: A, 1: B, 2: C, 3: D, 4: E, 5: F}
701
702impl_reflect_tuple! {0: A, 1: B, 2: C, 3: D, 4: E, 5: F, 6: G}
703
704impl_reflect_tuple! {0: A, 1: B, 2: C, 3: D, 4: E, 5: F, 6: G, 7: H}
705
706impl_reflect_tuple! {0: A, 1: B, 2: C, 3: D, 4: E, 5: F, 6: G, 7: H, 8: I}
707
708impl_reflect_tuple! {0: A, 1: B, 2: C, 3: D, 4: E, 5: F, 6: G, 7: H, 8: I, 9: J}
709
710impl_reflect_tuple! {0: A, 1: B, 2: C, 3: D, 4: E, 5: F, 6: G, 7: H, 8: I, 9: J, 10: K}
711
712impl_reflect_tuple! {0: A, 1: B, 2: C, 3: D, 4: E, 5: F, 6: G, 7: H, 8: I, 9: J, 10: K, 11: L}
713
714macro_rules! impl_type_path_tuple {
715 ($(#[$meta:meta])*) => {
716 $(#[$meta])*
717 impl TypePath for () {
718 fn type_path() -> &'static str {
719 "()"
720 }
721
722 fn short_type_path() -> &'static str {
723 "()"
724 }
725 }
726 };
727
728 ($(#[$meta:meta])* $param:ident) => {
729 $(#[$meta])*
730 impl <$param: TypePath> TypePath for ($param,) {
731 fn type_path() -> &'static str {
732 use $crate::__macro_exports::alloc_utils::ToOwned;
733 static CELL: GenericTypePathCell = GenericTypePathCell::new();
734 CELL.get_or_insert::<Self, _>(|| {
735 "(".to_owned() + $param::type_path() + ",)"
736 })
737 }
738
739 fn short_type_path() -> &'static str {
740 use $crate::__macro_exports::alloc_utils::ToOwned;
741 static CELL: GenericTypePathCell = GenericTypePathCell::new();
742 CELL.get_or_insert::<Self, _>(|| {
743 "(".to_owned() + $param::short_type_path() + ",)"
744 })
745 }
746 }
747 };
748
749 ($(#[$meta:meta])* $last:ident $(,$param:ident)*) => {
750 $(#[$meta])*
751 impl <$($param: TypePath,)* $last: TypePath> TypePath for ($($param,)* $last) {
752 fn type_path() -> &'static str {
753 use $crate::__macro_exports::alloc_utils::ToOwned;
754 static CELL: GenericTypePathCell = GenericTypePathCell::new();
755 CELL.get_or_insert::<Self, _>(|| {
756 "(".to_owned() $(+ $param::type_path() + ", ")* + $last::type_path() + ")"
757 })
758 }
759
760 fn short_type_path() -> &'static str {
761 use $crate::__macro_exports::alloc_utils::ToOwned;
762 static CELL: GenericTypePathCell = GenericTypePathCell::new();
763 CELL.get_or_insert::<Self, _>(|| {
764 "(".to_owned() $(+ $param::short_type_path() + ", ")* + $last::short_type_path() + ")"
765 })
766 }
767 }
768 };
769}
770
771all_tuples!(
772 #[doc(fake_variadic)]
773 impl_type_path_tuple,
774 0,
775 12,
776 P
777);
778
779#[cfg(feature = "functions")]
780const _: () = {
781 macro_rules! impl_get_ownership_tuple {
782 ($(#[$meta:meta])* $($name: ident),*) => {
783 $(#[$meta])*
784 $crate::func::args::impl_get_ownership!(($($name,)*); <$($name),*>);
785 };
786}
787
788 all_tuples!(
789 #[doc(fake_variadic)]
790 impl_get_ownership_tuple,
791 0,
792 12,
793 P
794 );
795
796 macro_rules! impl_from_arg_tuple {
797 ($(#[$meta:meta])* $($name: ident),*) => {
798 $(#[$meta])*
799 $crate::func::args::impl_from_arg!(($($name,)*); <$($name: FromReflect + MaybeTyped + TypePath + GetTypeRegistration),*>);
800 };
801}
802
803 all_tuples!(
804 #[doc(fake_variadic)]
805 impl_from_arg_tuple,
806 0,
807 12,
808 P
809 );
810
811 macro_rules! impl_into_return_tuple {
812 ($(#[$meta:meta])* $($name: ident),+) => {
813 $(#[$meta])*
814 $crate::func::impl_into_return!(($($name,)*); <$($name: FromReflect + MaybeTyped + TypePath + GetTypeRegistration),*>);
815 };
816}
817
818 all_tuples!(
820 #[doc(fake_variadic)]
821 impl_into_return_tuple,
822 1,
823 12,
824 P
825 );
826};
827
828#[cfg(test)]
829mod tests {
830 use super::Tuple;
831
832 #[test]
833 fn next_index_increment() {
834 let mut iter = (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11).iter_fields();
835 let size = iter.len();
836 iter.index = size - 1;
837 let prev_index = iter.index;
838 assert!(iter.next().is_some());
839 assert_eq!(prev_index, iter.index - 1);
840
841 assert!(iter.next().is_none());
843 assert_eq!(size, iter.index);
844 assert!(iter.next().is_none());
845 assert_eq!(size, iter.index);
846 }
847}