1use bevy_reflect_derive::impl_type_path;
2use bevy_utils::all_tuples;
3
4use crate::{
5 self as bevy_reflect, utility::GenericTypePathCell, ApplyError, FromReflect,
6 GetTypeRegistration, Reflect, ReflectMut, ReflectOwned, ReflectRef, TypeInfo, TypePath,
7 TypeRegistration, TypeRegistry, Typed, UnnamedField,
8};
9use crate::{ReflectKind, TypePathTable};
10use std::any::{Any, TypeId};
11use std::fmt::{Debug, Formatter};
12use std::slice::Iter;
13
14pub trait Tuple: Reflect {
37 fn field(&self, index: usize) -> Option<&dyn Reflect>;
40
41 fn field_mut(&mut self, index: usize) -> Option<&mut dyn Reflect>;
44
45 fn field_len(&self) -> usize;
47
48 fn iter_fields(&self) -> TupleFieldIter;
50
51 fn drain(self: Box<Self>) -> Vec<Box<dyn Reflect>>;
53
54 fn clone_dynamic(&self) -> DynamicTuple;
56}
57
58pub struct TupleFieldIter<'a> {
60 pub(crate) tuple: &'a dyn Tuple,
61 pub(crate) index: usize,
62}
63
64impl<'a> TupleFieldIter<'a> {
65 pub fn new(value: &'a dyn Tuple) -> Self {
66 TupleFieldIter {
67 tuple: value,
68 index: 0,
69 }
70 }
71}
72
73impl<'a> Iterator for TupleFieldIter<'a> {
74 type Item = &'a dyn Reflect;
75
76 fn next(&mut self) -> Option<Self::Item> {
77 let value = self.tuple.field(self.index);
78 self.index += value.is_some() as usize;
79 value
80 }
81
82 fn size_hint(&self) -> (usize, Option<usize>) {
83 let size = self.tuple.field_len();
84 (size, Some(size))
85 }
86}
87
88impl<'a> ExactSizeIterator for TupleFieldIter<'a> {}
89
90pub trait GetTupleField {
106 fn get_field<T: Reflect>(&self, index: usize) -> Option<&T>;
109
110 fn get_field_mut<T: Reflect>(&mut self, index: usize) -> Option<&mut T>;
113}
114
115impl<S: Tuple> GetTupleField for S {
116 fn get_field<T: Reflect>(&self, index: usize) -> Option<&T> {
117 self.field(index)
118 .and_then(|value| value.downcast_ref::<T>())
119 }
120
121 fn get_field_mut<T: Reflect>(&mut self, index: usize) -> Option<&mut T> {
122 self.field_mut(index)
123 .and_then(|value| value.downcast_mut::<T>())
124 }
125}
126
127impl GetTupleField for dyn Tuple {
128 fn get_field<T: Reflect>(&self, index: usize) -> Option<&T> {
129 self.field(index)
130 .and_then(|value| value.downcast_ref::<T>())
131 }
132
133 fn get_field_mut<T: Reflect>(&mut self, index: usize) -> Option<&mut T> {
134 self.field_mut(index)
135 .and_then(|value| value.downcast_mut::<T>())
136 }
137}
138
139#[derive(Clone, Debug)]
141pub struct TupleInfo {
142 type_path: TypePathTable,
143 type_id: TypeId,
144 fields: Box<[UnnamedField]>,
145 #[cfg(feature = "documentation")]
146 docs: Option<&'static str>,
147}
148
149impl TupleInfo {
150 pub fn new<T: Reflect + TypePath>(fields: &[UnnamedField]) -> Self {
157 Self {
158 type_path: TypePathTable::of::<T>(),
159 type_id: TypeId::of::<T>(),
160 fields: fields.to_vec().into_boxed_slice(),
161 #[cfg(feature = "documentation")]
162 docs: None,
163 }
164 }
165
166 #[cfg(feature = "documentation")]
168 pub fn with_docs(self, docs: Option<&'static str>) -> Self {
169 Self { docs, ..self }
170 }
171
172 pub fn field_at(&self, index: usize) -> Option<&UnnamedField> {
174 self.fields.get(index)
175 }
176
177 pub fn iter(&self) -> Iter<'_, UnnamedField> {
179 self.fields.iter()
180 }
181
182 pub fn field_len(&self) -> usize {
184 self.fields.len()
185 }
186
187 pub fn type_path_table(&self) -> &TypePathTable {
191 &self.type_path
192 }
193
194 pub fn type_path(&self) -> &'static str {
201 self.type_path_table().path()
202 }
203
204 pub fn type_id(&self) -> TypeId {
206 self.type_id
207 }
208
209 pub fn is<T: Any>(&self) -> bool {
211 TypeId::of::<T>() == self.type_id
212 }
213
214 #[cfg(feature = "documentation")]
216 pub fn docs(&self) -> Option<&'static str> {
217 self.docs
218 }
219}
220
221#[derive(Default, Debug)]
223pub struct DynamicTuple {
224 represented_type: Option<&'static TypeInfo>,
225 fields: Vec<Box<dyn Reflect>>,
226}
227
228impl DynamicTuple {
229 pub fn set_represented_type(&mut self, represented_type: Option<&'static TypeInfo>) {
237 if let Some(represented_type) = represented_type {
238 assert!(
239 matches!(represented_type, TypeInfo::Tuple(_)),
240 "expected TypeInfo::Tuple but received: {:?}",
241 represented_type
242 );
243 }
244 self.represented_type = represented_type;
245 }
246
247 pub fn insert_boxed(&mut self, value: Box<dyn Reflect>) {
249 self.represented_type = None;
250 self.fields.push(value);
251 }
252
253 pub fn insert<T: Reflect>(&mut self, value: T) {
255 self.represented_type = None;
256 self.insert_boxed(Box::new(value));
257 }
258}
259
260impl Tuple for DynamicTuple {
261 #[inline]
262 fn field(&self, index: usize) -> Option<&dyn Reflect> {
263 self.fields.get(index).map(|field| &**field)
264 }
265
266 #[inline]
267 fn field_mut(&mut self, index: usize) -> Option<&mut dyn Reflect> {
268 self.fields.get_mut(index).map(|field| &mut **field)
269 }
270
271 #[inline]
272 fn field_len(&self) -> usize {
273 self.fields.len()
274 }
275
276 #[inline]
277 fn iter_fields(&self) -> TupleFieldIter {
278 TupleFieldIter {
279 tuple: self,
280 index: 0,
281 }
282 }
283
284 #[inline]
285 fn drain(self: Box<Self>) -> Vec<Box<dyn Reflect>> {
286 self.fields
287 }
288
289 #[inline]
290 fn clone_dynamic(&self) -> DynamicTuple {
291 DynamicTuple {
292 represented_type: self.represented_type,
293 fields: self
294 .fields
295 .iter()
296 .map(|value| value.clone_value())
297 .collect(),
298 }
299 }
300}
301
302impl Reflect for DynamicTuple {
303 #[inline]
304 fn get_represented_type_info(&self) -> Option<&'static TypeInfo> {
305 self.represented_type
306 }
307
308 #[inline]
309 fn into_any(self: Box<Self>) -> Box<dyn Any> {
310 self
311 }
312
313 #[inline]
314 fn as_any(&self) -> &dyn Any {
315 self
316 }
317
318 #[inline]
319 fn as_any_mut(&mut self) -> &mut dyn Any {
320 self
321 }
322
323 #[inline]
324 fn into_reflect(self: Box<Self>) -> Box<dyn Reflect> {
325 self
326 }
327
328 #[inline]
329 fn as_reflect(&self) -> &dyn Reflect {
330 self
331 }
332
333 #[inline]
334 fn as_reflect_mut(&mut self) -> &mut dyn Reflect {
335 self
336 }
337
338 fn apply(&mut self, value: &dyn Reflect) {
339 tuple_apply(self, value);
340 }
341
342 fn set(&mut self, value: Box<dyn Reflect>) -> Result<(), Box<dyn Reflect>> {
343 *self = value.take()?;
344 Ok(())
345 }
346
347 #[inline]
348 fn reflect_kind(&self) -> ReflectKind {
349 ReflectKind::Tuple
350 }
351
352 #[inline]
353 fn reflect_ref(&self) -> ReflectRef {
354 ReflectRef::Tuple(self)
355 }
356
357 #[inline]
358 fn reflect_mut(&mut self) -> ReflectMut {
359 ReflectMut::Tuple(self)
360 }
361
362 #[inline]
363 fn reflect_owned(self: Box<Self>) -> ReflectOwned {
364 ReflectOwned::Tuple(self)
365 }
366
367 #[inline]
368 fn clone_value(&self) -> Box<dyn Reflect> {
369 Box::new(self.clone_dynamic())
370 }
371
372 fn try_apply(&mut self, value: &dyn Reflect) -> Result<(), ApplyError> {
373 tuple_try_apply(self, value)
374 }
375
376 fn reflect_partial_eq(&self, value: &dyn Reflect) -> Option<bool> {
377 tuple_partial_eq(self, value)
378 }
379
380 fn debug(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
381 write!(f, "DynamicTuple(")?;
382 tuple_debug(self, f)?;
383 write!(f, ")")
384 }
385
386 #[inline]
387 fn is_dynamic(&self) -> bool {
388 true
389 }
390}
391
392impl_type_path!((in bevy_reflect) DynamicTuple);
393
394#[inline]
400pub fn tuple_apply<T: Tuple>(a: &mut T, b: &dyn Reflect) {
401 if let Err(err) = tuple_try_apply(a, b) {
402 panic!("{err}");
403 }
404}
405
406#[inline]
414pub fn tuple_try_apply<T: Tuple>(a: &mut T, b: &dyn Reflect) -> Result<(), ApplyError> {
415 if let ReflectRef::Tuple(tuple) = b.reflect_ref() {
416 for (i, value) in tuple.iter_fields().enumerate() {
417 if let Some(v) = a.field_mut(i) {
418 v.try_apply(value)?;
419 }
420 }
421 } else {
422 return Err(ApplyError::MismatchedKinds {
423 from_kind: b.reflect_kind(),
424 to_kind: ReflectKind::Tuple,
425 });
426 }
427 Ok(())
428}
429
430#[inline]
439pub fn tuple_partial_eq<T: Tuple>(a: &T, b: &dyn Reflect) -> Option<bool> {
440 let ReflectRef::Tuple(b) = b.reflect_ref() else {
441 return Some(false);
442 };
443
444 if a.field_len() != b.field_len() {
445 return Some(false);
446 }
447
448 for (a_field, b_field) in a.iter_fields().zip(b.iter_fields()) {
449 let eq_result = a_field.reflect_partial_eq(b_field);
450 if let failed @ (Some(false) | None) = eq_result {
451 return failed;
452 }
453 }
454
455 Some(true)
456}
457
458#[inline]
476pub fn tuple_debug(dyn_tuple: &dyn Tuple, f: &mut Formatter<'_>) -> std::fmt::Result {
477 let mut debug = f.debug_tuple("");
478 for field in dyn_tuple.iter_fields() {
479 debug.field(&field as &dyn Debug);
480 }
481 debug.finish()
482}
483
484macro_rules! impl_reflect_tuple {
485 {$($index:tt : $name:tt),*} => {
486 impl<$($name: Reflect + TypePath + GetTypeRegistration),*> Tuple for ($($name,)*) {
487 #[inline]
488 fn field(&self, index: usize) -> Option<&dyn Reflect> {
489 match index {
490 $($index => Some(&self.$index as &dyn Reflect),)*
491 _ => None,
492 }
493 }
494
495 #[inline]
496 fn field_mut(&mut self, index: usize) -> Option<&mut dyn Reflect> {
497 match index {
498 $($index => Some(&mut self.$index as &mut dyn Reflect),)*
499 _ => None,
500 }
501 }
502
503 #[inline]
504 fn field_len(&self) -> usize {
505 let indices: &[usize] = &[$($index as usize),*];
506 indices.len()
507 }
508
509 #[inline]
510 fn iter_fields(&self) -> TupleFieldIter {
511 TupleFieldIter {
512 tuple: self,
513 index: 0,
514 }
515 }
516
517 #[inline]
518 fn drain(self: Box<Self>) -> Vec<Box<dyn Reflect>> {
519 vec![
520 $(Box::new(self.$index),)*
521 ]
522 }
523
524 #[inline]
525 fn clone_dynamic(&self) -> DynamicTuple {
526 let info = self.get_represented_type_info();
527 DynamicTuple {
528 represented_type: info,
529 fields: self
530 .iter_fields()
531 .map(|value| value.clone_value())
532 .collect(),
533 }
534 }
535 }
536
537 impl<$($name: Reflect + TypePath + GetTypeRegistration),*> Reflect for ($($name,)*) {
538 fn get_represented_type_info(&self) -> Option<&'static TypeInfo> {
539 Some(<Self as Typed>::type_info())
540 }
541
542 fn into_any(self: Box<Self>) -> Box<dyn Any> {
543 self
544 }
545
546 fn as_any(&self) -> &dyn Any {
547 self
548 }
549
550 fn as_any_mut(&mut self) -> &mut dyn Any {
551 self
552 }
553
554 fn into_reflect(self: Box<Self>) -> Box<dyn Reflect> {
555 self
556 }
557
558 fn as_reflect(&self) -> &dyn Reflect {
559 self
560 }
561
562 fn as_reflect_mut(&mut self) -> &mut dyn Reflect {
563 self
564 }
565
566 fn apply(&mut self, value: &dyn Reflect) {
567 crate::tuple_apply(self, value);
568 }
569
570 fn try_apply(&mut self, value: &dyn Reflect) -> Result<(), ApplyError> {
571 crate::tuple_try_apply(self, value)
572 }
573
574 fn set(&mut self, value: Box<dyn Reflect>) -> Result<(), Box<dyn Reflect>> {
575 *self = value.take()?;
576 Ok(())
577 }
578
579 fn reflect_kind(&self) -> ReflectKind {
580 ReflectKind::Tuple
581 }
582
583 fn reflect_ref(&self) -> ReflectRef {
584 ReflectRef::Tuple(self)
585 }
586
587 fn reflect_mut(&mut self) -> ReflectMut {
588 ReflectMut::Tuple(self)
589 }
590
591 fn reflect_owned(self: Box<Self>) -> ReflectOwned {
592 ReflectOwned::Tuple(self)
593 }
594
595 fn clone_value(&self) -> Box<dyn Reflect> {
596 Box::new(self.clone_dynamic())
597 }
598
599 fn reflect_partial_eq(&self, value: &dyn Reflect) -> Option<bool> {
600 crate::tuple_partial_eq(self, value)
601 }
602 }
603
604 impl <$($name: Reflect + TypePath + GetTypeRegistration),*> Typed for ($($name,)*) {
605 fn type_info() -> &'static TypeInfo {
606 static CELL: $crate::utility::GenericTypeInfoCell = $crate::utility::GenericTypeInfoCell::new();
607 CELL.get_or_insert::<Self, _>(|| {
608 let fields = [
609 $(UnnamedField::new::<$name>($index),)*
610 ];
611 let info = TupleInfo::new::<Self>(&fields);
612 TypeInfo::Tuple(info)
613 })
614 }
615 }
616
617 impl<$($name: Reflect + TypePath + GetTypeRegistration),*> GetTypeRegistration for ($($name,)*) {
618 fn get_type_registration() -> TypeRegistration {
619 TypeRegistration::of::<($($name,)*)>()
620 }
621
622 fn register_type_dependencies(_registry: &mut TypeRegistry) {
623 $(_registry.register::<$name>();)*
624 }
625 }
626
627 impl<$($name: FromReflect + TypePath + GetTypeRegistration),*> FromReflect for ($($name,)*)
628 {
629 fn from_reflect(reflect: &dyn Reflect) -> Option<Self> {
630 if let ReflectRef::Tuple(_ref_tuple) = reflect.reflect_ref() {
631 Some(
632 (
633 $(
634 <$name as FromReflect>::from_reflect(_ref_tuple.field($index)?)?,
635 )*
636 )
637 )
638 } else {
639 None
640 }
641 }
642 }
643 }
644}
645
646impl_reflect_tuple! {}
647impl_reflect_tuple! {0: A}
648impl_reflect_tuple! {0: A, 1: B}
649impl_reflect_tuple! {0: A, 1: B, 2: C}
650impl_reflect_tuple! {0: A, 1: B, 2: C, 3: D}
651impl_reflect_tuple! {0: A, 1: B, 2: C, 3: D, 4: E}
652impl_reflect_tuple! {0: A, 1: B, 2: C, 3: D, 4: E, 5: F}
653impl_reflect_tuple! {0: A, 1: B, 2: C, 3: D, 4: E, 5: F, 6: G}
654impl_reflect_tuple! {0: A, 1: B, 2: C, 3: D, 4: E, 5: F, 6: G, 7: H}
655impl_reflect_tuple! {0: A, 1: B, 2: C, 3: D, 4: E, 5: F, 6: G, 7: H, 8: I}
656impl_reflect_tuple! {0: A, 1: B, 2: C, 3: D, 4: E, 5: F, 6: G, 7: H, 8: I, 9: J}
657impl_reflect_tuple! {0: A, 1: B, 2: C, 3: D, 4: E, 5: F, 6: G, 7: H, 8: I, 9: J, 10: K}
658impl_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}
659
660macro_rules! impl_type_path_tuple {
661 () => {
662 impl TypePath for () {
663 fn type_path() -> &'static str {
664 "()"
665 }
666
667 fn short_type_path() -> &'static str {
668 "()"
669 }
670 }
671 };
672
673 ($param:ident) => {
674 impl <$param: TypePath> TypePath for ($param,) {
675 fn type_path() -> &'static str {
676 static CELL: GenericTypePathCell = GenericTypePathCell::new();
677 CELL.get_or_insert::<Self, _>(|| {
678 "(".to_owned() + $param::type_path() + ",)"
679 })
680 }
681
682 fn short_type_path() -> &'static str {
683 static CELL: GenericTypePathCell = GenericTypePathCell::new();
684 CELL.get_or_insert::<Self, _>(|| {
685 "(".to_owned() + $param::short_type_path() + ",)"
686 })
687 }
688 }
689 };
690
691 ($last:ident $(,$param:ident)*) => {
692
693 impl <$($param: TypePath,)* $last: TypePath> TypePath for ($($param,)* $last) {
694 fn type_path() -> &'static str {
695 static CELL: GenericTypePathCell = GenericTypePathCell::new();
696 CELL.get_or_insert::<Self, _>(|| {
697 "(".to_owned() $(+ $param::type_path() + ", ")* + $last::type_path() + ")"
698 })
699 }
700
701 fn short_type_path() -> &'static str {
702 static CELL: GenericTypePathCell = GenericTypePathCell::new();
703 CELL.get_or_insert::<Self, _>(|| {
704 "(".to_owned() $(+ $param::short_type_path() + ", ")* + $last::short_type_path() + ")"
705 })
706 }
707 }
708 };
709}
710
711all_tuples!(impl_type_path_tuple, 0, 12, P);
712
713#[cfg(test)]
714mod tests {
715 use super::Tuple;
716
717 #[test]
718 fn next_index_increment() {
719 let mut iter = (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11).iter_fields();
720 let size = iter.len();
721 iter.index = size - 1;
722 let prev_index = iter.index;
723 assert!(iter.next().is_some());
724 assert_eq!(prev_index, iter.index - 1);
725
726 assert!(iter.next().is_none());
728 assert_eq!(size, iter.index);
729 assert!(iter.next().is_none());
730 assert_eq!(size, iter.index);
731 }
732}