[NUI] Fix FlexLayout not to use Dictionary taking child views
authorJaehyun Cho <jae_hyun.cho@samsung.com>
Thu, 17 Apr 2025 12:24:30 +0000 (21:24 +0900)
committerJiyun Yang <ji.yang@samsung.com>
Wed, 23 Apr 2025 05:51:52 +0000 (14:51 +0900)
Not to block GC of child views, Dictionary taking child views is removed
from FlexLayout.

src/Tizen.NUI/src/public/Layouting/FlexLayout.cs

index b6cc92ff7ba3c0a30b93cae9a2aa7092a95a157e..cc35f1b7e2aebceb77bcbd2a6e9731775f2fb815 100755 (executable)
@@ -20,7 +20,6 @@ using Tizen.NUI.BaseComponents;
 using System.Runtime.InteropServices;
 using System.Diagnostics;
 using Tizen.NUI.Binding;
-using System.Collections.Generic;
 
 namespace Tizen.NUI
 {
@@ -89,14 +88,6 @@ namespace Tizen.NUI
         [EditorBrowsable(EditorBrowsableState.Never)]
         public static readonly BindableProperty FlexGrowProperty = null;
 
-        private static Dictionary<View, AlignmentType> flexAlignmentSelfMap;
-        private static Dictionary<View, float> flexAspectRatioMap;
-        private static Dictionary<View, float> flexBasisMap;
-        private static Dictionary<View, float> flexShrinkMap;
-        private static Dictionary<View, float> flexGrowMap;
-
-        private Dictionary<View, HandleRef> childHandleRefMap;
-
         private global::System.Runtime.InteropServices.HandleRef swigCPtr;
         private bool swigCMemOwn;
         private bool disposed;
@@ -134,14 +125,8 @@ namespace Tizen.NUI
             }
             else
             {
-                if (flexAlignmentSelfMap.TryGetValue(view, out var flexAlignmentSelf))
-                {
-                    return flexAlignmentSelf;
-                }
-                else
-                {
-                    return AlignmentType.Auto;
-                }
+                _ = view ?? throw new ArgumentNullException(nameof(view));
+                return view.GetAttached<LayoutParams>()?.FlexAlignmentSelf ?? AlignmentType.Auto;
             }
         }
 
@@ -185,14 +170,8 @@ namespace Tizen.NUI
             }
             else
             {
-                if (flexAspectRatioMap.TryGetValue(view, out var flexAspectRatio))
-                {
-                    return flexAspectRatio;
-                }
-                else
-                {
-                    return FlexUndefined;
-                }
+                _ = view ?? throw new ArgumentNullException(nameof(view));
+                return view.GetAttached<LayoutParams>()?.FlexAspectRatio ?? FlexUndefined;
             }
         }
 
@@ -212,14 +191,8 @@ namespace Tizen.NUI
             }
             else
             {
-                if (flexBasisMap.TryGetValue(view, out var flexBasis))
-                {
-                    return flexBasis;
-                }
-                else
-                {
-                    return FlexUndefined;
-                }
+                _ = view ?? throw new ArgumentNullException(nameof(view));
+                return view.GetAttached<LayoutParams>()?.FlexBasis ?? FlexUndefined;
             }
         }
 
@@ -239,14 +212,8 @@ namespace Tizen.NUI
             }
             else
             {
-                if (flexShrinkMap.TryGetValue(view, out var flexShrink))
-                {
-                    return flexShrink;
-                }
-                else
-                {
-                    return 1.0f;
-                }
+                _ = view ?? throw new ArgumentNullException(nameof(view));
+                return view.GetAttached<LayoutParams>()?.FlexShrink ?? 1.0f;
             }
         }
 
@@ -266,14 +233,8 @@ namespace Tizen.NUI
             }
             else
             {
-                if (flexGrowMap.TryGetValue(view, out var flexGrow))
-                {
-                    return flexGrow;
-                }
-                else
-                {
-                    return FlexUndefined;
-                }
+                _ = view ?? throw new ArgumentNullException(nameof(view));
+                return view.GetAttached<LayoutParams>()?.FlexGrow ?? FlexUndefined;
             }
         }
 
@@ -299,8 +260,15 @@ namespace Tizen.NUI
                 _ = view ?? throw new ArgumentNullException(nameof(view));
                 if (value >= AlignmentType.Auto && value <= AlignmentType.Stretch)
                 {
-                    flexAlignmentSelfMap[view] = value;
-                    view.Layout?.RequestLayout();
+                    var layoutParams = view.GetAttached<LayoutParams>();
+                    if (layoutParams != null)
+                    {
+                        layoutParams.FlexAlignmentSelf = value;
+                    }
+                    else
+                    {
+                        view.SetAttached(new LayoutParams() { FlexAlignmentSelf = value });
+                    }
                 }
             }
         }
@@ -356,8 +324,15 @@ namespace Tizen.NUI
                 _ = view ?? throw new ArgumentNullException(nameof(view));
                 if (value > 0)
                 {
-                    flexAspectRatioMap[view] = value;
-                    view.Layout?.RequestLayout();
+                    var layoutParams = view.GetAttached<LayoutParams>();
+                    if (layoutParams != null)
+                    {
+                        layoutParams.FlexAspectRatio = value;
+                    }
+                    else
+                    {
+                        view.SetAttached(new LayoutParams() { FlexAspectRatio = value });
+                    }
                 }
             }
         }
@@ -385,8 +360,15 @@ namespace Tizen.NUI
                 _ = view ?? throw new ArgumentNullException(nameof(view));
                 if (value >= 0)
                 {
-                    flexBasisMap[view] = value;
-                    view.Layout?.RequestLayout();
+                    var layoutParams = view.GetAttached<LayoutParams>();
+                    if (layoutParams != null)
+                    {
+                        layoutParams.FlexBasis = value;
+                    }
+                    else
+                    {
+                        view.SetAttached(new LayoutParams() { FlexBasis = value });
+                    }
                 }
             }
         }
