fyrox_core/
variable.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//! A wrapper for a variable that hold additional flag that tells that initial value was changed in runtime.
22//!
23//! For more info see [`InheritableVariable`]
24
25use crate::{
26    reflect::prelude::*,
27    visitor::{prelude::*, VisitorFlags},
28};
29use bitflags::bitflags;
30use std::{
31    any::{Any, TypeId},
32    cell::Cell,
33    fmt::Debug,
34    ops::{Deref, DerefMut},
35};
36
37#[derive(Reflect, Copy, Clone, Ord, PartialOrd, PartialEq, Eq)]
38#[repr(transparent)]
39pub struct VariableFlags(u8);
40
41bitflags! {
42    impl VariableFlags: u8 {
43        /// Nothing.
44        const NONE = 0;
45        /// A variable was externally modified.
46        const MODIFIED = 0b0000_0001;
47        /// A variable must be synced with respective variable from a data model. This flag is won't
48        /// be serialized when serializing an inheritable variable. This is purely a runtime flag
49        /// anyway.
50        const NEED_SYNC = 0b0000_0010;
51    }
52}
53
54impl Debug for VariableFlags {
55    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
56        if *self == VariableFlags::NONE {
57            write!(f, "NONE")
58        } else {
59            for (i, flag) in self.iter().enumerate() {
60                if i != 0 {
61                    write!(f, "|")?
62                }
63                match flag {
64                    VariableFlags::MODIFIED => write!(f, "MOD")?,
65                    VariableFlags::NEED_SYNC => write!(f, "SYNC")?,
66                    _ => {}
67                }
68            }
69            Ok(())
70        }
71    }
72}
73
74/// An error that could occur during inheritance.
75#[derive(Debug)]
76pub enum InheritError {
77    /// Types of properties mismatch.
78    TypesMismatch {
79        /// Type of left property.
80        left_type: &'static str,
81        /// Type of right property.
82        right_type: &'static str,
83    },
84}
85
86/// A wrapper for a variable that hold additional flag that tells that initial value was changed in runtime.
87///
88/// InheritableVariables are used for resource inheritance system. Resource inheritance may just sound weird,
89/// but the idea behind it is very simple - take property values from parent resource if the value in current
90/// hasn't changed in runtime.
91///
92/// To get better understanding, let's look at very simple example. Imagine you have a scene with a 3d model
93/// instance. Now you realizes that the 3d model has a misplaced object and you need to fix it, you open a
94/// 3D modelling software (Blender, 3Ds max, etc) and move the object to a correct spot and re-save the 3D model.
95/// The question is: what should happen with the instance of the object in the scene? Logical answer would be:
96/// if it hasn't been modified, then just take the new position from the 3D model. This is where inheritable
97/// variable comes into play. If you've change the value of such variable, it will remember changes and the object
98/// will stay on its new position instead of changed.
99///
100/// # Deref and DerefMut
101///
102/// Access via Deref provides access to inner variable. **DerefMut marks variable as modified** and returns a
103/// mutable reference to inner variable.
104pub struct InheritableVariable<T> {
105    value: T,
106    flags: Cell<VariableFlags>,
107}
108
109impl<T: Debug> Debug for InheritableVariable<T> {
110    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
111        write!(f, "{:?} (flags:{:?})", self.value, self.flags.get())
112    }
113}
114
115impl<T: Clone> Clone for InheritableVariable<T> {
116    #[inline]
117    fn clone(&self) -> Self {
118        Self {
119            value: self.value.clone(),
120            flags: self.flags.clone(),
121        }
122    }
123}
124
125impl<T> From<T> for InheritableVariable<T> {
126    #[inline]
127    fn from(v: T) -> Self {
128        InheritableVariable::new_modified(v)
129    }
130}
131
132impl<T: PartialEq> PartialEq for InheritableVariable<T> {
133    #[inline]
134    fn eq(&self, other: &Self) -> bool {
135        // `custom` flag intentionally ignored!
136        self.value.eq(&other.value)
137    }
138}
139
140impl<T: Eq> Eq for InheritableVariable<T> {}
141
142impl<T: Default> Default for InheritableVariable<T> {
143    #[inline]
144    fn default() -> Self {
145        Self {
146            value: T::default(),
147            flags: Cell::new(VariableFlags::MODIFIED),
148        }
149    }
150}
151
152impl<T: Clone> InheritableVariable<T> {
153    /// Clones wrapped value.
154    #[inline]
155    pub fn clone_inner(&self) -> T {
156        self.value.clone()
157    }
158
159    /// Tries to sync a value in a data model with a value in the inheritable variable. The value
160    /// will be synced only if it was marked as needs sync.
161    #[inline]
162    pub fn try_sync_model<S: FnOnce(T)>(&self, setter: S) -> bool {
163        if self.need_sync() {
164            // Drop flag first.
165            let mut flags = self.flags.get();
166            flags.remove(VariableFlags::NEED_SYNC);
167            self.flags.set(flags);
168
169            // Set new value in a data model.
170            (setter)(self.value.clone());
171
172            true
173        } else {
174            false
175        }
176    }
177}
178
179impl<T> InheritableVariable<T> {
180    /// Creates new modified variable from given value. This method should always be used to create inheritable
181    /// variables in the engine.
182    #[inline]
183    pub fn new_modified(value: T) -> Self {
184        Self {
185            value,
186            flags: Cell::new(VariableFlags::MODIFIED),
187        }
188    }
189
190    /// Creates new variable without any flags set.
191    #[inline]
192    pub fn new_non_modified(value: T) -> Self {
193        Self {
194            value,
195            flags: Cell::new(VariableFlags::NONE),
196        }
197    }
198
199    /// Creates new variable from a given value with custom flags.
200    #[inline]
201    pub fn new_with_flags(value: T, flags: VariableFlags) -> Self {
202        Self {
203            value,
204            flags: Cell::new(flags),
205        }
206    }
207
208    /// Replaces value and also raises the [`VariableFlags::MODIFIED`] flag.
209    #[inline]
210    pub fn set_value_and_mark_modified(&mut self, value: T) -> T {
211        self.mark_modified_and_need_sync();
212        std::mem::replace(&mut self.value, value)
213    }
214
215    /// Replaces value and flags.
216    #[inline]
217    pub fn set_value_with_flags(&mut self, value: T, flags: VariableFlags) -> T {
218        self.flags.set(flags);
219        std::mem::replace(&mut self.value, value)
220    }
221
222    /// Replaces current value without marking the variable modified.
223    #[inline]
224    pub fn set_value_silent(&mut self, value: T) -> T {
225        std::mem::replace(&mut self.value, value)
226    }
227
228    /// Returns true if the respective data model's variable must be synced.
229    #[inline]
230    pub fn need_sync(&self) -> bool {
231        self.flags.get().contains(VariableFlags::NEED_SYNC)
232    }
233
234    /// Returns a reference to the wrapped value.
235    #[inline]
236    pub fn get_value_ref(&self) -> &T {
237        &self.value
238    }
239
240    /// Returns a mutable reference to the wrapped value.
241    ///
242    /// # Important notes.
243    ///
244    /// The method raises `modified` flag, no matter if actual modification was made!
245    #[inline]
246    pub fn get_value_mut_and_mark_modified(&mut self) -> &mut T {
247        self.mark_modified_and_need_sync();
248        &mut self.value
249    }
250
251    /// Returns a mutable reference to the wrapped value.
252    ///
253    /// # Important notes.
254    ///
255    /// This method does not mark the value as modified!
256    #[inline]
257    pub fn get_value_mut_silent(&mut self) -> &mut T {
258        &mut self.value
259    }
260
261    /// Returns true if variable was modified and should not be overwritten during property inheritance.
262    #[inline]
263    pub fn is_modified(&self) -> bool {
264        self.flags.get().contains(VariableFlags::MODIFIED)
265    }
266
267    /// Marks value as modified, so its value won't be overwritten during property inheritance.
268    #[inline]
269    pub fn mark_modified(&mut self) {
270        self.flags
271            .get_mut()
272            .insert(VariableFlags::MODIFIED | VariableFlags::NEED_SYNC);
273    }
274
275    /// Deconstructs the variable and returns the wrapped value.
276    #[inline]
277    pub fn take(self) -> T {
278        self.value
279    }
280
281    #[inline]
282    fn mark_modified_and_need_sync(&mut self) {
283        self.flags
284            .get_mut()
285            .insert(VariableFlags::MODIFIED | VariableFlags::NEED_SYNC);
286    }
287}
288
289impl<T> Deref for InheritableVariable<T> {
290    type Target = T;
291
292    #[inline]
293    fn deref(&self) -> &Self::Target {
294        &self.value
295    }
296}
297
298impl<T> DerefMut for InheritableVariable<T> {
299    #[inline]
300    fn deref_mut(&mut self) -> &mut Self::Target {
301        self.mark_modified_and_need_sync();
302        &mut self.value
303    }
304}
305
306/// Special non-derived implementation of Visit to account for the special needs of InheritableVariable from Visitors.
307impl<T> Visit for InheritableVariable<T>
308where
309    T: Visit,
310{
311    /// Read or write this value, depending on whether [Visitor::is_reading()] is true or false.
312    /// InheritableVariable uses the visit method in a very special way. Rather than just directly
313    /// visiting the inner value and flags of the InheritableVariable, it allows for several distinct possibilities.
314    ///
315    /// # Cases when the visitor is reading:
316    ///
317    /// 1. If the visitor is reading, InheritableVariable allows for the possibilities that the data being read
318    /// is not an InheritableVariable but is data of type T. It uses this data to set the inner value
319    /// and adds [VariableFlags::MODIFIED] to [InheritableVariable::flags].
320    ///
321    /// 2. The data for this InheritableVariable may be missing entirely from the given visitor.
322    /// If so, then leave inner value unmodified and remove the `MODIFIED` flag from `flags`.
323    ///
324    /// # Cases when the visitor is writing:
325    ///
326    /// 1. If the visitor is writing and the `MODIFIED` flag is not set, then InheritableVariable writes **nothing at all.**
327    /// It does not even write an empty region.
328    ///
329    /// 2. If the visitor is writing and the `MODIFIED` flag is set, then the InheritableVariable writes itself to the Visitor
330    /// as if InheritableVariable were a normal struct, writing a Field for "Flags" and causing `value` to write itself.
331    ///
332    /// If the [VisitorFlags::SERIALIZE_EVERYTHING] flag is set in the [Visitor::flags], this causes the InheritableVariable to act
333    /// as if its `MODIFIED` flag were set.
334    fn visit(&mut self, name: &str, visitor: &mut Visitor) -> VisitResult {
335        let mut visited = false;
336
337        if visitor.is_reading() {
338            // Try to visit inner value first, this is very useful if user decides to make their
339            // variable inheritable, but still keep backward compatibility.
340            let has_flags = if let Ok(mut region) = visitor.enter_region(name) {
341                self.flags.get_mut().0.visit("Flags", &mut region).is_ok()
342            } else {
343                false
344            };
345            if !has_flags {
346                visited = self.value.visit(name, visitor).is_ok();
347                self.flags.get_mut().insert(VariableFlags::MODIFIED);
348            }
349        }
350
351        if !visited {
352            if visitor.is_reading() {
353                // The entire region could be missing if the variable wasn't modified.
354                if let Ok(mut region) = visitor.enter_region(name) {
355                    let _ = self.value.visit("Value", &mut region);
356                    self.flags.get_mut().0.visit("Flags", &mut region)?;
357                } else {
358                    // Default flags contains `modified` flag, we need to remove it if there's no
359                    // region at all.
360                    self.flags.get_mut().remove(VariableFlags::MODIFIED);
361                }
362            } else if self.flags.get().contains(VariableFlags::MODIFIED)
363                || visitor.flags.contains(VisitorFlags::SERIALIZE_EVERYTHING)
364            {
365                let mut region = visitor.enter_region(name)?;
366                self.value.visit("Value", &mut region)?;
367
368                let mut flags = self.flags.get();
369                // Remove NEED_SYNC flag, because it is a runtime flag and when saved, it produces
370                // a lot of merge conflicts in the assets.
371                flags.remove(VariableFlags::NEED_SYNC);
372                flags.0.visit("Flags", &mut region)?;
373            } else {
374                // Non-modified variables do not write anything.
375            }
376        }
377
378        Ok(())
379    }
380}
381
382impl<T> Reflect for InheritableVariable<T>
383where
384    T: Reflect + Clone + PartialEq + Debug,
385{
386    #[inline]
387    fn source_path() -> &'static str {
388        file!()
389    }
390
391    fn try_clone_box(&self) -> Option<Box<dyn Reflect>> {
392        Some(Box::new(self.value.clone()))
393    }
394
395    fn derived_types() -> &'static [TypeId]
396    where
397        Self: Sized,
398    {
399        T::derived_types()
400    }
401
402    fn query_derived_types(&self) -> &'static [TypeId] {
403        Self::derived_types()
404    }
405
406    #[inline]
407    fn type_name(&self) -> &'static str {
408        self.value.type_name()
409    }
410
411    #[inline]
412    fn doc(&self) -> &'static str {
413        self.value.doc()
414    }
415
416    fn assembly_name(&self) -> &'static str {
417        env!("CARGO_PKG_NAME")
418    }
419
420    fn type_assembly_name() -> &'static str {
421        env!("CARGO_PKG_NAME")
422    }
423
424    #[inline]
425    fn fields_ref(&self, func: &mut dyn FnMut(&[FieldRef])) {
426        self.value.fields_ref(func)
427    }
428
429    #[inline]
430    fn fields_mut(&mut self, func: &mut dyn FnMut(&mut [FieldMut])) {
431        self.value.fields_mut(func)
432    }
433
434    #[inline]
435    fn into_any(self: Box<Self>) -> Box<dyn Any> {
436        Box::new(self.value).into_any()
437    }
438
439    #[inline]
440    fn as_any(&self, func: &mut dyn FnMut(&dyn Any)) {
441        self.value.as_any(func)
442    }
443
444    #[inline]
445    fn as_any_mut(&mut self, func: &mut dyn FnMut(&mut dyn Any)) {
446        self.value.as_any_mut(func)
447    }
448
449    #[inline]
450    fn as_reflect(&self, func: &mut dyn FnMut(&dyn Reflect)) {
451        self.value.as_reflect(func)
452    }
453
454    #[inline]
455    fn as_reflect_mut(&mut self, func: &mut dyn FnMut(&mut dyn Reflect)) {
456        self.value.as_reflect_mut(func)
457    }
458
459    #[inline]
460    fn set(&mut self, value: Box<dyn Reflect>) -> Result<Box<dyn Reflect>, Box<dyn Reflect>> {
461        self.mark_modified_and_need_sync();
462        self.value.set(value)
463    }
464
465    #[inline]
466    fn set_field(
467        &mut self,
468        field: &str,
469        value: Box<dyn Reflect>,
470        func: &mut dyn FnMut(Result<Box<dyn Reflect>, SetFieldError>),
471    ) {
472        self.mark_modified_and_need_sync();
473        self.value.set_field(field, value, func)
474    }
475
476    #[inline]
477    fn field(&self, name: &str, func: &mut dyn FnMut(Option<&dyn Reflect>)) {
478        self.value.field(name, func)
479    }
480
481    #[inline]
482    fn field_mut(&mut self, name: &str, func: &mut dyn FnMut(Option<&mut dyn Reflect>)) {
483        // Any modifications inside of compound structs must mark the variable as modified.
484        self.mark_modified_and_need_sync();
485        self.value.field_mut(name, func)
486    }
487
488    #[inline]
489    fn as_array(&self, func: &mut dyn FnMut(Option<&dyn ReflectArray>)) {
490        self.value.as_array(func)
491    }
492
493    #[inline]
494    fn as_array_mut(&mut self, func: &mut dyn FnMut(Option<&mut dyn ReflectArray>)) {
495        // Any modifications inside of inheritable arrays must mark the variable as modified.
496        self.mark_modified_and_need_sync();
497        self.value.as_array_mut(func)
498    }
499
500    #[inline]
501    fn as_list(&self, func: &mut dyn FnMut(Option<&dyn ReflectList>)) {
502        self.value.as_list(func)
503    }
504
505    #[inline]
506    fn as_list_mut(&mut self, func: &mut dyn FnMut(Option<&mut dyn ReflectList>)) {
507        // Any modifications inside of inheritable lists must mark the variable as modified.
508        self.mark_modified_and_need_sync();
509        self.value.as_list_mut(func)
510    }
511
512    #[inline]
513    fn as_inheritable_variable(
514        &self,
515        func: &mut dyn FnMut(Option<&dyn ReflectInheritableVariable>),
516    ) {
517        func(Some(self))
518    }
519
520    #[inline]
521    fn as_inheritable_variable_mut(
522        &mut self,
523        func: &mut dyn FnMut(Option<&mut dyn ReflectInheritableVariable>),
524    ) {
525        func(Some(self))
526    }
527}
528
529impl<T> ReflectInheritableVariable for InheritableVariable<T>
530where
531    T: Reflect + Clone + PartialEq + Debug,
532{
533    fn try_inherit(
534        &mut self,
535        parent: &dyn ReflectInheritableVariable,
536        ignored_types: &[TypeId],
537    ) -> Result<Option<Box<dyn Reflect>>, InheritError> {
538        let mut result: Result<Option<Box<dyn Reflect>>, InheritError> = Ok(None);
539
540        match parent.inner_value_ref().as_any_raw().downcast_ref::<T>() {
541            Some(parent_value) => {
542                if !self.is_modified() {
543                    let mut parent_value_clone = parent_value.clone();
544
545                    mark_inheritable_properties_non_modified(
546                        &mut parent_value_clone,
547                        ignored_types,
548                    );
549
550                    result = Ok(Some(Box::new(std::mem::replace(
551                        &mut self.value,
552                        parent_value_clone,
553                    ))));
554                }
555            }
556            None => {
557                result = Err(InheritError::TypesMismatch {
558                    left_type: self.inner_value_ref().type_name(),
559                    right_type: parent.inner_value_ref().type_name(),
560                });
561            }
562        }
563
564        result
565    }
566
567    #[inline]
568    fn reset_modified_flag(&mut self) {
569        self.flags.get_mut().remove(VariableFlags::MODIFIED)
570    }
571
572    #[inline]
573    fn flags(&self) -> VariableFlags {
574        self.flags.get()
575    }
576
577    #[inline]
578    fn set_flags(&mut self, flags: VariableFlags) {
579        self.flags.set(flags)
580    }
581
582    #[inline]
583    fn is_modified(&self) -> bool {
584        self.is_modified()
585    }
586
587    #[inline]
588    fn value_equals(&self, other: &dyn ReflectInheritableVariable) -> bool {
589        let mut output_result = false;
590        other.as_reflect(&mut |reflect| {
591            reflect.downcast_ref::<T>(&mut |result| {
592                output_result = match result {
593                    Some(other) => &self.value == other,
594                    None => false,
595                };
596            })
597        });
598        output_result
599    }
600
601    #[inline]
602    fn clone_value_box(&self) -> Box<dyn Reflect> {
603        Box::new(self.value.clone())
604    }
605
606    #[inline]
607    fn mark_modified(&mut self) {
608        self.mark_modified()
609    }
610
611    #[inline]
612    fn inner_value_mut(&mut self) -> &mut dyn Reflect {
613        &mut self.value
614    }
615
616    #[inline]
617    fn inner_value_ref(&self) -> &dyn Reflect {
618        &self.value
619    }
620}
621
622/// Simultaneously walks over fields of given child and parent and tries to inherit values of properties
623/// of child with parent's properties. It is done recursively for every fields in entities.
624///
625/// ## How it works
626///
627/// In general, it uses reflection to iterate over child and parent properties and trying to inherit values.
628/// Child's field will take parent's field value only if child's field is **non-modified**. There are one
629/// edge case in inheritance: collections.
630///
631/// Inheritance for collections itself works the same as described above, however the content of collections
632/// can only be inherited if their sizes are equal. Also, since inheritance uses plain copy of inner data of
633/// inheritable variables, it works in a special way.
634///
635/// ```text
636/// Child                                       Parent (root)
637///     InheritableVariableA            <-         InheritableVariableA*
638///     InheritableCollection*          ->         InheritableCollection*
639///         Item0                                       Item0
640///             InheritableVariableB*   ->                  InheritableVariableB*
641///             InheritableVariableC    <-                  InheritableVariableC*
642///         Item1                                       Item1
643///             ..                                          ..
644///         ..                                          ..
645///         ItemN                                       ItemN
646///             ..                                          ..
647///
648/// * - means that the variable was modified
649/// ```
650///
651/// At first, `InheritableVariableA` will be copied from the parent as usual. Next, the inheritable collection
652/// won't be copied (because it is modified), however its items will be inherited separately.
653/// `InheritableVariableB` won't be copied either (since it is modified too), but `InheritableVariableC` **will**
654/// be copied from parent.
655pub fn try_inherit_properties(
656    child: &mut dyn Reflect,
657    parent: &dyn Reflect,
658    ignored_types: &[TypeId],
659) -> Result<(), InheritError> {
660    let child_type_id = (*child).type_id();
661    let parent_type_id = (*parent).type_id();
662
663    if ignored_types.contains(&child_type_id) || ignored_types.contains(&parent_type_id) {
664        return Ok(());
665    }
666
667    if child_type_id != parent_type_id {
668        return Err(InheritError::TypesMismatch {
669            left_type: (*child).type_name(),
670            right_type: (*parent).type_name(),
671        });
672    }
673
674    let mut result = None;
675
676    child.as_inheritable_variable_mut(&mut |inheritable_child| {
677        if let Some(inheritable_child) = inheritable_child {
678            parent.as_inheritable_variable(&mut |inheritable_parent| {
679                if let Some(inheritable_parent) = inheritable_parent {
680                    if let Err(e) = inheritable_child.try_inherit(inheritable_parent, ignored_types)
681                    {
682                        result = Some(Err(e));
683                    }
684
685                    if !matches!(result, Some(Err(_))) {
686                        result = Some(try_inherit_properties(
687                            inheritable_child.inner_value_mut(),
688                            inheritable_parent.inner_value_ref(),
689                            ignored_types,
690                        ));
691                    }
692                }
693            })
694        }
695    });
696
697    if result.is_none() {
698        child.as_array_mut(&mut |child_collection| {
699            if let Some(child_collection) = child_collection {
700                parent.as_array(&mut |parent_collection| {
701                    if let Some(parent_collection) = parent_collection {
702                        if child_collection.reflect_len() == parent_collection.reflect_len() {
703                            for i in 0..child_collection.reflect_len() {
704                                // Sparse arrays (like Pool) could have empty entries.
705                                if let (Some(child_item), Some(parent_item)) = (
706                                    child_collection.reflect_index_mut(i),
707                                    parent_collection.reflect_index(i),
708                                ) {
709                                    if let Err(e) = try_inherit_properties(
710                                        child_item,
711                                        parent_item,
712                                        ignored_types,
713                                    ) {
714                                        result = Some(Err(e));
715
716                                        break;
717                                    }
718                                }
719                            }
720                        }
721                    }
722                })
723            }
724        })
725    }
726
727    if result.is_none() {
728        child.fields_mut(&mut |child_fields| {
729            parent.fields_ref(&mut |parent_fields| {
730                for (child_field, parent_field) in child_fields.iter_mut().zip(parent_fields) {
731                    // Look into inner properties recursively and try to inherit them. This is mandatory step, because inner
732                    // fields may also be InheritableVariable<T>.
733                    if let Err(e) = try_inherit_properties(
734                        child_field.value.field_value_as_reflect_mut(),
735                        parent_field.value.field_value_as_reflect(),
736                        ignored_types,
737                    ) {
738                        result = Some(Err(e));
739                    }
740
741                    if matches!(result, Some(Err(_))) {
742                        break;
743                    }
744                }
745            })
746        });
747    }
748
749    result.unwrap_or(Ok(()))
750}
751
752pub fn do_with_inheritable_variables<F>(
753    root: &mut dyn Reflect,
754    func: &mut F,
755    ignored_types: &[TypeId],
756) where
757    F: FnMut(&mut dyn ReflectInheritableVariable),
758{
759    root.apply_recursively_mut(
760        &mut |object| {
761            object.as_inheritable_variable_mut(&mut |variable| {
762                if let Some(variable) = variable {
763                    func(variable);
764                }
765            });
766        },
767        ignored_types,
768    )
769}
770
771pub fn mark_inheritable_properties_non_modified(
772    object: &mut dyn Reflect,
773    ignored_types: &[TypeId],
774) {
775    do_with_inheritable_variables(
776        object,
777        &mut |variable| variable.reset_modified_flag(),
778        ignored_types,
779    );
780}
781
782pub fn mark_inheritable_properties_modified(object: &mut dyn Reflect, ignored_types: &[TypeId]) {
783    do_with_inheritable_variables(
784        object,
785        &mut |variable| variable.mark_modified(),
786        ignored_types,
787    );
788}
789
790#[cfg(test)]
791mod test {
792    use std::cell::RefCell;
793    use std::{cell::Cell, ops::DerefMut};
794
795    use crate::{
796        reflect::{prelude::*, ReflectInheritableVariable},
797        variable::{try_inherit_properties, InheritableVariable, VariableFlags},
798        visitor::{Visit, Visitor},
799    };
800
801    #[derive(Reflect, Clone, Debug, PartialEq)]
802    struct Foo {
803        value: InheritableVariable<f32>,
804    }
805
806    #[derive(Reflect, Clone, Debug, PartialEq)]
807    struct Bar {
808        foo: Foo,
809
810        other_value: InheritableVariable<String>,
811    }
812
813    #[test]
814    fn test_property_inheritance_via_reflection() {
815        let mut parent = Bar {
816            foo: Foo {
817                value: InheritableVariable::new_non_modified(1.23),
818            },
819            other_value: InheritableVariable::new_non_modified("Foobar".to_string()),
820        };
821
822        let mut child = parent.clone();
823
824        // Try inherit non-modified, the result objects must be equal.
825        try_inherit_properties(&mut child, &parent, &[]).unwrap();
826        assert_eq!(parent, child);
827
828        // Then modify parent's and child's values.
829        parent
830            .other_value
831            .set_value_and_mark_modified("Baz".to_string());
832        assert!(ReflectInheritableVariable::is_modified(&parent.other_value),);
833
834        child.foo.value.set_value_and_mark_modified(3.21);
835        assert!(ReflectInheritableVariable::is_modified(&child.foo.value));
836
837        try_inherit_properties(&mut child, &parent, &[]).unwrap();
838
839        // This property reflects parent's changes, because it is non-modified.
840        assert_eq!(child.other_value.value, "Baz".to_string());
841        // This property must remain unchanged, because it is modified.
842        assert_eq!(child.foo.value.value, 3.21);
843    }
844
845    #[test]
846    fn test_inheritable_variable_equality() {
847        let va = InheritableVariable::new_non_modified(1.23);
848        let vb = InheritableVariable::new_non_modified(1.23);
849
850        assert!(va.value_equals(&vb))
851    }
852
853    #[derive(Reflect, Clone, Debug)]
854    enum SomeEnum {
855        Bar(InheritableVariable<f32>),
856        Baz {
857            foo: InheritableVariable<f32>,
858            foobar: InheritableVariable<u32>,
859        },
860    }
861
862    #[test]
863    fn test_enum_inheritance_tuple() {
864        let mut child = SomeEnum::Bar(InheritableVariable::new_non_modified(1.23));
865        let parent = SomeEnum::Bar(InheritableVariable::new_non_modified(3.21));
866
867        try_inherit_properties(&mut child, &parent, &[]).unwrap();
868
869        if let SomeEnum::Bar(value) = child {
870            assert_eq!(*value, 3.21);
871        } else {
872            unreachable!()
873        }
874    }
875
876    #[test]
877    fn test_enum_inheritance_struct() {
878        let mut child = SomeEnum::Baz {
879            foo: InheritableVariable::new_non_modified(1.23),
880            foobar: InheritableVariable::new_non_modified(123),
881        };
882        let parent = SomeEnum::Baz {
883            foo: InheritableVariable::new_non_modified(3.21),
884            foobar: InheritableVariable::new_non_modified(321),
885        };
886
887        try_inherit_properties(&mut child, &parent, &[]).unwrap();
888
889        if let SomeEnum::Baz { foo, foobar } = child {
890            assert_eq!(*foo, 3.21);
891            assert_eq!(*foobar, 321);
892        } else {
893            unreachable!()
894        }
895    }
896
897    #[test]
898    fn test_collection_inheritance() {
899        #[derive(Reflect, Clone, Debug, PartialEq)]
900        struct Foo {
901            some_data: f32,
902        }
903
904        #[derive(Reflect, Clone, Debug, PartialEq)]
905        struct CollectionItem {
906            foo: InheritableVariable<Foo>,
907            bar: InheritableVariable<u32>,
908        }
909
910        #[derive(Reflect, Clone, Debug, PartialEq)]
911        struct MyEntity {
912            collection: InheritableVariable<Vec<CollectionItem>>,
913        }
914
915        let parent = MyEntity {
916            collection: InheritableVariable::new_modified(vec![CollectionItem {
917                foo: InheritableVariable::new_modified(Foo { some_data: 123.321 }),
918                bar: InheritableVariable::new_modified(321),
919            }]),
920        };
921
922        let mut child = MyEntity {
923            collection: InheritableVariable::new_modified(vec![CollectionItem {
924                foo: InheritableVariable::new_modified(Foo { some_data: 321.123 }),
925                bar: InheritableVariable::new_non_modified(321),
926            }]),
927        };
928
929        try_inherit_properties(&mut child, &parent, &[]).unwrap();
930
931        // Flags must be transferred correctly.
932        let item = &child.collection[0];
933        assert!(!item.bar.is_modified());
934        assert_eq!(item.bar.value, 321);
935
936        assert_eq!(item.foo.value, Foo { some_data: 321.123 });
937        assert!(item.foo.is_modified());
938    }
939
940    #[test]
941    fn test_compound_inheritance() {
942        #[derive(Reflect, Clone, Debug, PartialEq, Eq)]
943        struct SomeComplexData {
944            foo: InheritableVariable<u32>,
945        }
946
947        #[derive(Reflect, Clone, Debug, PartialEq)]
948        struct MyEntity {
949            some_field: InheritableVariable<f32>,
950
951            // This field won't be inherited correctly - at first it will take parent's value and then
952            // will try to inherit inner fields, but its is useless step, because inner data is already
953            // a full copy of parent's field value. This absolutely ok, it just indicates issues in user
954            // code.
955            incorrectly_inheritable_data: InheritableVariable<SomeComplexData>,
956
957            // Subfields of this field will be correctly inherited, because the field itself is not inheritable.
958            inheritable_data: SomeComplexData,
959        }
960
961        let mut child = MyEntity {
962            some_field: InheritableVariable::new_non_modified(1.23),
963            incorrectly_inheritable_data: InheritableVariable::new_non_modified(SomeComplexData {
964                foo: InheritableVariable::new_modified(222),
965            }),
966            inheritable_data: SomeComplexData {
967                foo: InheritableVariable::new_modified(222),
968            },
969        };
970
971        let parent = MyEntity {
972            some_field: InheritableVariable::new_non_modified(3.21),
973            incorrectly_inheritable_data: InheritableVariable::new_non_modified(SomeComplexData {
974                foo: InheritableVariable::new_non_modified(321),
975            }),
976            inheritable_data: SomeComplexData {
977                foo: InheritableVariable::new_modified(321),
978            },
979        };
980
981        assert!(try_inherit_properties(&mut child, &parent, &[]).is_ok());
982
983        assert_eq!(child.some_field.value, 3.21);
984        // These fields are equal, despite the fact that they're marked as modified.
985        // This is due incorrect usage of inheritance.
986        assert_eq!(
987            child.incorrectly_inheritable_data.foo.value,
988            parent.incorrectly_inheritable_data.foo.value
989        );
990        // These fields are not equal, as it should be.
991        assert_ne!(
992            child.inheritable_data.foo.value,
993            parent.inheritable_data.foo.value
994        );
995    }
996
997    #[test]
998    fn inheritable_variable_from_t() {
999        assert_eq!(
1000            InheritableVariable::from(42),
1001            InheritableVariable {
1002                value: 42,
1003                ..Default::default()
1004            }
1005        );
1006    }
1007
1008    #[test]
1009    fn default_for_inheritable_variable() {
1010        assert_eq!(
1011            InheritableVariable::<i32>::default(),
1012            InheritableVariable {
1013                value: 0,
1014                flags: Cell::new(VariableFlags::MODIFIED),
1015            }
1016        );
1017    }
1018
1019    #[test]
1020    fn inheritable_variable_clone_inner() {
1021        let v = InheritableVariable::from(42);
1022
1023        assert_eq!(v.clone_inner(), 42);
1024    }
1025
1026    #[test]
1027    fn inheritable_variable_try_sync_model() {
1028        let v = InheritableVariable::from(42);
1029        assert!(!v.try_sync_model(|s| println!("{s}")));
1030
1031        let v = InheritableVariable::new_with_flags(42, VariableFlags::NEED_SYNC);
1032        assert!(v.try_sync_model(|s| println!("{s}")));
1033    }
1034
1035    #[test]
1036    fn inheritable_variable_new_with_flags() {
1037        let v = InheritableVariable::new_with_flags(42, VariableFlags::MODIFIED);
1038
1039        assert_eq!(
1040            v,
1041            InheritableVariable {
1042                value: 42,
1043                flags: Cell::new(VariableFlags::MODIFIED),
1044            }
1045        );
1046    }
1047
1048    #[test]
1049    fn inheritable_variable_set_value_with_flags() {
1050        let mut v = InheritableVariable::from(42);
1051        let res = v.set_value_with_flags(15, VariableFlags::NEED_SYNC);
1052
1053        assert_eq!(res, 42);
1054        assert_eq!(
1055            v,
1056            InheritableVariable {
1057                value: 15,
1058                flags: Cell::new(VariableFlags::NEED_SYNC),
1059            }
1060        );
1061    }
1062
1063    #[test]
1064    fn inheritable_variable_set_value_silent() {
1065        let mut v = InheritableVariable::from(42);
1066        let res = v.set_value_silent(15);
1067
1068        assert_eq!(res, 42);
1069        assert_eq!(
1070            v,
1071            InheritableVariable {
1072                value: 15,
1073                flags: Cell::new(VariableFlags::MODIFIED),
1074            }
1075        );
1076    }
1077
1078    #[test]
1079    fn inheritable_variable_need_sync() {
1080        let v = InheritableVariable::from(42);
1081        assert!(!v.need_sync());
1082
1083        let v = InheritableVariable::new_with_flags(42, VariableFlags::NEED_SYNC);
1084        assert!(v.need_sync());
1085    }
1086
1087    #[test]
1088    fn inheritable_variable_get_value_ref() {
1089        let v = InheritableVariable::from(42);
1090
1091        assert_eq!(v.get_value_ref(), &42);
1092    }
1093
1094    #[test]
1095    fn inheritable_variable_get_value_mut_and_mark_modified() {
1096        let mut v = InheritableVariable::from(42);
1097
1098        assert_eq!(v.get_value_mut_and_mark_modified(), &mut 42);
1099        assert_eq!(
1100            v,
1101            InheritableVariable {
1102                value: 42,
1103                flags: Cell::new(VariableFlags::MODIFIED),
1104            }
1105        );
1106    }
1107
1108    #[test]
1109    fn inheritable_variable_get_value_mut_silent() {
1110        let mut v = InheritableVariable::from(42);
1111
1112        assert_eq!(v.get_value_mut_silent(), &mut 42);
1113    }
1114
1115    #[test]
1116    fn inheritable_variable_is_modified() {
1117        let v = InheritableVariable::new_with_flags(42, VariableFlags::NONE);
1118        assert!(!v.is_modified());
1119
1120        let v = InheritableVariable::new_with_flags(42, VariableFlags::MODIFIED);
1121        assert!(v.is_modified());
1122    }
1123
1124    #[test]
1125    fn inheritable_variable_mark_modified() {
1126        let mut v = InheritableVariable::new_with_flags(42, VariableFlags::NONE);
1127        v.mark_modified();
1128
1129        assert_eq!(
1130            v,
1131            InheritableVariable {
1132                value: 42,
1133                flags: Cell::new(VariableFlags::MODIFIED),
1134            }
1135        );
1136    }
1137
1138    #[test]
1139    fn inheritable_variable_take() {
1140        let v = InheritableVariable::from(42);
1141
1142        assert_eq!(v.take(), 42);
1143    }
1144
1145    #[test]
1146    fn deref_mut_for_inheritable_variable() {
1147        let mut v = InheritableVariable::new_with_flags(42, VariableFlags::NONE);
1148        let res = v.deref_mut();
1149
1150        assert_eq!(res, &mut 42);
1151        assert_eq!(
1152            v,
1153            InheritableVariable {
1154                value: 42,
1155                flags: Cell::new(VariableFlags::MODIFIED),
1156            }
1157        );
1158    }
1159
1160    #[test]
1161    fn visit_for_inheritable_variable() {
1162        let mut v = InheritableVariable::from(42);
1163        let mut visitor = Visitor::default();
1164
1165        assert!(v.visit("name", &mut visitor).is_ok());
1166    }
1167
1168    #[test]
1169    fn inheritable_variable_type_name() {
1170        let v = InheritableVariable::from(42);
1171
1172        assert_eq!(Reflect::type_name(&v), "i32");
1173    }
1174
1175    #[test]
1176    fn inheritable_variable_doc() {
1177        let v = InheritableVariable::from(42);
1178
1179        assert_eq!(v.doc(), "");
1180    }
1181
1182    #[test]
1183    fn inheritable_variable_flags() {
1184        let v = InheritableVariable::new_with_flags(42, VariableFlags::NONE);
1185
1186        assert_eq!(v.flags(), VariableFlags::NONE);
1187    }
1188
1189    #[test]
1190    fn inheritable_variable_set_flags() {
1191        let mut v = InheritableVariable::new_with_flags(42, VariableFlags::NONE);
1192        v.set_flags(VariableFlags::NEED_SYNC);
1193
1194        assert_eq!(v.flags(), VariableFlags::NEED_SYNC);
1195    }
1196
1197    #[test]
1198    fn inheritable_variable_ref_cell() {
1199        let v = InheritableVariable::new_modified(RefCell::new(123u32));
1200        assert_eq!(
1201            v.inner_value_ref()
1202                .as_any_raw()
1203                .downcast_ref::<RefCell<u32>>(),
1204            Some(&RefCell::new(123u32))
1205        );
1206    }
1207}