use bevy_reflect_derive::impl_type_path; use smallvec::SmallVec; use std::any::Any; use crate::utility::GenericTypeInfoCell; use crate::{ self as bevy_reflect, FromReflect, FromType, GetTypeRegistration, List, ListInfo, ListIter, Reflect, ReflectFromPtr, ReflectKind, ReflectMut, ReflectOwned, ReflectRef, TypeInfo, TypePath, TypeRegistration, Typed, }; impl List for SmallVec where T::Item: FromReflect + TypePath, { fn get(&self, index: usize) -> Option<&dyn Reflect> { if index < SmallVec::len(self) { Some(&self[index] as &dyn Reflect) } else { None } } fn get_mut(&mut self, index: usize) -> Option<&mut dyn Reflect> { if index < SmallVec::len(self) { Some(&mut self[index] as &mut dyn Reflect) } else { None } } fn insert(&mut self, index: usize, value: Box) { let value = value.take::().unwrap_or_else(|value| { ::Item::from_reflect(&*value).unwrap_or_else(|| { panic!( "Attempted to insert invalid value of type {}.", value.reflect_type_path() ) }) }); SmallVec::insert(self, index, value); } fn remove(&mut self, index: usize) -> Box { Box::new(self.remove(index)) } fn push(&mut self, value: Box) { let value = value.take::().unwrap_or_else(|value| { ::Item::from_reflect(&*value).unwrap_or_else(|| { panic!( "Attempted to push invalid value of type {}.", value.reflect_type_path() ) }) }); SmallVec::push(self, value); } fn pop(&mut self) -> Option> { self.pop().map(|value| Box::new(value) as Box) } fn len(&self) -> usize { >::len(self) } fn iter(&self) -> ListIter { ListIter::new(self) } fn drain(self: Box) -> Vec> { self.into_iter() .map(|value| Box::new(value) as Box) .collect() } } impl Reflect for SmallVec where T::Item: FromReflect + TypePath, { fn get_represented_type_info(&self) -> Option<&'static TypeInfo> { Some(::type_info()) } fn into_any(self: Box) -> Box { self } fn as_any(&self) -> &dyn Any { self } fn as_any_mut(&mut self) -> &mut dyn Any { self } fn into_reflect(self: Box) -> Box { self } fn as_reflect(&self) -> &dyn Reflect { self } fn as_reflect_mut(&mut self) -> &mut dyn Reflect { self } fn apply(&mut self, value: &dyn Reflect) { crate::list_apply(self, value); } fn set(&mut self, value: Box) -> Result<(), Box> { *self = value.take()?; Ok(()) } fn reflect_kind(&self) -> ReflectKind { ReflectKind::List } fn reflect_ref(&self) -> ReflectRef { ReflectRef::List(self) } fn reflect_mut(&mut self) -> ReflectMut { ReflectMut::List(self) } fn reflect_owned(self: Box) -> ReflectOwned { ReflectOwned::List(self) } fn clone_value(&self) -> Box { Box::new(self.clone_dynamic()) } fn reflect_partial_eq(&self, value: &dyn Reflect) -> Option { crate::list_partial_eq(self, value) } } impl Typed for SmallVec where T::Item: FromReflect + TypePath, { fn type_info() -> &'static TypeInfo { static CELL: GenericTypeInfoCell = GenericTypeInfoCell::new(); CELL.get_or_insert::(|| TypeInfo::List(ListInfo::new::())) } } impl_type_path!(::smallvec::SmallVec); impl FromReflect for SmallVec where T::Item: FromReflect + TypePath, { fn from_reflect(reflect: &dyn Reflect) -> Option { if let ReflectRef::List(ref_list) = reflect.reflect_ref() { let mut new_list = Self::with_capacity(ref_list.len()); for field in ref_list.iter() { new_list.push(::Item::from_reflect(field)?); } Some(new_list) } else { None } } } impl GetTypeRegistration for SmallVec where T::Item: FromReflect + TypePath, { fn get_type_registration() -> TypeRegistration { let mut registration = TypeRegistration::of::>(); registration.insert::(FromType::>::from_type()); registration } }