[NUI][API10] Reduce PropertyValue creation during Animation
authorEunki, Hong <eunkiki.hong@samsung.com>
Thu, 20 Oct 2022 12:30:37 +0000 (21:30 +0900)
committerdongsug-song <35130733+dongsug-song@users.noreply.github.com>
Thu, 20 Oct 2022 12:38:02 +0000 (21:38 +0900)
There was some PropertyValue creation during data conversion.
Let we reduce new PropertyValue class creation so GC feel happy

This patch is copy of https://github.com/Samsung/TizenFX/pull/4674

Signed-off-by: Eunki, Hong <eunkiki.hong@samsung.com>
src/Tizen.NUI/Tizen.NUI.csproj
src/Tizen.NUI/src/internal/Common/PropertyHelper.cs
src/Tizen.NUI/src/internal/Interop/Interop.Animation.cs
src/Tizen.NUI/src/internal/Interop/Interop.PropertyValue.cs
src/Tizen.NUI/src/public/Animation/Animation.cs
src/Tizen.NUI/src/public/Common/PropertyValue.cs

index 93e8196..889d37d 100755 (executable)
@@ -5,7 +5,7 @@
         <LangVersion>8.0</LangVersion>
     </PropertyGroup>
     <PropertyGroup>
-        <DefineConstants>NUI_DEBUG_OFF;NUI_PROPERTY_CHANGE_1;NUI_PROPERTY_CHANGE_2;NUI_PROPERTY_CHANGE_3;NUI_VISUAL_PROPERTY_CHANGE_1;</DefineConstants>
+        <DefineConstants>NUI_DEBUG_OFF;NUI_PROPERTY_CHANGE_1;NUI_PROPERTY_CHANGE_2;NUI_PROPERTY_CHANGE_3;NUI_VISUAL_PROPERTY_CHANGE_1;NUI_ANIMATION_PROPERTY_CHANGE_1;</DefineConstants>
     </PropertyGroup>
     <ItemGroup>
         <TizenPreloadFile Include="Tizen.NUI.preload"
index 7a11812..309600b 100755 (executable)
@@ -260,6 +260,27 @@ namespace Tizen.NUI
                 return PropertyValue.CreateFromObject(refined);
             }
 
