bevy_reflect/impls/
smallvec.rs

1use bevy_reflect_derive::impl_type_path;
2use smallvec::SmallVec;
3
4use std::any::Any;
5
6use crate::utility::GenericTypeInfoCell;
7use crate::{
8    self as bevy_reflect, ApplyError, FromReflect, FromType, GetTypeRegistration, List, ListInfo,
9    ListIter, Reflect, ReflectFromPtr, ReflectKind, ReflectMut, ReflectOwned, ReflectRef, TypeInfo,
10    TypePath, TypeRegistration, Typed,
11};
12
13impl<T: smallvec::Array + TypePath + Send + Sync> List for SmallVec<T>
14where
15    T::Item: FromReflect + TypePath,
16{
17    fn get(&self, index: usize) -> Option<&dyn Reflect> {
18        if index < SmallVec::len(self) {
19            Some(&self[index] as &dyn Reflect)
20        } else {
21            None
22        }
23    }
24
25    fn get_mut(&mut self, index: usize) -> Option<&mut dyn Reflect> {
26        if index < SmallVec::len(self) {
27            Some(&mut self[index] as &mut dyn Reflect)
28        } else {
29            None
30        }
31    }
32
33    fn insert(&mut self, index: usize, value: Box<dyn Reflect>) {
34        let value = value.take::<T::Item>().unwrap_or_else(|value| {
35            <T as smallvec::Array>::Item::from_reflect(&*value).unwrap_or_else(|| {
36                panic!(
37                    "Attempted to insert invalid value of type {}.",
38                    value.reflect_type_path()
39                )
40            })
41        });
42        SmallVec::insert(self, index, value);
43    }
44
45    fn remove(&mut self, index: usize) -> Box<dyn Reflect> {
46        Box::new(self.remove(index))
47    }
48
49    fn push(&mut self, value: Box<dyn Reflect>) {
50        let value = value.take::<T::Item>().unwrap_or_else(|value| {
51            <T as smallvec::Array>::Item::from_reflect(&*value).unwrap_or_else(|| {
52                panic!(
53                    "Attempted to push invalid value of type {}.",
54                    value.reflect_type_path()
55                )
56            })
57        });
58        SmallVec::push(self, value);
59    }
60
61    fn pop(&mut self) -> Option<Box<dyn Reflect>> {
62        self.pop().map(|value| Box::new(value) as Box<dyn Reflect>)
63    }
64
65    fn len(&self) -> usize {
66        <SmallVec<T>>::len(self)
67    }
68
69    fn iter(&self) -> ListIter {
70        ListIter::new(self)
71    }
72
73    fn drain(self: Box<Self>) -> Vec<Box<dyn Reflect>> {
74        self.into_iter()
75            .map(|value| Box::new(value) as Box<dyn Reflect>)
76            .collect()
77    }
78}
79
80impl<T: smallvec::Array + TypePath + Send + Sync> Reflect for SmallVec<T>
81where
82    T::Item: FromReflect + TypePath,
83{
84    fn get_represented_type_info(&self) -> Option<&'static TypeInfo> {
85        Some(<Self as Typed>::type_info())
86    }
87
88    fn into_any(self: Box<Self>) -> Box<dyn Any> {
89        self
90    }
91
92    fn as_any(&self) -> &dyn Any {
93        self
94    }
95
96    fn as_any_mut(&mut self) -> &mut dyn Any {
97        self
98    }
99
100    fn into_reflect(self: Box<Self>) -> Box<dyn Reflect> {
101        self
102    }
103
104    fn as_reflect(&self) -> &dyn Reflect {
105        self
106    }
107
108    fn as_reflect_mut(&mut self) -> &mut dyn Reflect {
109        self
110    }
111
112    fn apply(&mut self, value: &dyn Reflect) {
113        crate::list_apply(self, value);
114    }
115
116    fn try_apply(&mut self, value: &dyn Reflect) -> Result<(), ApplyError> {
117        crate::list_try_apply(self, value)
118    }
119
120    fn set(&mut self, value: Box<dyn Reflect>) -> Result<(), Box<dyn Reflect>> {
121        *self = value.take()?;
122        Ok(())
123    }
124
125    fn reflect_kind(&self) -> ReflectKind {
126        ReflectKind::List
127    }
128
129    fn reflect_ref(&self) -> ReflectRef {
130        ReflectRef::List(self)
131    }
132
133    fn reflect_mut(&mut self) -> ReflectMut {
134        ReflectMut::List(self)
135    }
136
137    fn reflect_owned(self: Box<Self>) -> ReflectOwned {
138        ReflectOwned::List(self)
139    }
140
141    fn clone_value(&self) -> Box<dyn Reflect> {
142        Box::new(self.clone_dynamic())
143    }
144
145    fn reflect_partial_eq(&self, value: &dyn Reflect) -> Option<bool> {
146        crate::list_partial_eq(self, value)
147    }
148}
149
150impl<T: smallvec::Array + TypePath + Send + Sync + 'static> Typed for SmallVec<T>
151where
152    T::Item: FromReflect + TypePath,
153{
154    fn type_info() -> &'static TypeInfo {
155        static CELL: GenericTypeInfoCell = GenericTypeInfoCell::new();
156        CELL.get_or_insert::<Self, _>(|| TypeInfo::List(ListInfo::new::<Self, T::Item>()))
157    }
158}
159
160impl_type_path!(::smallvec::SmallVec<T: smallvec::Array>);
161
162impl<T: smallvec::Array + TypePath + Send + Sync> FromReflect for SmallVec<T>
163where
164    T::Item: FromReflect + TypePath,
165{
166    fn from_reflect(reflect: &dyn Reflect) -> Option<Self> {
167        if let ReflectRef::List(ref_list) = reflect.reflect_ref() {
168            let mut new_list = Self::with_capacity(ref_list.len());
169            for field in ref_list.iter() {
170                new_list.push(<T as smallvec::Array>::Item::from_reflect(field)?);
171            }
172            Some(new_list)
173        } else {
174            None
175        }
176    }
177}
178
179impl<T: smallvec::Array + TypePath + Send + Sync> GetTypeRegistration for SmallVec<T>
180where
181    T::Item: FromReflect + TypePath,
182{
183    fn get_type_registration() -> TypeRegistration {
184        let mut registration = TypeRegistration::of::<SmallVec<T>>();
185        registration.insert::<ReflectFromPtr>(FromType::<SmallVec<T>>::from_type());
186        registration
187    }
188}