bevy_reflect/impls/macros/
map.rs1macro_rules! impl_reflect_for_hashmap {
2 ($ty:path) => {
3 const _: () = {
4 impl<K, V, S> $crate::map::Map for $ty
5 where
6 K: $crate::from_reflect::FromReflect + $crate::type_info::MaybeTyped + $crate::type_path::TypePath + $crate::type_registry::GetTypeRegistration + Eq + core::hash::Hash,
7 V: $crate::from_reflect::FromReflect + $crate::type_info::MaybeTyped + $crate::type_path::TypePath + $crate::type_registry::GetTypeRegistration,
8 S: $crate::type_path::TypePath + core::hash::BuildHasher + Default + Send + Sync,
9 {
10 fn get(&self, key: &dyn $crate::reflect::PartialReflect) -> Option<&dyn $crate::reflect::PartialReflect> {
11 key.try_downcast_ref::<K>()
12 .and_then(|key| Self::get(self, key))
13 .map(|value| value as &dyn $crate::reflect::PartialReflect)
14 }
15
16 fn get_mut(&mut self, key: &dyn $crate::reflect::PartialReflect) -> Option<&mut dyn $crate::reflect::PartialReflect> {
17 key.try_downcast_ref::<K>()
18 .and_then(move |key| Self::get_mut(self, key))
19 .map(|value| value as &mut dyn $crate::reflect::PartialReflect)
20 }
21
22 fn len(&self) -> usize {
23 Self::len(self)
24 }
25
26 fn iter(&self) -> bevy_platform::prelude::Box<dyn Iterator<Item = (&dyn $crate::reflect::PartialReflect, &dyn $crate::reflect::PartialReflect)> + '_> {
27 bevy_platform::prelude::Box::new(self.iter().map(|(k, v)| (k as &dyn $crate::reflect::PartialReflect, v as &dyn $crate::reflect::PartialReflect)))
28 }
29
30 fn drain(&mut self) -> bevy_platform::prelude::Vec<(bevy_platform::prelude::Box<dyn $crate::reflect::PartialReflect>, bevy_platform::prelude::Box<dyn $crate::reflect::PartialReflect>)> {
31 self.drain()
32 .map(|(key, value)| {
33 (
34 bevy_platform::prelude::Box::new(key) as bevy_platform::prelude::Box<dyn $crate::reflect::PartialReflect>,
35 bevy_platform::prelude::Box::new(value) as bevy_platform::prelude::Box<dyn $crate::reflect::PartialReflect>,
36 )
37 })
38 .collect()
39 }
40
41 fn retain(&mut self, f: &mut dyn FnMut(&dyn $crate::reflect::PartialReflect, &mut dyn $crate::reflect::PartialReflect) -> bool) {
42 self.retain(move |key, value| f(key, value));
43 }
44
45 fn to_dynamic_map(&self) -> $crate::map::DynamicMap {
46 let mut dynamic_map = $crate::map::DynamicMap::default();
47 dynamic_map.set_represented_type($crate::reflect::PartialReflect::get_represented_type_info(self));
48 for (k, v) in self {
49 let key = K::from_reflect(k).unwrap_or_else(|| {
50 panic!(
51 "Attempted to clone invalid key of type {}.",
52 k.reflect_type_path()
53 )
54 });
55 dynamic_map.insert_boxed(bevy_platform::prelude::Box::new(key), v.to_dynamic());
56 }
57 dynamic_map
58 }
59
60 fn insert_boxed(
61 &mut self,
62 key: bevy_platform::prelude::Box<dyn $crate::reflect::PartialReflect>,
63 value: bevy_platform::prelude::Box<dyn $crate::reflect::PartialReflect>,
64 ) -> Option<bevy_platform::prelude::Box<dyn $crate::reflect::PartialReflect>> {
65 let key = K::take_from_reflect(key).unwrap_or_else(|key| {
66 panic!(
67 "Attempted to insert invalid key of type {}.",
68 key.reflect_type_path()
69 )
70 });
71 let value = V::take_from_reflect(value).unwrap_or_else(|value| {
72 panic!(
73 "Attempted to insert invalid value of type {}.",
74 value.reflect_type_path()
75 )
76 });
77 self.insert(key, value)
78 .map(|old_value| bevy_platform::prelude::Box::new(old_value) as bevy_platform::prelude::Box<dyn $crate::reflect::PartialReflect>)
79 }
80
81 fn remove(&mut self, key: &dyn $crate::reflect::PartialReflect) -> Option<bevy_platform::prelude::Box<dyn $crate::reflect::PartialReflect>> {
82 let mut from_reflect = None;
83 key.try_downcast_ref::<K>()
84 .or_else(|| {
85 from_reflect = K::from_reflect(key);
86 from_reflect.as_ref()
87 })
88 .and_then(|key| self.remove(key))
89 .map(|value| bevy_platform::prelude::Box::new(value) as bevy_platform::prelude::Box<dyn $crate::reflect::PartialReflect>)
90 }
91 }
92
93 impl<K, V, S> $crate::reflect::PartialReflect for $ty
94 where
95 K: $crate::from_reflect::FromReflect + $crate::type_info::MaybeTyped + $crate::type_path::TypePath + $crate::type_registry::GetTypeRegistration + Eq + core::hash::Hash,
96 V: $crate::from_reflect::FromReflect + $crate::type_info::MaybeTyped + $crate::type_path::TypePath + $crate::type_registry::GetTypeRegistration,
97 S: $crate::type_path::TypePath + core::hash::BuildHasher + Default + Send + Sync,
98 {
99 fn get_represented_type_info(&self) -> Option<&'static $crate::type_info::TypeInfo> {
100 Some(<Self as $crate::type_info::Typed>::type_info())
101 }
102
103 #[inline]
104 fn into_partial_reflect(self: bevy_platform::prelude::Box<Self>) -> bevy_platform::prelude::Box<dyn $crate::reflect::PartialReflect> {
105 self
106 }
107
108 fn as_partial_reflect(&self) -> &dyn $crate::reflect::PartialReflect {
109 self
110 }
111
112 fn as_partial_reflect_mut(&mut self) -> &mut dyn $crate::reflect::PartialReflect {
113 self
114 }
115
116 fn try_into_reflect(
117 self: bevy_platform::prelude::Box<Self>,
118 ) -> Result<bevy_platform::prelude::Box<dyn $crate::reflect::Reflect>, bevy_platform::prelude::Box<dyn $crate::reflect::PartialReflect>> {
119 Ok(self)
120 }
121
122 fn try_as_reflect(&self) -> Option<&dyn $crate::reflect::Reflect> {
123 Some(self)
124 }
125
126 fn try_as_reflect_mut(&mut self) -> Option<&mut dyn $crate::reflect::Reflect> {
127 Some(self)
128 }
129
130 fn reflect_kind(&self) -> $crate::kind::ReflectKind {
131 $crate::kind::ReflectKind::Map
132 }
133
134 fn reflect_ref(&self) -> $crate::kind::ReflectRef<'_> {
135 $crate::kind::ReflectRef::Map(self)
136 }
137
138 fn reflect_mut(&mut self) -> $crate::kind::ReflectMut<'_> {
139 $crate::kind::ReflectMut::Map(self)
140 }
141
142 fn reflect_owned(self: bevy_platform::prelude::Box<Self>) -> $crate::kind::ReflectOwned {
143 $crate::kind::ReflectOwned::Map(self)
144 }
145
146 fn reflect_clone(&self) -> Result<bevy_platform::prelude::Box<dyn $crate::reflect::Reflect>, $crate::error::ReflectCloneError> {
147 let mut map = Self::with_capacity_and_hasher(self.len(), S::default());
148 for (key, value) in self.iter() {
149 let key = key.reflect_clone_and_take()?;
150 let value = value.reflect_clone_and_take()?;
151 map.insert(key, value);
152 }
153
154 Ok(bevy_platform::prelude::Box::new(map))
155 }
156
157 fn reflect_partial_eq(&self, value: &dyn $crate::reflect::PartialReflect) -> Option<bool> {
158 $crate::map::map_partial_eq(self, value)
159 }
160
161 fn apply(&mut self, value: &dyn $crate::reflect::PartialReflect) {
162 $crate::map::map_apply(self, value);
163 }
164
165 fn try_apply(&mut self, value: &dyn $crate::reflect::PartialReflect) -> Result<(), $crate::reflect::ApplyError> {
166 $crate::map::map_try_apply(self, value)
167 }
168 }
169
170 $crate::impl_full_reflect!(
171 <K, V, S> for $ty
172 where
173 K: $crate::from_reflect::FromReflect + $crate::type_info::MaybeTyped + $crate::type_path::TypePath + $crate::type_registry::GetTypeRegistration + Eq + core::hash::Hash,
174 V: $crate::from_reflect::FromReflect + $crate::type_info::MaybeTyped + $crate::type_path::TypePath + $crate::type_registry::GetTypeRegistration,
175 S: $crate::type_path::TypePath + core::hash::BuildHasher + Default + Send + Sync,
176 );
177
178 impl<K, V, S> $crate::type_info::Typed for $ty
179 where
180 K: $crate::from_reflect::FromReflect + $crate::type_info::MaybeTyped + $crate::type_path::TypePath + $crate::type_registry::GetTypeRegistration + Eq + core::hash::Hash,
181 V: $crate::from_reflect::FromReflect + $crate::type_info::MaybeTyped + $crate::type_path::TypePath + $crate::type_registry::GetTypeRegistration,
182 S: $crate::type_path::TypePath + core::hash::BuildHasher + Default + Send + Sync,
183 {
184 fn type_info() -> &'static $crate::type_info::TypeInfo {
185 static CELL: $crate::utility::GenericTypeInfoCell = $crate::utility::GenericTypeInfoCell::new();
186 CELL.get_or_insert::<Self, _>(|| {
187 $crate::type_info::TypeInfo::Map(
188 $crate::map::MapInfo::new::<Self, K, V>().with_generics($crate::generics::Generics::from_iter([
189 $crate::generics::TypeParamInfo::new::<K>("K"),
190 $crate::generics::TypeParamInfo::new::<V>("V"),
191 ])),
192 )
193 })
194 }
195 }
196
197 impl<K, V, S> $crate::type_registry::GetTypeRegistration for $ty
198 where
199 K: $crate::from_reflect::FromReflect + $crate::type_info::MaybeTyped + $crate::type_path::TypePath + $crate::type_registry::GetTypeRegistration + Eq + core::hash::Hash,
200 V: $crate::from_reflect::FromReflect + $crate::type_info::MaybeTyped + $crate::type_path::TypePath + $crate::type_registry::GetTypeRegistration,
201 S: $crate::type_path::TypePath + core::hash::BuildHasher + Default + Send + Sync + Default,
202 {
203 fn get_type_registration() -> $crate::type_registry::TypeRegistration {
204 let mut registration = $crate::type_registry::TypeRegistration::of::<Self>();
205 registration.insert::<$crate::type_registry::ReflectFromPtr>($crate::type_registry::FromType::<Self>::from_type());
206 registration.insert::<$crate::from_reflect::ReflectFromReflect>($crate::type_registry::FromType::<Self>::from_type());
207 registration
208 }
209
210 fn register_type_dependencies(registry: &mut $crate::type_registry::TypeRegistry) {
211 registry.register::<K>();
212 registry.register::<V>();
213 }
214 }
215
216 impl<K, V, S> $crate::from_reflect::FromReflect for $ty
217 where
218 K: $crate::from_reflect::FromReflect + $crate::type_info::MaybeTyped + $crate::type_path::TypePath + $crate::type_registry::GetTypeRegistration + Eq + core::hash::Hash,
219 V: $crate::from_reflect::FromReflect + $crate::type_info::MaybeTyped + $crate::type_path::TypePath + $crate::type_registry::GetTypeRegistration,
220 S: $crate::type_path::TypePath + core::hash::BuildHasher + Default + Send + Sync,
221 {
222 fn from_reflect(reflect: &dyn $crate::reflect::PartialReflect) -> Option<Self> {
223 let ref_map = reflect.reflect_ref().as_map().ok()?;
224
225 let mut new_map = Self::with_capacity_and_hasher(ref_map.len(), S::default());
226
227 for (key, value) in ref_map.iter() {
228 let new_key = K::from_reflect(key)?;
229 let new_value = V::from_reflect(value)?;
230 new_map.insert(new_key, new_value);
231 }
232
233 Some(new_map)
234 }
235 }
236 };
237 };
238}
239
240pub(crate) use impl_reflect_for_hashmap;