Skip to main content

fyrox_core/reflect/
std_impls.rs

1// Copyright (c) 2019-present Dmitry Stepanov and Fyrox Engine contributors.
2//
3// Permission is hereby granted, free of charge, to any person obtaining a copy
4// of this software and associated documentation files (the "Software"), to deal
5// in the Software without restriction, including without limitation the rights
6// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7// copies of the Software, and to permit persons to whom the Software is
8// furnished to do so, subject to the following conditions:
9//
10// The above copyright notice and this permission notice shall be included in all
11// copies or substantial portions of the Software.
12//
13// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19// SOFTWARE.
20
21//! `Reflect` implementations for `std` types
22
23use crate::{
24    delegate_reflect,
25    reflect::{blank_reflect, prelude::*},
26    sstorage::ImmutableString,
27    uuid::Uuid,
28    SafeLock,
29};
30use fyrox_core_derive::impl_reflect;
31use std::{
32    any::Any,
33    cell::{Cell, RefCell},
34    collections::HashMap,
35    fmt::Debug,
36    hash::{BuildHasher, Hash},
37    ops::{Deref, DerefMut, Range},
38    rc::Rc,
39    sync::Arc,
40    time::{Duration, Instant},
41};
42
43macro_rules! impl_blank_reflect {
44    ( $( $ty:ty ),* $(,)? ) => {
45        $(
46            impl Reflect for $ty {
47                blank_reflect!();
48            }
49        )*
50    }
51}
52
53impl_blank_reflect! {
54    f32, f64,
55    usize, u8, u16, u32, u64,
56    isize, i8, i16, i32, i64,
57    bool, char,
58    String,
59    std::path::PathBuf,
60    Duration, Instant,
61    ImmutableString
62}
63
64macro_rules! impl_reflect_tuple {
65    (
66        $(
67            ( $($t:ident,)* );
68        )*
69    ) => {
70        $(
71            impl< $($t: Clone + Reflect),* > Reflect for ( $($t,)* ) {
72                blank_reflect!();
73            }
74        )*
75    }
76}
77
78impl_reflect_tuple! {
79    (T0,);
80    (T0, T1, );
81    (T0, T1, T2, );
82    (T0, T1, T2, T3,);
83    (T0, T1, T2, T3, T4,);
84}
85
86impl<const N: usize, T: Reflect + Clone> Reflect for [T; N] {
87    blank_reflect!();
88
89    fn as_array(&self, func: &mut dyn FnMut(Option<&dyn ReflectArray>)) {
90        func(Some(self))
91    }
92
93    fn as_array_mut(&mut self, func: &mut dyn FnMut(Option<&mut dyn ReflectArray>)) {
94        func(Some(self))
95    }
96}
97
98impl<const N: usize, T: Reflect + Clone> ReflectArray for [T; N] {
99    fn reflect_index(&self, index: usize) -> Option<&dyn Reflect> {
100        if let Some(item) = self.get(index) {
101            Some(item)
102        } else {
103            None
104        }
105    }
106
107    fn reflect_index_mut(&mut self, index: usize) -> Option<&mut dyn Reflect> {
108        if let Some(item) = self.get_mut(index) {
109            Some(item)
110        } else {
111            None
112        }
113    }
114
115    fn reflect_len(&self) -> usize {
116        self.len()
117    }
118}
119
120impl_reflect! {
121    #[reflect(ReflectList, ReflectArray)]
122    pub struct Vec<T: Reflect + Clone>;
123}
124
125impl<T: Reflect + Clone> ReflectArray for Vec<T> {
126    fn reflect_index(&self, index: usize) -> Option<&dyn Reflect> {
127        self.get(index).map(|x| x as &dyn Reflect)
128    }
129
130    fn reflect_index_mut(&mut self, index: usize) -> Option<&mut dyn Reflect> {
131        self.get_mut(index).map(|x| x as &mut dyn Reflect)
132    }
133
134    fn reflect_len(&self) -> usize {
135        self.len()
136    }
137}
138
139/// REMARK: `Reflect` is implemented for `Vec<T>` where `T: Reflect` only.
140impl<T: Reflect + Clone> ReflectList for Vec<T> {
141    fn reflect_push(&mut self, value: Box<dyn Reflect>) -> Result<(), Box<dyn Reflect>> {
142        self.push(*value.downcast::<T>()?);
143        Ok(())
144    }
145
146    fn reflect_pop(&mut self) -> Option<Box<dyn Reflect>> {
147        if let Some(item) = self.pop() {
148            Some(Box::new(item))
149        } else {
150            None
151        }
152    }
153
154    fn reflect_remove(&mut self, index: usize) -> Option<Box<dyn Reflect>> {
155        if index < self.len() {
156            Some(Box::new(self.remove(index)))
157        } else {
158            None
159        }
160    }
161
162    fn reflect_insert(
163        &mut self,
164        index: usize,
165        value: Box<dyn Reflect>,
166    ) -> Result<(), Box<dyn Reflect>> {
167        self.insert(index, *value.downcast::<T>()?);
168        Ok(())
169    }
170}
171
172impl<K, V, S> Reflect for HashMap<K, V, S>
173where
174    K: Reflect + Eq + Hash + Clone + 'static,
175    V: Reflect + Clone,
176    S: BuildHasher + Clone + 'static,
177{
178    blank_reflect!();
179
180    fn as_hash_map(&self, func: &mut dyn FnMut(Option<&dyn ReflectHashMap>)) {
181        func(Some(self))
182    }
183
184    fn as_hash_map_mut(&mut self, func: &mut dyn FnMut(Option<&mut dyn ReflectHashMap>)) {
185        func(Some(self))
186    }
187}
188
189impl<K, V, S> ReflectHashMap for HashMap<K, V, S>
190where
191    K: Reflect + Eq + Hash + Clone + 'static,
192    V: Reflect + Clone,
193    S: BuildHasher + Clone + 'static,
194{
195    fn reflect_insert(
196        &mut self,
197        key: Box<dyn Reflect>,
198        value: Box<dyn Reflect>,
199    ) -> Option<Box<dyn Reflect>> {
200        if let Ok(key) = key.downcast::<K>() {
201            if let Ok(value) = value.downcast::<V>() {
202                if let Some(previous) = self.insert(*key, *value) {
203                    return Some(Box::new(previous));
204                }
205            }
206        }
207
208        None
209    }
210
211    fn reflect_len(&self) -> usize {
212        self.len()
213    }
214
215    fn reflect_get(&self, key: &dyn Reflect, func: &mut dyn FnMut(Option<&dyn Reflect>)) {
216        key.downcast_ref::<K>(&mut |result| match result {
217            Some(key) => match self.get(key) {
218                Some(value) => func(Some(value as &dyn Reflect)),
219                None => func(None),
220            },
221            None => func(None),
222        })
223    }
224
225    fn reflect_get_mut(
226        &mut self,
227        key: &dyn Reflect,
228        func: &mut dyn FnMut(Option<&mut dyn Reflect>),
229    ) {
230        key.downcast_ref::<K>(&mut |result| match result {
231            Some(key) => match self.get_mut(key) {
232                Some(value) => func(Some(value as &mut dyn Reflect)),
233                None => func(None),
234            },
235            None => func(None),
236        })
237    }
238
239    fn reflect_get_nth_value_ref(&self, index: usize) -> Option<&dyn Reflect> {
240        self.values().nth(index).map(|v| v as &dyn Reflect)
241    }
242
243    fn reflect_get_nth_value_mut(&mut self, index: usize) -> Option<&mut dyn Reflect> {
244        self.values_mut().nth(index).map(|v| v as &mut dyn Reflect)
245    }
246
247    fn reflect_get_at(&self, index: usize) -> Option<(&dyn Reflect, &dyn Reflect)> {
248        self.iter()
249            .nth(index)
250            .map(|(k, v)| (k as &dyn Reflect, v as &dyn Reflect))
251    }
252
253    fn reflect_get_at_mut(&mut self, index: usize) -> Option<(&dyn Reflect, &mut dyn Reflect)> {
254        self.iter_mut()
255            .nth(index)
256            .map(|(k, v)| (k as &dyn Reflect, v as &mut dyn Reflect))
257    }
258
259    fn reflect_remove(
260        &mut self,
261        key: &dyn Reflect,
262        func: &mut dyn FnMut(Option<Box<dyn Reflect>>),
263    ) {
264        key.downcast_ref::<K>(&mut |result| match result {
265            Some(key) => func(
266                self.remove(key)
267                    .map(|value| Box::new(value) as Box<dyn Reflect>),
268            ),
269            None => func(None),
270        })
271    }
272}
273
274impl Reflect for () {
275    blank_reflect!();
276}
277
278impl_reflect! { pub struct Uuid; }
279
280impl_reflect! {
281    pub struct Cell<T: Debug + Copy>;
282}
283
284impl_reflect! {
285    pub enum Option<T: Clone + Debug + Reflect> {
286        Some(T),
287        None
288    }
289}
290
291impl_reflect! {
292    pub struct Range<Idx: Clone + Debug + Reflect> {
293        pub start: Idx,
294        pub end: Idx,
295    }
296}
297
298impl<T: Reflect + Clone> Reflect for Box<T> {
299    delegate_reflect!();
300}
301
302macro_rules! impl_reflect_inner_mutability {
303    ($self:ident, $acquire_lock_guard:block, $into_inner:block) => {
304        fn source_path() -> &'static str {
305            file!()
306        }
307
308        fn derived_types() -> &'static [std::any::TypeId] {
309            // TODO: This seems to be impossible to implement because of `?Sized` trait bound
310            // up above.
311            &[]
312        }
313
314        fn try_clone_box(&$self) -> Option<Box<dyn Reflect>> {
315            let guard = $acquire_lock_guard;
316            Some(Box::new(guard.clone()))
317        }
318
319        fn query_derived_types(&self) -> &'static [std::any::TypeId] {
320            T::derived_types()
321        }
322
323        fn type_name(&$self) -> &'static str {
324            std::any::type_name::<T>()
325        }
326
327        fn doc(&$self) -> &'static str {
328            ""
329        }
330
331        fn assembly_name(&self) -> &'static str {
332            env!("CARGO_PKG_NAME")
333        }
334
335        fn type_assembly_name() -> &'static str {
336            env!("CARGO_PKG_NAME")
337        }
338
339        fn fields_ref(&$self, func: &mut dyn FnMut(&[FieldRef])) {
340            let guard = $acquire_lock_guard;
341            guard.fields_ref(func)
342        }
343
344        fn fields_mut(&mut $self, func: &mut dyn FnMut(&mut [FieldMut])) {
345            let mut guard = $acquire_lock_guard;
346            guard.fields_mut(func)
347        }
348
349        fn into_any($self: Box<Self>) -> Box<dyn Any> {
350            let inner = $into_inner;
351            Box::new(inner)
352        }
353
354        fn as_any(&$self, func: &mut dyn FnMut(&dyn Any)) {
355            let guard = $acquire_lock_guard;
356            (*guard).as_any(func)
357        }
358
359        fn as_any_mut(&mut $self, func: &mut dyn FnMut(&mut dyn Any)) {
360            let mut guard = $acquire_lock_guard;
361            (*guard).as_any_mut(func)
362        }
363
364        fn as_reflect(&$self, func: &mut dyn FnMut(&dyn Reflect)) {
365            let guard = $acquire_lock_guard;
366            (*guard).as_reflect(func)
367        }
368
369        fn as_reflect_mut(&mut $self, func: &mut dyn FnMut(&mut dyn Reflect)) {
370            let mut guard = $acquire_lock_guard;
371            (*guard).as_reflect_mut(func)
372        }
373
374        fn set(&mut $self, value: Box<dyn Reflect>) -> Result<Box<dyn Reflect>, Box<dyn Reflect>> {
375            let mut guard = $acquire_lock_guard;
376            guard.set(value)
377        }
378
379        fn set_field(
380            &mut $self,
381            field: &str,
382            value: Box<dyn Reflect>,
383            func: &mut dyn FnMut(Result<Box<dyn Reflect>, SetFieldError>),
384        ) {
385            let mut guard = $acquire_lock_guard;
386            guard.set_field(field, value, func)
387        }
388
389        fn field(&$self, name: &str, func: &mut dyn FnMut(Option<&dyn Reflect>)) {
390            let guard = $acquire_lock_guard;
391            guard.field(name, func)
392        }
393
394        fn field_mut(&mut $self, name: &str, func: &mut dyn FnMut(Option<&mut dyn Reflect>)) {
395            let mut guard = $acquire_lock_guard;
396            guard.field_mut(name, func)
397        }
398
399        fn as_array(&$self, func: &mut dyn FnMut(Option<&dyn ReflectArray>)) {
400            let guard = $acquire_lock_guard;
401            guard.as_array(func)
402        }
403
404        fn as_array_mut(&mut $self, func: &mut dyn FnMut(Option<&mut dyn ReflectArray>)) {
405            let mut guard = $acquire_lock_guard;
406            guard.as_array_mut(func)
407        }
408
409        fn as_list(&$self, func: &mut dyn FnMut(Option<&dyn ReflectList>)) {
410            let guard = $acquire_lock_guard;
411            guard.as_list(func)
412        }
413
414        fn as_list_mut(&mut $self, func: &mut dyn FnMut(Option<&mut dyn ReflectList>)) {
415            let mut guard = $acquire_lock_guard;
416            guard.as_list_mut(func)
417        }
418
419        fn as_inheritable_variable(
420            &$self,
421            func: &mut dyn FnMut(Option<&dyn ReflectInheritableVariable>),
422        ) {
423            let guard = $acquire_lock_guard;
424            guard.as_inheritable_variable(func)
425        }
426
427        fn as_inheritable_variable_mut(
428            &mut $self,
429            func: &mut dyn FnMut(Option<&mut dyn ReflectInheritableVariable>),
430        ) {
431            let mut guard = $acquire_lock_guard;
432            guard.as_inheritable_variable_mut(func)
433        }
434
435        fn as_hash_map(&$self, func: &mut dyn FnMut(Option<&dyn ReflectHashMap>)) {
436            let guard = $acquire_lock_guard;
437            guard.as_hash_map(func)
438        }
439
440        fn as_hash_map_mut(&mut $self, func: &mut dyn FnMut(Option<&mut dyn ReflectHashMap>)) {
441            let mut guard = $acquire_lock_guard;
442            guard.as_hash_map_mut(func)
443        }
444    };
445}
446
447impl<T: Reflect + Clone> Reflect for parking_lot::Mutex<T> {
448    impl_reflect_inner_mutability!(self, { self.safe_lock() }, { self.into_inner() });
449}
450
451impl<T: Reflect + Clone> Reflect for parking_lot::RwLock<T> {
452    impl_reflect_inner_mutability!(self, { self.write() }, { self.into_inner() });
453}
454
455#[allow(clippy::mut_mutex_lock)]
456impl<T: Reflect + Clone> Reflect for std::sync::Mutex<T> {
457    impl_reflect_inner_mutability!(self, { self.safe_lock().unwrap() }, { self.into_inner() });
458}
459
460impl<T: Reflect + Clone> Reflect for std::sync::RwLock<T> {
461    impl_reflect_inner_mutability!(self, { self.write().unwrap() }, { self.into_inner() });
462}
463
464impl<T: Reflect + Clone> Reflect for Arc<parking_lot::Mutex<T>> {
465    impl_reflect_inner_mutability!(self, { self.safe_lock() }, {
466        Arc::into_inner(*self)
467            .expect("Value cannot be shared!")
468            .into_inner()
469    });
470}
471
472impl<T: Reflect + Clone> Reflect for Arc<std::sync::Mutex<T>> {
473    impl_reflect_inner_mutability!(self, { self.lock().unwrap() }, {
474        Arc::into_inner(*self)
475            .expect("Value cannot be shared!")
476            .into_inner()
477    });
478}
479
480impl<T: Reflect + Clone> Reflect for Arc<std::sync::RwLock<T>> {
481    impl_reflect_inner_mutability!(self, { self.write().unwrap() }, {
482        Arc::into_inner(*self)
483            .expect("Value cannot be shared!")
484            .into_inner()
485    });
486}
487
488impl<T: Reflect + Clone> Reflect for Arc<parking_lot::RwLock<T>> {
489    impl_reflect_inner_mutability!(self, { self.write() }, {
490        Arc::into_inner(*self)
491            .expect("Value cannot be shared!")
492            .into_inner()
493    });
494}
495
496impl<T: Reflect + Clone> Reflect for RefCell<T> {
497    impl_reflect_inner_mutability!(self, { self.borrow_mut() }, { self.into_inner() });
498}
499
500impl<T: Reflect + Clone> Reflect for Rc<RefCell<T>> {
501    impl_reflect_inner_mutability!(self, { self.borrow_mut() }, {
502        Rc::into_inner(*self)
503            .expect("Value cannot be shared!")
504            .into_inner()
505    });
506}