Skip to content

Commit ab86102

Browse files
committed
feat(dirty_measure_ios): Fixed the broken build for iOS. Not actual implementation of DIRTY_MEASURE_PATH for iOS.
1 parent 44bc0ed commit ab86102

24 files changed

+365
-324
lines changed

src/SamplesApp/Benchmarks.Shared/Suite/Windows_UI/ColorBench/XamlControlsResourcesCreationBenchmark.cs

Lines changed: 34 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -5,40 +5,41 @@
55
using Microsoft.UI.Xaml.Controls;
66
using Windows.UI;
77

8-
namespace SamplesApp.Benchmarks.Suite.Windows_UI.ColorBench
8+
#pragma warning disable CS0219
9+
10+
namespace SamplesApp.Benchmarks.Suite.Windows_UI.ColorBench;
11+
12+
public class ColorBenchmark
913
{
10-
public class ColorBenchmark
14+
Color _color1 = Color.FromArgb(0xFF, 0xFF, 0x00, 0x00), _color2 = Color.FromArgb(0xFF, 0x00, 0xFF, 0x00);
15+
16+
[Benchmark]
17+
public void Create_Color()
18+
{
19+
var c = new Color();
20+
}
21+
22+
[Benchmark]
23+
public void Create_Color_WithParams()
24+
{
25+
var c = Color.FromArgb(0xFF, 0xFF, 0xFF, 0xFF);
26+
}
27+
28+
[Benchmark]
29+
public void Create_Color_GetHashCode()
30+
{
31+
var c = Color.FromArgb(0xFF, 0xFF, 0xFF, 0xFF).GetHashCode();
32+
}
33+
34+
[Benchmark]
35+
public void Create_Color_op_Equals()
36+
{
37+
var b = _color1 == _color2;
38+
}
39+
40+
[Benchmark]
41+
public void Create_Color_Equals()
1142
{
12-
Color _color1 = Color.FromArgb(0xFF, 0xFF, 0x00, 0x00), _color2 = Color.FromArgb(0xFF, 0x00, 0xFF, 0x00);
13-
14-
[Benchmark]
15-
public void Create_Color()
16-
{
17-
var c = new Color();
18-
}
19-
20-
[Benchmark]
21-
public void Create_Color_WithParams()
22-
{
23-
var c = Color.FromArgb(0xFF, 0xFF, 0xFF, 0xFF);
24-
}
25-
26-
[Benchmark]
27-
public void Create_Color_GetHashCode()
28-
{
29-
var c = Color.FromArgb(0xFF, 0xFF, 0xFF, 0xFF).GetHashCode();
30-
}
31-
32-
[Benchmark]
33-
public void Create_Color_op_Equals()
34-
{
35-
var b = _color1 == _color2;
36-
}
37-
38-
[Benchmark]
39-
public void Create_Color_Equals()
40-
{
41-
var b = _color1.Equals(_color2);
42-
}
43+
var b = _color1.Equals(_color2);
4344
}
4445
}

src/Uno.UI-UnitTests-only.slnf

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
"SourceGenerators\\Uno.UI.Tasks\\Uno.UI.Tasks.csproj",
1111
"T4Generator\\T4Generator.csproj",
1212
"Uno.Analyzers.Tests\\Uno.Analyzers.Tests.csproj",
13+
"Uno.Analyzers\\Uno.Analyzers.csproj",
1314
"Uno.Foundation.Logging\\Uno.Foundation.Logging.csproj",
1415
"Uno.Foundation\\Uno.Foundation.csproj",
1516
"Uno.UI.Composition\\Uno.UI.Composition.csproj",
@@ -26,4 +27,4 @@
2627
"Uno.UWP\\Uno.csproj"
2728
]
2829
}
29-
}
30+
}

src/Uno.UI.Tests/Windows_UI_XAML_Controls/GridTests/Given_Grid.cs

