diff --git a/crates/bevy_reflect/src/impls/std.rs b/crates/bevy_reflect/src/impls/std.rs index e54a59efb2680..ca7ad9c8710e9 100644 --- a/crates/bevy_reflect/src/impls/std.rs +++ b/crates/bevy_reflect/src/impls/std.rs @@ -15,6 +15,7 @@ use bevy_utils::{HashMap, HashSet}; use std::{ any::Any, borrow::Cow, + collections::VecDeque, ffi::OsString, hash::{Hash, Hasher}, num::{ @@ -177,152 +178,164 @@ impl_from_reflect_value!(NonZeroU16); impl_from_reflect_value!(NonZeroU8); impl_from_reflect_value!(NonZeroI8); -impl Array for Vec { - #[inline] - fn get(&self, index: usize) -> Option<&dyn Reflect> { - <[T]>::get(self, index).map(|value| value as &dyn Reflect) - } +macro_rules! impl_reflect_for_veclike { + ($ty:ty, $push:expr, $pop:expr, $sub:ty) => { + impl Array for $ty { + #[inline] + fn get(&self, index: usize) -> Option<&dyn Reflect> { + <$sub>::get(self, index).map(|value| value as &dyn Reflect) + } - #[inline] - fn get_mut(&mut self, index: usize) -> Option<&mut dyn Reflect> { - <[T]>::get_mut(self, index).map(|value| value as &mut dyn Reflect) - } + #[inline] + fn get_mut(&mut self, index: usize) -> Option<&mut dyn Reflect> { + <$sub>::get_mut(self, index).map(|value| value as &mut dyn Reflect) + } - #[inline] - fn len(&self) -> usize { - <[T]>::len(self) - } + #[inline] + fn len(&self) -> usize { + <$sub>::len(self) + } - #[inline] - fn iter(&self) -> ArrayIter { - ArrayIter { - array: self, - index: 0, - } - } + #[inline] + fn iter(&self) -> ArrayIter { + ArrayIter { + array: self, + index: 0, + } + } - #[inline] - fn drain(self: Box) -> Vec> { - self.into_iter() - .map(|value| Box::new(value) as Box) - .collect() - } -} + #[inline] + fn drain(self: Box) -> Vec> { + self.into_iter() + .map(|value| Box::new(value) as Box) + .collect() + } + } -impl List for Vec { - fn push(&mut self, value: Box) { - let value = value.take::().unwrap_or_else(|value| { - T::from_reflect(&*value).unwrap_or_else(|| { - panic!( - "Attempted to push invalid value of type {}.", - value.type_name() - ) - }) - }); - Vec::push(self, value); - } + impl List for $ty { + fn push(&mut self, value: Box) { + let value = value.take::().unwrap_or_else(|value| { + T::from_reflect(&*value).unwrap_or_else(|| { + panic!( + "Attempted to push invalid value of type {}.", + value.type_name() + ) + }) + }); + $push(self, value); + } - fn pop(&mut self) -> Option> { - self.pop().map(|value| Box::new(value) as Box) - } -} + fn pop(&mut self) -> Option> { + $pop(self).map(|value| Box::new(value) as Box) + } + } -impl Reflect for Vec { - fn type_name(&self) -> &str { - std::any::type_name::() - } + impl Reflect for $ty { + fn type_name(&self) -> &str { + std::any::type_name::() + } - fn get_type_info(&self) -> &'static TypeInfo { - ::type_info() - } + fn get_type_info(&self) -> &'static TypeInfo { + ::type_info() + } - fn into_any(self: Box) -> Box { - self - } + fn into_any(self: Box) -> Box { + self + } - fn as_any(&self) -> &dyn Any { - self - } + fn as_any(&self) -> &dyn Any { + self + } - fn as_any_mut(&mut self) -> &mut dyn Any { - self - } + fn as_any_mut(&mut self) -> &mut dyn Any { + self + } - fn into_reflect(self: Box) -> Box { - self - } + fn into_reflect(self: Box) -> Box { + self + } - fn as_reflect(&self) -> &dyn Reflect { - self - } + fn as_reflect(&self) -> &dyn Reflect { + self + } - fn as_reflect_mut(&mut self) -> &mut 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 apply(&mut self, value: &dyn Reflect) { + crate::list_apply(self, value); + } - fn set(&mut self, value: Box) -> Result<(), Box> { - *self = value.take()?; - Ok(()) - } + fn set(&mut self, value: Box) -> Result<(), Box> { + *self = value.take()?; + Ok(()) + } - fn reflect_ref(&self) -> ReflectRef { - ReflectRef::List(self) - } + fn reflect_ref(&self) -> ReflectRef { + ReflectRef::List(self) + } - fn reflect_mut(&mut self) -> ReflectMut { - ReflectMut::List(self) - } + fn reflect_mut(&mut self) -> ReflectMut { + ReflectMut::List(self) + } - fn reflect_owned(self: Box) -> ReflectOwned { - ReflectOwned::List(self) - } + fn reflect_owned(self: Box) -> ReflectOwned { + ReflectOwned::List(self) + } - fn clone_value(&self) -> Box { - Box::new(List::clone_dynamic(self)) - } + fn clone_value(&self) -> Box { + Box::new(List::clone_dynamic(self)) + } - fn reflect_hash(&self) -> Option { - crate::array_hash(self) - } + fn reflect_hash(&self) -> Option { + crate::array_hash(self) + } - fn reflect_partial_eq(&self, value: &dyn Reflect) -> Option { - crate::list_partial_eq(self, value) - } -} + fn reflect_partial_eq(&self, value: &dyn Reflect) -> Option { + crate::list_partial_eq(self, value) + } + } -impl Typed for Vec { - fn type_info() -> &'static TypeInfo { - static CELL: GenericTypeInfoCell = GenericTypeInfoCell::new(); - CELL.get_or_insert::(|| TypeInfo::List(ListInfo::new::())) - } -} + impl Typed for $ty { + fn type_info() -> &'static TypeInfo { + static CELL: GenericTypeInfoCell = GenericTypeInfoCell::new(); + CELL.get_or_insert::(|| TypeInfo::List(ListInfo::new::())) + } + } -impl GetTypeRegistration for Vec { - fn get_type_registration() -> TypeRegistration { - let mut registration = TypeRegistration::of::>(); - registration.insert::(FromType::>::from_type()); - registration - } -} + impl GetTypeRegistration for $ty { + fn get_type_registration() -> TypeRegistration { + let mut registration = TypeRegistration::of::>(); + registration.insert::(FromType::>::from_type()); + registration + } + } -impl FromReflect for Vec { - 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(T::from_reflect(field)?); + impl FromReflect for $ty { + 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() { + $push(&mut new_list, T::from_reflect(field)?); + } + Some(new_list) + } else { + None + } } - Some(new_list) - } else { - None } - } + }; } +impl_reflect_for_veclike!(Vec, Vec::push, Vec::pop, [T]); +impl_reflect_for_veclike!( + VecDeque, + VecDeque::push_back, + VecDeque::pop_back, + VecDeque:: +); + impl Map for HashMap { fn get(&self, key: &dyn Reflect) -> Option<&dyn Reflect> { key.downcast_ref::()