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