Skip to main content

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