Lines changed: 26 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1010,23 +1010,26 @@ public void When_Grid_RowCollection_Changes()
10101010
.GridRow(1)
10111011
);
10121012

1013-
SUT.Measure(new Size(20, 20));
1014-
SUT.Arrange(new Rect(0, 0, 20, 20));
1013+
var measureAvailableSize = new Size(20, 20);
1014+
var arrangeFinalRect = new Rect(default, measureAvailableSize);
1015+
1016+
SUT.Measure(measureAvailableSize);
1017+
SUT.Arrange(arrangeFinalRect);
10151018

1016-
Assert.AreEqual(new Rect(0, 0, 20, 20), child.Arranged);
1019+
child.Arranged.Should().Be(arrangeFinalRect);
10171020

10181021
var row1 = new RowDefinition { Height = new GridLength(5) };
10191022
SUT.RowDefinitions.Add(row1);
10201023
SUT.RowDefinitions.Add(new RowDefinition { Height = new GridLength(1, GridUnitType.Auto) });
10211024

1022-
SUT.Measure(new Size(20, 20));
1023-
SUT.Arrange(new Rect(0, 0, 20, 20));
1025+
SUT.Measure(measureAvailableSize);
1026+
SUT.Arrange(arrangeFinalRect);
10241027

1025-
Assert.AreEqual(new Rect(0, 5, 20, 10), child.Arranged);
1028+
child.Arranged.Should().Be(new Rect(0, 5, 20, 10));
10261029

1027-
SUT.InvalidateMeasureCallCount.Should().Be(2);
1030+
SUT.InvalidateMeasureCallCount.Should().Be(1);
10281031
row1.Height = new GridLength(10);
1029-
SUT.InvalidateMeasureCallCount.Should().Be(3);
1032+
SUT.InvalidateMeasureCallCount.Should().Be(2);
10301033
}
10311034

10321035
[TestMethod]
@@ -1061,9 +1064,9 @@ public void When_Grid_ColumnCollection_Changes()
10611064

10621065
child.Arranged.Should().Be(new Rect(5, 0, 10, 20));
10631066

1064-
SUT.InvalidateMeasureCallCount.Should().Be(2);
1067+
SUT.InvalidateMeasureCallCount.Should().Be(1);
10651068
col1.Width = new GridLength(10);
1066-
SUT.InvalidateMeasureCallCount.Should().Be(3);
1069+
SUT.InvalidateMeasureCallCount.Should().Be(2);
10671070
}
10681071

10691072
[TestMethod]
@@ -1075,21 +1078,33 @@ public void When_Grid_Column_Min_MaxWidth_Changes()
10751078

10761079
SUT.ForceLoaded();
10771080

1078-
10791081
SUT.Measure(new Size(20, 20));
10801082
SUT.Arrange(new Rect(0, 0, 20, 20));
10811083

10821084
ColumnDefinition ColumnDefinition1;
10831085

10841086
SUT.ColumnDefinitions.Add(ColumnDefinition1 = new ColumnDefinition { Width = new GridLength(5) });
10851087
SUT.InvalidateMeasureCallCount.Should().Be(1);
1088+
1089+
SUT.Measure(new Size(20, 20)); // need to remeasure for the invalidation to be called again
1090+
10861091
SUT.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Auto) });
10871092
SUT.InvalidateMeasureCallCount.Should().Be(2);
10881093

10891094
ColumnDefinition1.MaxWidth = 22;
1095+
SUT.InvalidateMeasureCallCount.Should().Be(2); // Already invalidated, no new invalidations should be done
1096+
1097+
SUT.Measure(new Size(20, 20)); // need to remeasure for the invalidation to be called again
1098+
1099+
ColumnDefinition1.MaxWidth = 23;
10901100
SUT.InvalidateMeasureCallCount.Should().Be(3);
10911101

