1use std::any::{Any, TypeId};
2use std::fmt::{Debug, Formatter};
3use std::hash::{Hash, Hasher};
4
5use bevy_reflect_derive::impl_type_path;
6
7use crate::utility::reflect_hasher;
8use crate::{
9 self as bevy_reflect, ApplyError, FromReflect, Reflect, ReflectKind, ReflectMut, ReflectOwned,
10 ReflectRef, TypeInfo, TypePath, TypePathTable,
11};
12
13pub trait List: Reflect {
51 fn get(&self, index: usize) -> Option<&dyn Reflect>;
53
54 fn get_mut(&mut self, index: usize) -> Option<&mut dyn Reflect>;
56
57 fn insert(&mut self, index: usize, element: Box<dyn Reflect>);
63
64 fn remove(&mut self, index: usize) -> Box<dyn Reflect>;
70
71 fn push(&mut self, value: Box<dyn Reflect>) {
73 self.insert(self.len(), value);
74 }
75
76 fn pop(&mut self) -> Option<Box<dyn Reflect>> {
78 if self.is_empty() {
79 None
80 } else {
81 Some(self.remove(self.len() - 1))
82 }
83 }
84
85 fn len(&self) -> usize;
87
88 fn is_empty(&self) -> bool {
90 self.len() == 0
91 }
92
93 fn iter(&self) -> ListIter;
95
96 fn drain(self: Box<Self>) -> Vec<Box<dyn Reflect>>;
98
99 fn clone_dynamic(&self) -> DynamicList {
101 DynamicList {
102 represented_type: self.get_represented_type_info(),
103 values: self.iter().map(|value| value.clone_value()).collect(),
104 }
105 }
106}
107
108#[derive(Clone, Debug)]
110pub struct ListInfo {
111 type_path: TypePathTable,
112 type_id: TypeId,
113 item_type_path: TypePathTable,
114 item_type_id: TypeId,
115 #[cfg(feature = "documentation")]
116 docs: Option<&'static str>,
117}
118
119impl ListInfo {
120 pub fn new<TList: List + TypePath, TItem: FromReflect + TypePath>() -> Self {
122 Self {
123 type_path: TypePathTable::of::<TList>(),
124 type_id: TypeId::of::<TList>(),
125 item_type_path: TypePathTable::of::<TItem>(),
126 item_type_id: TypeId::of::<TItem>(),
127 #[cfg(feature = "documentation")]
128 docs: None,
129 }
130 }
131
132 #[cfg(feature = "documentation")]
134 pub fn with_docs(self, docs: Option<&'static str>) -> Self {
135 Self { docs, ..self }
136 }
137
138 pub fn type_path_table(&self) -> &TypePathTable {
142 &self.type_path
143 }
144
145 pub fn type_path(&self) -> &'static str {
152 self.type_path_table().path()
153 }
154
155 pub fn type_id(&self) -> TypeId {
157 self.type_id
158 }
159
160 pub fn is<T: Any>(&self) -> bool {
162 TypeId::of::<T>() == self.type_id
163 }
164
165 pub fn item_type_path_table(&self) -> &TypePathTable {
169 &self.item_type_path
170 }
171
172 pub fn item_type_id(&self) -> TypeId {
174 self.item_type_id
175 }
176
177 pub fn item_is<T: Any>(&self) -> bool {
179 TypeId::of::<T>() == self.item_type_id
180 }
181
182 #[cfg(feature = "documentation")]
184 pub fn docs(&self) -> Option<&'static str> {
185 self.docs
186 }
187}
188
189#[derive(Default)]
191pub struct DynamicList {
192 represented_type: Option<&'static TypeInfo>,
193 values: Vec<Box<dyn Reflect>>,
194}
195
196impl DynamicList {
197 pub fn set_represented_type(&mut self, represented_type: Option<&'static TypeInfo>) {
204 if let Some(represented_type) = represented_type {
205 assert!(
206 matches!(represented_type, TypeInfo::List(_)),
207 "expected TypeInfo::List but received: {:?}",
208 represented_type
209 );
210 }
211
212 self.represented_type = represented_type;
213 }
214
215 pub fn push<T: Reflect>(&mut self, value: T) {
217 self.values.push(Box::new(value));
218 }
219
220 pub fn push_box(&mut self, value: Box<dyn Reflect>) {
222 self.values.push(value);
223 }
224}
225
226impl List for DynamicList {
227 fn get(&self, index: usize) -> Option<&dyn Reflect> {
228 self.values.get(index).map(|value| &**value)
229 }
230
231 fn get_mut(&mut self, index: usize) -> Option<&mut dyn Reflect> {
232 self.values.get_mut(index).map(|value| &mut **value)
233 }
234
235 fn insert(&mut self, index: usize, element: Box<dyn Reflect>) {
236 self.values.insert(index, element);
237 }
238
239 fn remove(&mut self, index: usize) -> Box<dyn Reflect> {
240 self.values.remove(index)
241 }
242
243 fn push(&mut self, value: Box<dyn Reflect>) {
244 DynamicList::push_box(self, value);
245 }
246
247 fn pop(&mut self) -> Option<Box<dyn Reflect>> {
248 self.values.pop()
249 }
250
251 fn len(&self) -> usize {
252 self.values.len()
253 }
254
255 fn iter(&self) -> ListIter {
256 ListIter::new(self)
257 }
258
259 fn drain(self: Box<Self>) -> Vec<Box<dyn Reflect>> {
260 self.values
261 }
262
263 fn clone_dynamic(&self) -> DynamicList {
264 DynamicList {
265 represented_type: self.represented_type,
266 values: self
267 .values
268 .iter()
269 .map(|value| value.clone_value())
270 .collect(),
271 }
272 }
273}
274
275impl Reflect for DynamicList {
276 #[inline]
277 fn get_represented_type_info(&self) -> Option<&'static TypeInfo> {
278 self.represented_type
279 }
280
281 #[inline]
282 fn into_any(self: Box<Self>) -> Box<dyn Any> {
283 self
284 }
285
286 #[inline]
287 fn as_any(&self) -> &dyn Any {
288 self
289 }
290
291 #[inline]
292 fn as_any_mut(&mut self) -> &mut dyn Any {
293 self
294 }
295
296 #[inline]
297 fn into_reflect(self: Box<Self>) -> Box<dyn Reflect> {
298 self
299 }
300
301 #[inline]
302 fn as_reflect(&self) -> &dyn Reflect {
303 self
304 }
305
306 #[inline]
307 fn as_reflect_mut(&mut self) -> &mut dyn Reflect {
308 self
309 }
310
311 fn apply(&mut self, value: &dyn Reflect) {
312 list_apply(self, value);
313 }
314
315 fn try_apply(&mut self, value: &dyn Reflect) -> Result<(), ApplyError> {
316 list_try_apply(self, value)
317 }
318
319 #[inline]
320 fn set(&mut self, value: Box<dyn Reflect>) -> Result<(), Box<dyn Reflect>> {
321 *self = value.take()?;
322 Ok(())
323 }
324
325 #[inline]
326 fn reflect_kind(&self) -> ReflectKind {
327 ReflectKind::List
328 }
329
330 #[inline]
331 fn reflect_ref(&self) -> ReflectRef {
332 ReflectRef::List(self)
333 }
334
335 #[inline]
336 fn reflect_mut(&mut self) -> ReflectMut {
337 ReflectMut::List(self)
338 }
339
340 #[inline]
341 fn reflect_owned(self: Box<Self>) -> ReflectOwned {
342 ReflectOwned::List(self)
343 }
344
345 #[inline]
346 fn clone_value(&self) -> Box<dyn Reflect> {
347 Box::new(self.clone_dynamic())
348 }
349
350 #[inline]
351 fn reflect_hash(&self) -> Option<u64> {
352 list_hash(self)
353 }
354
355 fn reflect_partial_eq(&self, value: &dyn Reflect) -> Option<bool> {
356 list_partial_eq(self, value)
357 }
358
359 fn debug(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
360 write!(f, "DynamicList(")?;
361 list_debug(self, f)?;
362 write!(f, ")")
363 }
364
365 #[inline]
366 fn is_dynamic(&self) -> bool {
367 true
368 }
369}
370
371impl_type_path!((in bevy_reflect) DynamicList);
372
373impl Debug for DynamicList {
374 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
375 self.debug(f)
376 }
377}
378
379impl IntoIterator for DynamicList {
380 type Item = Box<dyn Reflect>;
381 type IntoIter = std::vec::IntoIter<Self::Item>;
382
383 fn into_iter(self) -> Self::IntoIter {
384 self.values.into_iter()
385 }
386}
387
388pub struct ListIter<'a> {
390 list: &'a dyn List,
391 index: usize,
392}
393
394impl<'a> ListIter<'a> {
395 #[inline]
397 pub const fn new(list: &'a dyn List) -> ListIter {
398 ListIter { list, index: 0 }
399 }
400}
401
402impl<'a> Iterator for ListIter<'a> {
403 type Item = &'a dyn Reflect;
404
405 #[inline]
406 fn next(&mut self) -> Option<Self::Item> {
407 let value = self.list.get(self.index);
408 self.index += value.is_some() as usize;
409 value
410 }
411
412 #[inline]
413 fn size_hint(&self) -> (usize, Option<usize>) {
414 let size = self.list.len();
415 (size, Some(size))
416 }
417}
418
419impl<'a> ExactSizeIterator for ListIter<'a> {}
420
421#[inline]
423pub fn list_hash<L: List>(list: &L) -> Option<u64> {
424 let mut hasher = reflect_hasher();
425 Any::type_id(list).hash(&mut hasher);
426 list.len().hash(&mut hasher);
427 for value in list.iter() {
428 hasher.write_u64(value.reflect_hash()?);
429 }
430 Some(hasher.finish())
431}
432
433#[inline]
442pub fn list_apply<L: List>(a: &mut L, b: &dyn Reflect) {
443 if let Err(err) = list_try_apply(a, b) {
444 panic!("{err}");
445 }
446}
447
448#[inline]
459pub fn list_try_apply<L: List>(a: &mut L, b: &dyn Reflect) -> Result<(), ApplyError> {
460 if let ReflectRef::List(list_value) = b.reflect_ref() {
461 for (i, value) in list_value.iter().enumerate() {
462 if i < a.len() {
463 if let Some(v) = a.get_mut(i) {
464 v.try_apply(value)?;
465 }
466 } else {
467 List::push(a, value.clone_value());
468 }
469 }
470 } else {
471 return Err(ApplyError::MismatchedKinds {
472 from_kind: b.reflect_kind(),
473 to_kind: ReflectKind::List,
474 });
475 }
476 Ok(())
477}
478
479#[inline]
488pub fn list_partial_eq<L: List>(a: &L, b: &dyn Reflect) -> Option<bool> {
489 let ReflectRef::List(list) = b.reflect_ref() else {
490 return Some(false);
491 };
492
493 if a.len() != list.len() {
494 return Some(false);
495 }
496
497 for (a_value, b_value) in a.iter().zip(list.iter()) {
498 let eq_result = a_value.reflect_partial_eq(b_value);
499 if let failed @ (Some(false) | None) = eq_result {
500 return failed;
501 }
502 }
503
504 Some(true)
505}
506
507#[inline]
525pub fn list_debug(dyn_list: &dyn List, f: &mut Formatter<'_>) -> std::fmt::Result {
526 let mut debug = f.debug_list();
527 for item in dyn_list.iter() {
528 debug.entry(&item as &dyn Debug);
529 }
530 debug.finish()
531}
532
533#[cfg(test)]
534mod tests {
535 use super::DynamicList;
536 use crate::{Reflect, ReflectRef};
537 use std::assert_eq;
538
539 #[test]
540 fn test_into_iter() {
541 let mut list = DynamicList::default();
542 list.push(0usize);
543 list.push(1usize);
544 list.push(2usize);
545 let items = list.into_iter();
546 for (index, item) in items.into_iter().enumerate() {
547 let value = item.take::<usize>().expect("couldn't downcast to usize");
548 assert_eq!(index, value);
549 }
550 }
551
552 #[test]
553 fn next_index_increment() {
554 const SIZE: usize = if cfg!(debug_assertions) {
555 4
556 } else {
557 usize::MAX
559 };
560 let b = Box::new(vec![(); SIZE]).into_reflect();
561
562 let ReflectRef::List(list) = b.reflect_ref() else {
563 panic!("Not a list...");
564 };
565
566 let mut iter = list.iter();
567 iter.index = SIZE - 1;
568 assert!(iter.next().is_some());
569
570 assert!(iter.next().is_none());
572 assert!(iter.index == SIZE);
573 assert!(iter.next().is_none());
574 assert!(iter.index == SIZE);
575 }
576}