Skip to content

Commit

Permalink
[NUI] Extract View variables for Layout to remove wasted memory
Browse files Browse the repository at this point in the history
If an application does not use Layout, then View's variables used for
Layout waste memory.
To remove those wasted memory, those variables are moved to the new
internal class LayoutExtraData and it is not allocated if Layout is not
used.

Signed-off-by: Jiyun Yang <[email protected]>
  • Loading branch information
rabbitfor authored and jaehyun0cho committed Jan 22, 2025
1 parent b946acc commit a5e9501
Show file tree
Hide file tree
Showing 5 changed files with 142 additions and 88 deletions.
134 changes: 59 additions & 75 deletions src/Tizen.NUI/src/public/BaseComponents/View.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright(c) 2022 Samsung Electronics Co., Ltd.
* Copyright(c) 2017-2025 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -35,18 +35,9 @@ public partial class View : Container, IResourcesProvider
private static bool defaultAllowOnlyOwnTouch = false;

internal BackgroundExtraData backgroundExtraData;

private bool layoutSet = false;
private LayoutItem layout; // Exclusive layout assigned to this View.

// List of transitions paired with the condition that uses the transition.
private Dictionary<TransitionCondition, TransitionList> layoutTransitions;
private int widthPolicy = LayoutParamPolicies.WrapContent; // Layout width policy
private int heightPolicy = LayoutParamPolicies.WrapContent; // Layout height policy
private float weight = 0.0f; // Weighting of child View in a Layout
private bool excludeLayouting = false;
private LayoutTransition layoutTransition;
private TransitionOptions transitionOptions = null;
private int widthPolicy = LayoutParamPolicies.WrapContent;
private int heightPolicy = LayoutParamPolicies.WrapContent;
private LayoutExtraData layoutExtraData;
private ThemeData themeData;
private Dictionary<Type, object> attached;
private bool isThemeChanged = false;
Expand Down Expand Up @@ -574,13 +565,7 @@ internal View(ViewImpl implementation, bool shown = true) : this(Interop.View.Ne
/// </summary>
/// This will be public opened after ACR done. Before ACR, need to be hidden as inhouse API.
[EditorBrowsable(EditorBrowsableState.Never)]
public bool LayoutSet
{
get
{
return layoutSet;
}
}
public bool LayoutSet => layoutExtraData?.LayoutSet ?? false;

/// <summary>
/// Flag to allow Layouting to be disabled for Views.
Expand Down Expand Up @@ -807,13 +792,10 @@ internal void SetInternalExcludeLayouting(bool excludeLayouting)

private bool InternalExcludeLayouting
{
get
{
return excludeLayouting;
}
get => layoutExtraData?.ExcludeLayouting ?? false;
set
{
excludeLayouting = value;
EnsureLayoutExtraData().ExcludeLayouting = value;
if (Layout != null && Layout.SetPositionByLayout == value)
{
Layout.SetPositionByLayout = !value;
Expand Down Expand Up @@ -2911,7 +2893,7 @@ internal void SetInternalSizeWidth(float sizeWidth)
if (widthPolicy != widthPolicyCeiling)
{
widthPolicy = widthPolicyCeiling;
layout?.RequestLayout();
RequestLayout();
}

Object.InternalSetPropertyFloat(SwigCPtr, Property.SizeWidth, width);
Expand Down Expand Up @@ -2975,7 +2957,7 @@ internal void SetInternalSizeHeight(float sizeHeight)
if (heightPolicy != heightPolicyCeiling)
{
heightPolicy = heightPolicyCeiling;
layout?.RequestLayout();
RequestLayout();
}

Object.InternalSetPropertyFloat(SwigCPtr, Property.SizeHeight, height);
Expand Down Expand Up @@ -4208,7 +4190,7 @@ public Size2D MinimumSize
{
throw new ArgumentNullException(nameof(value));
}
if (layout != null)
if (layoutExtraData?.Layout is LayoutItem layout)
{
// Note: it only works if minimum size is >= than natural size.
// To force the size it should be done through the width&height spec or Size2D.
Expand Down Expand Up @@ -4260,10 +4242,7 @@ public Size2D MaximumSize
{
// We don't have Layout.Maximum(Width|Height) so we cannot apply it to layout.
// MATCH_PARENT spec + parent container size can be used to limit
if (layout != null)
{
layout.RequestLayout();
}
RequestLayout();

if (NUIApplication.IsUsingXaml)
{
Expand Down Expand Up @@ -4578,7 +4557,7 @@ public ViewLayoutDirectionType LayoutDirection
SetInternalLayoutDirection(value);
}
NotifyPropertyChanged();
layout?.RequestLayout();
RequestLayout();
}
}

Expand Down Expand Up @@ -4711,7 +4690,7 @@ private int InternalWidthSpecification
{
SizeWidth = widthPolicy;
}
layout?.RequestLayout();
RequestLayout();
}
}

Expand Down Expand Up @@ -4786,7 +4765,7 @@ private int InternalHeightSpecification
{
SizeHeight = heightPolicy;
}
layout?.RequestLayout();
RequestLayout();
}
}