10921102
ColumnDefinition1.MinWidth = 5;
1103+
SUT.InvalidateMeasureCallCount.Should().Be(3); // Already invalidated, no new invalidations should be done
1104+
1105+
SUT.Measure(new Size(20, 20)); // need to remeasure for the invalidation to be called again
1106+
1107+
ColumnDefinition1.MinWidth = 6;
10931108
SUT.InvalidateMeasureCallCount.Should().Be(4);
10941109
}
10951110

src/Uno.UI/Extensions/ViewExtensions.Android.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -536,7 +536,7 @@ public static Task AnimateAsync(this View view, Animation animation)
536536
{
537537
var tcs = new TaskCompletionSource<object?>();
538538

539-
void OnAnimationEnd(object s, Animation.AnimationEndEventArgs e)
539+
void OnAnimationEnd(object? s, Animation.AnimationEndEventArgs? e)
540540
{
541541
animation.AnimationEnd -= OnAnimationEnd;
542542
tcs.SetResult(null);

src/Uno.UI/Extensions/ViewExtensions.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -100,10 +100,11 @@ internal static string GetLayoutDetails(this UIElement uiElement)
100100

101101
sb
102102
.Append(uiElement.IsMeasureDirty is true ? " MEASURE_DIRTY" : "")
103-
#if !__ANDROID__
103+
#if __ANDROID__
104+
.Append(uiElement.IsLayoutRequested ? " [IsLayoutRequested]" : "")
105+
#elif __IOS__ || __MACOS__
104106
.Append(uiElement.IsMeasureDirtyPath is true ? " MEASURE_DIRTY_PATH" : "")
105107
#else
106-
.Append(uiElement.IsLayoutRequested ? " [IsLayoutRequested]" : "")
107108
#endif
108109
.Append(uiElement.IsMeasureDirtyPathDisabled is true ? " MEASURE_DIRTY_PATH_DISABLED" : "")
109110
.Append(uiElement.IsArrangeDirty is true ? " ARRANGE_DIRTY" : "");

src/Uno.UI/Extensions/ViewExtensions.iOSmacOS.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#nullable enable
22

3+
using System.Collections.Generic;
34
using Windows.UI.Xaml;
45

56
namespace Uno.UI
@@ -14,5 +15,11 @@ public static string ShowLocalVisualTree(this UIElement element, int fromHeight
1415
return UIKit.UIViewExtensions.ShowLocalVisualTree(element as UIKit.UIView, fromHeight);
1516
#endif
1617
}
18+
19+
#if __IOS__
20+
internal static IEnumerable<UIKit.UIView> GetChildren(this UIElement element) => element.ChildrenShadow;
21+
#elif __MACOS__
22+
internal static IEnumerable<AppKit.NSView> GetChildren(this UIElement element) => element.ChildrenShadow;
23+
#endif
1724
}
1825
}

src/Uno.UI/UI/Xaml/FrameworkElement.iOS.cs

Lines changed: 31 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,7 @@ public override void SetNeedsLayout()
3434
base.SetNeedsLayout();
3535
}
3636

37-
IsMeasureDirty = true;
38-
IsArrangeDirty = true;
37+
SetLayoutFlags(LayoutFlag.MeasureDirty | LayoutFlag.ArrangeDirty);
3938

4039
SetSuperviewNeedsLayout();
4140
}
@@ -60,38 +59,42 @@ public override void LayoutSubviews()
6059
XamlMeasure(Bounds.Size.Add(Margin));
6160
}
6261