@@ -414,8 +396,15 @@ namespace Tizen.NUI
                 _ = view ?? throw new ArgumentNullException(nameof(view));
                 if (value >= 0)
                 {
-                    flexShrinkMap[view] = value;
-                    view.Layout?.RequestLayout();
+                    var layoutParams = view.GetAttached<LayoutParams>();
+                    if (layoutParams != null)
+                    {
+                        layoutParams.FlexShrink = value;
+                    }
+                    else
+                    {
+                        view.SetAttached(new LayoutParams() { FlexShrink = value });
+                    }
                 }
             }
         }
@@ -443,8 +432,15 @@ namespace Tizen.NUI
                 _ = view ?? throw new ArgumentNullException(nameof(view));
                 if (value >= 0)
                 {
-                    flexGrowMap[view] = value;
-                    view.Layout?.RequestLayout();
+                    var layoutParams = view.GetAttached<LayoutParams>();
+                    if (layoutParams != null)
+                    {
+                        layoutParams.FlexGrow = value;
+                    }
+                    else
+                    {
+                        view.SetAttached(new LayoutParams() { FlexGrow = value });
+                    }
                 }
             }
         }
@@ -472,14 +468,6 @@ namespace Tizen.NUI
                 FlexGrowProperty = BindableProperty.CreateAttached("FlexGrow", typeof(float), typeof(FlexLayout), FlexUndefined,
                     validateValue: (bindable, value) => (float)value >= 0, propertyChanged: OnChildPropertyChanged);
             }
-            else
-            {
-                flexAlignmentSelfMap = new Dictionary<View, AlignmentType>();
-                flexAspectRatioMap = new Dictionary<View, float>();
-                flexBasisMap = new Dictionary<View, float>();
-                flexShrinkMap = new Dictionary<View, float>();
-                flexGrowMap = new Dictionary<View, float>();
-            }
         }
 
         internal FlexLayout(global::System.IntPtr cPtr, bool cMemoryOwn)
@@ -487,10 +475,6 @@ namespace Tizen.NUI
             swigCMemOwn = cMemoryOwn;
             swigCPtr = new global::System.Runtime.InteropServices.HandleRef(this, cPtr);
             measureChildDelegate = new ChildMeasureCallback(measureChild);
-            if (!NUIApplication.IsUsingXaml)
-            {
-                childHandleRefMap = new Dictionary<View, HandleRef>();
-            }
         }
 
         internal static global::System.Runtime.InteropServices.HandleRef getCPtr(FlexLayout obj)
@@ -899,7 +883,15 @@ namespace Tizen.NUI
             }
             else
             {
-                childHandleRefMap[child.Owner] = childHandleRef;
+                var layoutParams = child.Owner.GetAttached<LayoutParams>();
+                if (layoutParams != null)
+                {
+                    layoutParams.FlexItem = childHandleRef;
+                }
+                else
+                {
+                    child.Owner.SetAttached(new LayoutParams() { FlexItem = childHandleRef });
+                }
             }
         }
 
@@ -975,6 +967,9 @@ namespace Tizen.NUI
             {
                 LayoutItem layoutItem = LayoutChildren[i];
                 View Child = layoutItem?.Owner;
+                if (Child == null)
+                    continue;
+
                 HandleRef childHandleRef;
                 if (NUIApplication.IsUsingXaml)
                 {
@@ -982,9 +977,9 @@ namespace Tizen.NUI
                 }
                 else
                 {
-                    childHandleRef = childHandleRefMap[Child];
+                    childHandleRef = Child.GetAttached<LayoutParams>()?.FlexItem ?? new HandleRef();
                 }
-                if (childHandleRef.Handle == IntPtr.Zero || Child == null)
+                if (childHandleRef.Handle == IntPtr.Zero)
                     continue;
 
                 AlignmentType flexAlignemnt = GetFlexAlignmentSelf(Child);
@@ -1067,5 +1062,69 @@ namespace Tizen.NUI
                 }
             }
         }
+
+        private class LayoutParams
+        {
+            /// <summary>
+            /// Constructs LayoutParams.
+            /// </summary>
+            public LayoutParams()
+            {
+            }
+
+            /// <summary>
+            /// Gets or sets the alignment of the flex layout item.
+            /// </summary>
+            public AlignmentType FlexAlignmentSelf
+            {
+                get;
+                set;
+            } = AlignmentType.Auto;
+
+            /// <summary>
+            /// Gets or sets the aspect ratio of the flex layout item.
+            /// </summary>
+            public float FlexAspectRatio
+            {
+                get;
+                set;
+            } = FlexUndefined;
+
+            /// <summary>
+            /// Gets or sets the basis of the flex layout item.
+            /// </summary>
+            public float FlexBasis
+            {
+                get;
+                set;
+            } = FlexUndefined;
+
+            /// <summary>
+            /// Gets or sets the shrink of the flex layout item.
+            /// </summary>
+            public float FlexShrink
+            {
+                get;
+                set;
+            } = 1.0f;
+
+            /// <summary>
+            /// Gets or sets the grow of the flex layout item.
+            /// </summary>
+            public float FlexGrow
+            {
+                get;
+                set;
+            } = FlexUndefined;
+
+            /// <summary>
+            /// Gets or sets the item handle of the flex layout item.
+            /// </summary>
+            public HandleRef FlexItem
+            {
+                get;
+                set;
+            } = new HandleRef();
+        }
     } // FLexlayout
 } // namesspace Tizen.NUI