Expand All @@ -4798,11 +4777,13 @@ public Dictionary<TransitionCondition, TransitionList> LayoutTransitions
{
get
{
if (layoutTransitions == null)
var layoutExtraData = EnsureLayoutExtraData();

if (layoutExtraData.LayoutTransitions == null)
{
layoutTransitions = new Dictionary<TransitionCondition, TransitionList>();
layoutExtraData.LayoutTransitions = new Dictionary<TransitionCondition, TransitionList>();
}
return layoutTransitions;
return layoutExtraData.LayoutTransitions;
}
}

Expand Down Expand Up @@ -4843,26 +4824,26 @@ public LayoutTransition LayoutTransition

private LayoutTransition InternalLayoutTransition
{
get
{
return layoutTransition;
}
get => EnsureLayoutExtraData().LayoutTransition;
set
{
if (value == null)
{
throw new global::System.ArgumentNullException(nameof(value));
}
if (layoutTransitions == null)

var layoutExtraData = EnsureLayoutExtraData();

if (layoutExtraData.LayoutTransitions == null)
{
layoutTransitions = new Dictionary<TransitionCondition, TransitionList>();
layoutExtraData.LayoutTransitions = new Dictionary<TransitionCondition, TransitionList>();
}

LayoutTransitionsHelper.AddTransitionForCondition(layoutTransitions, value.Condition, value, true);
LayoutTransitionsHelper.AddTransitionForCondition(layoutExtraData.LayoutTransitions, value.Condition, value, true);

AttachTransitionsToChildren(value);

layoutTransition = value;
layoutExtraData.LayoutTransition = value;
}
}

Expand Down Expand Up @@ -4919,7 +4900,7 @@ private Extents InternalPaddingEX
SetProperty(View.Property.PADDING, temp);
temp.Dispose();
NotifyPropertyChanged();
layout?.RequestLayout();
RequestLayout();
}
}

Expand Down Expand Up @@ -5146,20 +5127,19 @@ public LayoutItem Layout

private LayoutItem InternalLayout
{
get
{
return layout;
}
get => layoutExtraData?.Layout;
set
{
var layoutExtraData = EnsureLayoutExtraData();

// Do nothing if layout provided is already set on this View.
if (value == layout)
if (value == layoutExtraData.Layout)
{
return;
}

LayoutingDisabled = false;
layoutSet = true;
layoutExtraData.LayoutSet = true;

// If new layout being set already has a owner then that owner receives a replacement default layout.
// First check if the layout to be set already has a owner.
Expand All @@ -5177,20 +5157,20 @@ private LayoutItem InternalLayout
// Copy Margin and Padding to new layout being set or restore padding and margin back to
// View if no replacement. Previously margin and padding values would have been moved from
// the View to the layout.
if (layout != null) // Existing layout
if (layoutExtraData.Layout != null) // Existing layout
{
if (value != null)
{
// Existing layout being replaced so copy over margin and padding values.
value.Margin = layout.Margin;
value.Padding = layout.Padding;
value.SetPositionByLayout = !excludeLayouting;
value.Margin = layoutExtraData.Layout.Margin;
value.Padding = layoutExtraData.Layout.Padding;
value.SetPositionByLayout = !layoutExtraData.ExcludeLayouting;
}
else
{
// Layout not being replaced so restore margin and padding to View.
SetValue(MarginProperty, layout.Margin);
SetValue(PaddingProperty, layout.Padding);
SetValue(MarginProperty, layoutExtraData.Layout.Margin);
SetValue(PaddingProperty, layoutExtraData.Layout.Padding);
NotifyPropertyChanged();
}
}
Expand Down Expand Up @@ -5233,12 +5213,12 @@ private LayoutItem InternalLayout
NotifyPropertyChanged();
}

value.SetPositionByLayout = !excludeLayouting;
value.SetPositionByLayout = !layoutExtraData.ExcludeLayouting;
}
}