63-
OnBeforeArrange();
64-
65-
Rect finalRect;
66-
var parent = Superview;
67-
if (parent is UIElement
68-
|| parent is ISetLayoutSlots
69-
// In the case of ListViewItem inside native list, its parent's parent is ListViewBaseInternalContainer
70-
|| parent?.Superview is ISetLayoutSlots
71-
)
72-
{
73-
finalRect = LayoutSlotWithMarginsAndAlignments;
74-
}
75-
else
62+
if (IsArrangeDirty)
7663
{
77-
// Here the "arrange" is coming from a native element,
78-
// so we convert those measurements to logical ones.
79-
finalRect = RectFromUIRect(Frame);
80-
81-
// We also need to set the LayoutSlot as it was not by the parent.
82-
// Note: This is only an approximation of the LayoutSlot as margin and alignment might already been applied at this point.
83-
LayoutInformation.SetLayoutSlot(this, finalRect);
84-
LayoutSlotWithMarginsAndAlignments = finalRect;
64+
ClearLayoutFlags(LayoutFlag.ArrangeDirty);
65+
66+
OnBeforeArrange();
67+
68+
Rect finalRect;
69+
var parent = Superview;
70+
if (parent is UIElement
71+
|| parent is ISetLayoutSlots
72+
// In the case of ListViewItem inside native list, its parent's parent is ListViewBaseInternalContainer
73+
|| parent?.Superview is ISetLayoutSlots
74+
)
75+
{
76+
finalRect = LayoutSlotWithMarginsAndAlignments;
77+
}
78+
else
79+
{
80+
// Here the "arrange" is coming from a native element,
81+
// so we convert those measurements to logical ones.
82+
finalRect = RectFromUIRect(Frame);
83+
84+
// We also need to set the LayoutSlot as it was not by the parent.
85+
// Note: This is only an approximation of the LayoutSlot as margin and alignment might already been applied at this point.
86+
LayoutInformation.SetLayoutSlot(this, finalRect);
87+
LayoutSlotWithMarginsAndAlignments = finalRect;
88+
}
89+
90+
_layouter.Arrange(finalRect);
91+
92+
OnAfterArrange();
8593
}
86-
87-
_layouter.Arrange(finalRect);
88-
89-
OnAfterArrange();
9094
}
9195
finally
9296
{
9397
_inLayoutSubviews = false;
94-
IsArrangeDirty = false;
9598
}
9699
}
97100
catch (Exception e)

src/Uno.UI/UI/Xaml/FrameworkElement.iOSmacOS.cs

Lines changed: 5 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -34,24 +34,14 @@ public FrameworkElement()
3434

3535
internal CGSize? XamlMeasure(CGSize availableSize)
3636
{
37-
// If set layout has not been called, we can
38-
// return a previously cached result for the same available size.
39-
if (
40-
!IsMeasureDirty
41-
&& _lastAvailableSize.HasValue
42-
&& availableSize == _lastAvailableSize
43-
)
37+
if (((ILayouterElement)this).XamlMeasureInternal(availableSize, _lastAvailableSize, out var measuredSize))
4438
{
45-
return _lastMeasure;
39+
_lastAvailableSize = availableSize;
40+
_lastMeasure = measuredSize;
41+
SetLayoutFlags(LayoutFlag.ArrangeDirty);
4642
}
4743

48-
_lastAvailableSize = availableSize;
49-
IsMeasureDirty = false;
50-
51-
var result = _layouter.Measure(SizeFromUISize(availableSize));
52-
53-
// Result here exclude the margins on the element
54-
return _lastMeasure = result.LogicalToPhysicalPixels();
44+
return _lastMeasure;
5545
}
5646

5747
/// <summary>

src/Uno.UI/UI/Xaml/FrameworkElement.macOS.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,8 @@ protected internal override void OnInvalidateMeasure()
4747

4848
if (!IsMeasureDirty)
4949
{
50-
IsArrangeDirty = true;
51-
IsMeasureDirty = true;
50+
InvalidateMeasure();
51+
InvalidateArrange();
5252

5353
if (Parent is FrameworkElement fe)
5454
{
@@ -90,8 +90,8 @@ public override void Layout()
9090
finally
9191
{
9292
_inLayoutSubviews = false;
93-
IsMeasureDirty = false;
94-
IsArrangeDirty = false;
93+
94+
ClearLayoutFlags(LayoutFlag.MeasureDirty | LayoutFlag.ArrangeDirty);
9595
}
9696
}
9797

0 commit comments

Comments
 (0)