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