// Remove existing layout from it's parent layout group.
layout?.Unparent();
layoutExtraData.Layout?.Unparent();

// Set layout to this view
SetLayout(value);
Expand All @@ -5251,14 +5231,12 @@ private LayoutItem InternalLayout
/// <since_tizen> 6 </since_tizen>
public float Weight
{
get
{
return weight;
}
get => layoutExtraData?.Weight ?? 0;
set
{
weight = value;
layout?.RequestLayout();
var layoutExtraData = EnsureLayoutExtraData();
layoutExtraData.Weight = value;
layoutExtraData.Layout?.RequestLayout();
}
}

Expand Down Expand Up @@ -5922,14 +5900,8 @@ public TransitionOptions TransitionOptions

private TransitionOptions InternalTransitionOptions
{
set
{
transitionOptions = value;
}
get
{
return transitionOptions;
}
get => layoutExtraData?.TransitionOptions;
set => EnsureLayoutExtraData().TransitionOptions = value;
}

/// <summary>
Expand Down Expand Up @@ -6024,5 +5996,17 @@ private OffScreenRenderingType GetInternalOffScreenRendering()
default: return OffScreenRenderingType.None;
}
}

private LayoutExtraData EnsureLayoutExtraData()
{
if (layoutExtraData == null)
{
layoutExtraData = new LayoutExtraData();
}

return layoutExtraData;
}

private void RequestLayout() => layoutExtraData?.Layout?.RequestLayout();
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright(c) 2019-2022 Samsung Electronics Co., Ltd.
* Copyright(c) 2019-2025 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -798,12 +798,13 @@ internal static void SetInternalSize2DProperty(BindableObject bindable, object o
}
if (relayoutRequired)
{
view.layout?.RequestLayout();
view.RequestLayout();
}

Object.InternalSetPropertyVector2ActualVector3(view.SwigCPtr, View.Property.SIZE, ((Size2D)newValue).SwigCPtr);
}
}

internal static object GetInternalSize2DProperty(BindableObject bindable)
{
var view = (View)bindable;
Expand Down Expand Up @@ -1577,7 +1578,7 @@ internal static void SetInternalSizeProperty(BindableObject bindable, object old
}
if (relayoutRequired)
{
view.layout?.RequestLayout();
view.RequestLayout();
}

view.SetSize(width, height, depth);
Expand Down
8 changes: 4 additions & 4 deletions src/Tizen.NUI/src/public/BaseComponents/ViewInternal.cs
Original file line number Diff line number Diff line change
Expand Up @@ -192,9 +192,9 @@ internal void SetLayout(LayoutItem layout)
{
LayoutCount++;

this.layout = layout;
this.layout?.AttachToOwner(this);
this.layout?.RequestLayout();
EnsureLayoutExtraData().Layout = layout;
layout?.AttachToOwner(this);
layout?.RequestLayout();
}

internal void AttachTransitionsToChildren(LayoutTransition transition)
Expand Down Expand Up @@ -1172,7 +1172,7 @@ internal void ResetLayout()
{
LayoutCount--;

layout = null;
EnsureLayoutExtraData().Layout = null;
}

internal ResourceLoadingStatusType GetBackgroundResourceStatus()
Expand Down
8 changes: 2 additions & 6 deletions src/Tizen.NUI/src/public/BaseComponents/ViewPublicMethods.cs
Original file line number Diff line number Diff line change
Expand Up @@ -127,8 +127,6 @@ public Animation AnimateColor(string targetVisual, object destinationColor, int
/// <since_tizen> 4 </since_tizen>
public override void Add(View child)
{
bool hasLayout = (layout != null);

if (null == child)
{
Tizen.Log.Fatal("NUI", "Child is null");
Expand Down Expand Up @@ -186,14 +184,12 @@ public override void Remove(View child)
return;
}

bool hasLayout = (layout != null);

// If View has a layout then do a deferred child removal
// Actual child removal is performed by the layouting system so
// transitions can be completed.
if (hasLayout)
if (Layout != null)
{
(layout as LayoutGroup)?.RemoveChildFromLayoutGroup(child);
(Layout as LayoutGroup)?.RemoveChildFromLayoutGroup(child);
}

RemoveChild(child);
Expand Down
Loading

0 comments on commit a5e9501

Please sign in to comment.