+            // Refine object as IntPtr of PropertyValue to optimize.
+            // Warning : This API don't automatically release memory.
+            internal global::System.IntPtr RefineValueIntPtr(object value)
+            {
+                Debug.Assert(Property != null && value != null);
+
+                var refined = value;
+
+                if (objectConverter != null)
+                {
+                    refined = objectConverter(value);
+                }
+
+                if (refined == null)
+                {
+                    return global::System.IntPtr.Zero;
+                }
+
+                return PropertyValue.CreateFromObjectIntPtr(refined);
+            }
+
             internal KeyFrames RefineKeyFrames(KeyFrames keyFrames)
             {
                 Debug.Assert(keyFrames != null);
index 8e665f2..6c702b2 100755 (executable)
@@ -155,6 +155,32 @@ namespace Tizen.NUI
             [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_Animation_AnimateTo__SWIG_3")]
             public static extern void AnimateTo(global::System.Runtime.InteropServices.HandleRef jarg1, global::System.Runtime.InteropServices.HandleRef jarg2, global::System.Runtime.InteropServices.HandleRef jarg3, global::System.Runtime.InteropServices.HandleRef jarg4, global::System.Runtime.InteropServices.HandleRef jarg5);
 
+#if NUI_ANIMATION_PROPERTY_CHANGE_1
+            [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_Animation_AnimateBy__SWIG_0")]
+            public static extern void AnimateBy(global::System.Runtime.InteropServices.HandleRef jarg1, global::System.Runtime.InteropServices.HandleRef jarg2, global::System.IntPtr jarg3);
+
+            [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_Animation_AnimateBy__SWIG_1")]
+            public static extern void AnimateByAlphaFunction(global::System.Runtime.InteropServices.HandleRef jarg1, global::System.Runtime.InteropServices.HandleRef jarg2, global::System.IntPtr jarg3, global::System.Runtime.InteropServices.HandleRef jarg4);
+
+            [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_Animation_AnimateBy__SWIG_2")]
+            public static extern void AnimateByTimePeriod(global::System.Runtime.InteropServices.HandleRef jarg1, global::System.Runtime.InteropServices.HandleRef jarg2, global::System.IntPtr jarg3, global::System.Runtime.InteropServices.HandleRef jarg4);
+
+            [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_Animation_AnimateBy__SWIG_3")]
+            public static extern void AnimateBy(global::System.Runtime.InteropServices.HandleRef jarg1, global::System.Runtime.InteropServices.HandleRef jarg2, global::System.IntPtr jarg3, global::System.Runtime.InteropServices.HandleRef jarg4, global::System.Runtime.InteropServices.HandleRef jarg5);
+
+            [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_Animation_AnimateTo__SWIG_0")]
+            public static extern void AnimateTo(global::System.Runtime.InteropServices.HandleRef jarg1, global::System.Runtime.InteropServices.HandleRef jarg2, global::System.IntPtr jarg3);
+
+            [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_Animation_AnimateTo__SWIG_1")]
+            public static extern void AnimateToAlphaFunction(global::System.Runtime.InteropServices.HandleRef jarg1, global::System.Runtime.InteropServices.HandleRef jarg2, global::System.IntPtr jarg3, global::System.Runtime.InteropServices.HandleRef jarg4);
+
+            [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_Animation_AnimateTo__SWIG_2")]
+            public static extern void AnimateToTimePeriod(global::System.Runtime.InteropServices.HandleRef jarg1, global::System.Runtime.InteropServices.HandleRef jarg2, global::System.IntPtr jarg3, global::System.Runtime.InteropServices.HandleRef jarg4);
+
+            [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_Animation_AnimateTo__SWIG_3")]
+            public static extern void AnimateTo(global::System.Runtime.InteropServices.HandleRef jarg1, global::System.Runtime.InteropServices.HandleRef jarg2, global::System.IntPtr jarg3, global::System.Runtime.InteropServices.HandleRef jarg4, global::System.Runtime.InteropServices.HandleRef jarg5);
+#endif
+
             [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_Animation_AnimateBetween__SWIG_0")]
             public static extern void AnimateBetween(global::System.Runtime.InteropServices.HandleRef jarg1, global::System.Runtime.InteropServices.HandleRef jarg2, global::System.Runtime.InteropServices.HandleRef jarg3);
 
index 57f1ebb..e9544dc 100755 (executable)
@@ -89,6 +89,11 @@ namespace Tizen.NUI
             [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_delete_Property_Value")]
             public static extern void DeletePropertyValue(global::System.Runtime.InteropServices.HandleRef jarg1);
 
+#if NUI_ANIMATION_PROPERTY_CHANGE_1
+            [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_delete_Property_Value")]
+            public static extern void DeletePropertyValueIntPtr(global::System.IntPtr jarg1);
+#endif
+
             [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_Property_Value_GetType")]
             public static extern int PropertyValueGetType(global::System.Runtime.InteropServices.HandleRef jarg1);
 
index dece1b7..3a42d98 100755 (executable)
@@ -666,9 +666,19 @@ namespace Tizen.NUI
                 var current = result;
                 while (current != null)
                 {
+#if NUI_ANIMATION_PROPERTY_CHANGE_1
+                    var targetValueIntPtr = current.RefineValueIntPtr(relativeValue);
+                    if (targetValueIntPtr == global::System.IntPtr.Zero)
+                    {
+                        throw new ArgumentException("Invalid " + nameof(relativeValue));
+                    }
+                    AnimateByIntPtr(current.Property, targetValueIntPtr, alphaFunction);
+                    Interop.PropertyValue.DeletePropertyValueIntPtr(targetValueIntPtr);
+#else
                     var targetValue = current.RefineValue(relativeValue) ?? throw new ArgumentException("Invalid " + nameof(relativeValue));
                     AnimateBy(current.Property, targetValue, alphaFunction);
                     targetValue.Dispose();
+#endif
                     current = current.NextResult;
                 }
             }
@@ -712,9 +722,19 @@ namespace Tizen.NUI
                 using (var time = new TimePeriod(startTime, endTime - startTime))
                     while (current != null)
                     {
+#if NUI_ANIMATION_PROPERTY_CHANGE_1
+                        var targetValueIntPtr = current.RefineValueIntPtr(relativeValue);
+                        if (targetValueIntPtr == global::System.IntPtr.Zero)
+                        {
+                            throw new ArgumentException("Invalid " + nameof(relativeValue));
+                        }
+                        AnimateByIntPtr(current.Property, targetValueIntPtr, alphaFunction, time);
+                        Interop.PropertyValue.DeletePropertyValueIntPtr(targetValueIntPtr);
+#else
                         var targetValue = current.RefineValue(relativeValue) ?? throw new ArgumentException("Invalid " + nameof(relativeValue));
                         AnimateBy(current.Property, targetValue, alphaFunction, time);
                         targetValue.Dispose();
+#endif
                         current = current.NextResult;
                     }
             }
@@ -755,9 +775,19 @@ namespace Tizen.NUI
                 var current = result;
                 while (current != null)
                 {
+#if NUI_ANIMATION_PROPERTY_CHANGE_1
+                    var targetValueIntPtr = current.RefineValueIntPtr(destinationValue);
+                    if (targetValueIntPtr == global::System.IntPtr.Zero)
+                    {
+                        throw new ArgumentException("Invalid " + nameof(destinationValue));
+                    }
+                    AnimateToIntPtr(current.Property, targetValueIntPtr, alphaFunction);
+                    Interop.PropertyValue.DeletePropertyValueIntPtr(targetValueIntPtr);
+#else
                     var targetValue = current.RefineValue(destinationValue) ?? throw new ArgumentException("Invalid " + nameof(destinationValue));
                     AnimateTo(current.Property, targetValue, alphaFunction);
                     targetValue.Dispose();
+#endif
                     current = current.NextResult;
                 }
             }
@@ -868,9 +898,19 @@ namespace Tizen.NUI
                 using (var time = new TimePeriod(startTime, endTime - startTime))
                     while (current != null)
                     {
+#if NUI_ANIMATION_PROPERTY_CHANGE_1
+                        var targetValueIntPtr = current.RefineValueIntPtr(destinationValue);
+                        if (targetValueIntPtr == global::System.IntPtr.Zero)
+                        {
+                            throw new ArgumentException("Invalid " + nameof(destinationValue));
+                        }
+                        AnimateToIntPtr(current.Property, targetValueIntPtr, alphaFunction, time);
+                        Interop.PropertyValue.DeletePropertyValueIntPtr(targetValueIntPtr);
+#else
                         var targetValue = current.RefineValue(destinationValue) ?? throw new ArgumentException("Invalid " + nameof(destinationValue));
                         AnimateTo(current.Property, targetValue, alphaFunction, time);
                         targetValue.Dispose();
+#endif
                         current = current.NextResult;
                     }
             }
@@ -1442,6 +1482,60 @@ namespace Tizen.NUI
             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
         }
 
+#if NUI_ANIMATION_PROPERTY_CHANGE_1
+        internal void AnimateByIntPtr(Property target, global::System.IntPtr relativeValueIntPtr, AlphaFunction alpha)
+        {
+            if (alpha == null)
+            {
+                Interop.Animation.AnimateBy(SwigCPtr, Property.getCPtr(target), relativeValueIntPtr);
+            }
+            else
+            {
+                Interop.Animation.AnimateByAlphaFunction(SwigCPtr, Property.getCPtr(target), relativeValueIntPtr, AlphaFunction.getCPtr(alpha));
+            }
+            if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
+        }
+
+        internal void AnimateByIntPtr(Property target, global::System.IntPtr relativeValueIntPtr, AlphaFunction alpha, TimePeriod period)
+        {
+            if (alpha == null)
+            {
+                Interop.Animation.AnimateByTimePeriod(SwigCPtr, Property.getCPtr(target), relativeValueIntPtr, TimePeriod.getCPtr(period));
+            }
+            else
+            {
+                Interop.Animation.AnimateBy(SwigCPtr, Property.getCPtr(target), relativeValueIntPtr, AlphaFunction.getCPtr(alpha), TimePeriod.getCPtr(period));
+            }
+            if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
+        }
+
+        internal void AnimateToIntPtr(Property target, global::System.IntPtr destinationValueIntPtr, AlphaFunction alpha)
+        {
+            if (alpha == null)
+            {
+                Interop.Animation.AnimateTo(SwigCPtr, Property.getCPtr(target), destinationValueIntPtr);
+            }
+            else
+            {
+                Interop.Animation.AnimateToAlphaFunction(SwigCPtr, Property.getCPtr(target), destinationValueIntPtr, AlphaFunction.getCPtr(alpha));
+            }
+            if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
+        }
+
+        internal void AnimateToIntPtr(Property target, global::System.IntPtr destinationValueIntPtr, AlphaFunction alpha, TimePeriod period)
+        {
+            if (alpha == null)
+            {
+                Interop.Animation.AnimateToTimePeriod(SwigCPtr, Property.getCPtr(target), destinationValueIntPtr, TimePeriod.getCPtr(period));
+            }
+            else
+            {
+                Interop.Animation.AnimateTo(SwigCPtr, Property.getCPtr(target), destinationValueIntPtr, AlphaFunction.getCPtr(alpha), TimePeriod.getCPtr(period));
+            }
+            if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
+        }
+#endif
+
         internal void AnimateBetween(Property target, KeyFrames keyFrames)
         {
             Interop.Animation.AnimateBetween(SwigCPtr, Property.getCPtr(target), KeyFrames.getCPtr(keyFrames));
index a82f1d5..5c926c6 100755 (executable)
@@ -417,6 +417,112 @@ namespace Tizen.NUI
             return value;
         }
 
+#if NUI_ANIMATION_PROPERTY_CHANGE_1
+        /// <summary>
+        /// An extension to the property value class that allows us to create a
+        /// Property value from a C# object, for example, integer, float, or string.<br />
+        /// Warning : This API don't automatically release memory.
+        /// </summary>
+        /// <param name="obj">An object to create.</param>
+        /// <returns>The created value's IntPtr.</returns>
+        /// <exception cref="global::System.ArgumentNullException"> Thrown when obj is null. </exception>
+        static internal global::System.IntPtr CreateFromObjectIntPtr(System.Object obj)
+        {
+            if (null == obj)
+            {
+                throw new global::System.ArgumentNullException(nameof(obj));
+            }
+
+            System.Type type = obj.GetType();
+            global::System.IntPtr value = global::System.IntPtr.Zero;
+            if (type.IsEnum)
+            {
+                value = Interop.PropertyValue.NewPropertyValue((int)obj);//Enum.Parse(type, str);
+            }
+            else if (type.Equals(typeof(int)))
+            {
+                value = Interop.PropertyValue.NewPropertyValue((int)obj);
+            }
+            else if (type.Equals(typeof(System.Int32)))
+            {
+                value = Interop.PropertyValue.NewPropertyValue((int)obj);
+            }
+            else if (type.Equals(typeof(bool)))
+            {
+                value = Interop.PropertyValue.NewPropertyValue((bool)obj);
+            }
+            else if (type.Equals(typeof(float)))
+            {
+                value = Interop.PropertyValue.NewPropertyValue((float)obj);
+            }
+            else if (type.Equals(typeof(string)))
+            {
+                value = Interop.PropertyValue.NewPropertyValueString((string)obj);
+            }
+            else if (type.Equals(typeof(Vector2)))
+            {
+                value = Interop.PropertyValue.NewPropertyValueVector2(Vector2.getCPtr((Vector2)obj));
+            }
+            else if (type.Equals(typeof(Vector3)))
+            {
+                value = Interop.PropertyValue.NewPropertyValueVector3(Vector3.getCPtr((Vector3)obj));
+            }
+            else if (type.Equals(typeof(Vector4)))
+            {
+                value = Interop.PropertyValue.NewPropertyValueVector4(Vector4.getCPtr((Vector4)obj));
+            }
+            else if (type.Equals(typeof(Position)))
+            {
+                value = Interop.PropertyValue.NewPropertyValueVector3(Position.getCPtr((Position)obj));
+            }
+            else if (type.Equals(typeof(Position2D)))
+            {
+                value = Interop.PropertyValue.NewPropertyValueVector2(Position2D.getCPtr((Position2D)obj));
+            }
+            else if (type.Equals(typeof(Size)))
+            {
+                value = Interop.PropertyValue.NewPropertyValueVector3(Size.getCPtr((Size)obj));
+            }
+            else if (type.Equals(typeof(Size2D)))
+            {
+                value = Interop.PropertyValue.NewPropertyValueVector2(Size2D.getCPtr((Size2D)obj));
+            }
+            else if (type.Equals(typeof(Color)))
+            {
+                value = Interop.PropertyValue.NewPropertyValueVector4(Color.getCPtr((Color)obj));
+            }
+            else if (type.Equals(typeof(Rotation)))
+            {
+                value = Interop.PropertyValue.NewPropertyValueQuaternion(Rotation.getCPtr((Rotation)obj));
+            }
+            else if (type.Equals(typeof(RelativeVector2)))
+            {
+                value = Interop.PropertyValue.NewPropertyValueVector2(RelativeVector2.getCPtr((RelativeVector2)obj));
+            }
+            else if (type.Equals(typeof(RelativeVector3)))
+            {
+                value = Interop.PropertyValue.NewPropertyValueVector3(RelativeVector3.getCPtr((RelativeVector3)obj));
+            }
+            else if (type.Equals(typeof(RelativeVector4)))
+            {
+                value = Interop.PropertyValue.NewPropertyValueVector4(RelativeVector4.getCPtr((RelativeVector4)obj));
+            }
+            else if (type.Equals(typeof(Extents)))
+            {
+                value = Interop.PropertyValue.NewPropertyValueExtents(Extents.getCPtr((Extents)obj));
+            }
+            else if (type.Equals(typeof(Rectangle)))
+            {
+                value = Interop.PropertyValue.NewPropertyValueRect(Rectangle.getCPtr((Rectangle)obj));
+            }
+            else
+            {
+                throw new global::System.InvalidOperationException("Unimplemented type for Property Value :" + type.Name);
+            }
+            return value;
+        }
+#endif
+
         /// <summary>
         /// Retrieves a Size2D value.
         /// </summary>