bevy_reflect/impls/
smallvec.rs1use 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}