1use crate::component::Component;
2use crate::entity_id::EntityId;
3use crate::error;
4use crate::r#mut::Mut;
5use crate::sparse_set::SparseSet;
6use crate::tracking::Tracking;
7use crate::views::{View, ViewMut};
8use core::any::type_name;
9
10pub trait Get {
12 #[allow(missing_docs)]
13 type Out;
14 fn get(self, entity: EntityId) -> Result<Self::Out, error::MissingComponent>;
36}
37
38impl<'a, T: Component> Get for &'a SparseSet<T> {
39 type Out = &'a T;
40
41 fn get(self, entity: EntityId) -> Result<Self::Out, error::MissingComponent> {
42 self.private_get(entity)
43 .ok_or_else(|| error::MissingComponent {
44 id: entity,
45 name: type_name::<T>(),
46 })
47 }
48}
49
50impl<'a, 'b, T: Component, Track: Tracking> Get for &'b View<'a, T, Track> {
51 type Out = &'b T;
52
53 #[inline]
54 fn get(self, entity: EntityId) -> Result<Self::Out, error::MissingComponent> {
55 (**self)
56 .private_get(entity)
57 .ok_or_else(|| error::MissingComponent {
58 id: entity,
59 name: type_name::<T>(),
60 })
61 }
62}
63
64impl<'a, 'b, T: Component, Track: Tracking> Get for &'b ViewMut<'a, T, Track> {
65 type Out = &'b T;
66
67 #[inline]
68 fn get(self, entity: EntityId) -> Result<Self::Out, error::MissingComponent> {
69 (**self)
70 .private_get(entity)
71 .ok_or_else(|| error::MissingComponent {
72 id: entity,
73 name: type_name::<T>(),
74 })
75 }
76}
77
78impl<'a, 'b, T: Component, Track: Tracking> Get for &'b mut ViewMut<'a, T, Track> {
79 type Out = Mut<'b, T>;
80
81 #[inline]
82 fn get(self, entity: EntityId) -> Result<Self::Out, error::MissingComponent> {
83 let index = self
84 .index_of(entity)
85 .ok_or_else(|| error::MissingComponent {
86 id: entity,
87 name: type_name::<T>(),
88 })?;
89
90 let SparseSet {
91 data,
92 modification_data,
93 is_tracking_modification,
94 ..
95 } = self.sparse_set;
96
97 Ok(Mut {
98 flag: is_tracking_modification
99 .then(|| unsafe { modification_data.get_unchecked_mut(index) }),
100 current: self.current,
101 data: unsafe { data.get_unchecked_mut(index) },
102 })
103 }
104}
105
106macro_rules! impl_get_component {
107 ($(($type: ident, $index: tt))+) => {
108 impl<$($type: Get),+> Get for ($($type,)+) {
109 type Out = ($($type::Out,)+);
110 #[inline]
111 fn get(self, entity: EntityId) -> Result<Self::Out, error::MissingComponent> {
112 Ok(($(self.$index.get(entity)?,)+))
113 }
114 }
115 }
116}
117
118macro_rules! get_component {
119 ($(($type: ident, $index: tt))+; ($type1: ident, $index1: tt) $(($queue_type: ident, $queue_index: tt))*) => {
120 impl_get_component![$(($type, $index))*];
121 get_component![$(($type, $index))* ($type1, $index1); $(($queue_type, $queue_index))*];
122 };
123 ($(($type: ident, $index: tt))+;) => {
124 impl_get_component![$(($type, $index))*];
125 }
126}
127
128#[cfg(not(feature = "extended_tuple"))]
129get_component![(ViewA, 0); (ViewB, 1) (ViewC, 2) (ViewD, 3) (ViewE, 4) (ViewF, 5) (ViewG, 6) (ViewH, 7) (ViewI, 8) (ViewJ, 9)];
130#[cfg(feature = "extended_tuple")]
131get_component![
132 (ViewA, 0); (ViewB, 1) (ViewC, 2) (ViewD, 3) (ViewE, 4) (ViewF, 5) (ViewG, 6) (ViewH, 7) (ViewI, 8) (ViewJ, 9)
133 (ViewK, 10) (ViewL, 11) (ViewM, 12) (ViewN, 13) (ViewO, 14) (ViewP, 15) (ViewQ, 16) (ViewR, 17) (ViewS, 18) (ViewT, 19)
134 (ViewU, 20) (ViewV, 21) (ViewW, 22) (ViewX, 23) (ViewY, 24) (ViewZ, 25) (ViewAA, 26) (ViewBB, 27) (ViewCC, 28) (ViewDD, 29)
135 (ViewEE, 30) (ViewFF, 31)
136];