From d5b622af62777f831d698cdf5ba37a3aad6221d0 Mon Sep 17 00:00:00 2001 From: Jerome Laban Date: Wed, 5 May 2021 13:49:04 -0400 Subject: [PATCH] perf: Reduce foreach/linq usage in pointers management Improves the performance of UIElement.Visibility changes --- src/Uno.UI/UI/Xaml/DependencyObjectExtensions.cs | 16 ++++++++++++++++ src/Uno.UI/UI/Xaml/UIElement.PointerCapture.cs | 2 +- src/Uno.UI/UI/Xaml/UIElement.Pointers.cs | 12 +++++++++--- 3 files changed, 26 insertions(+), 4 deletions(-) diff --git a/src/Uno.UI/UI/Xaml/DependencyObjectExtensions.cs b/src/Uno.UI/UI/Xaml/DependencyObjectExtensions.cs index c5a30456e678..ffc951f38616 100644 --- a/src/Uno.UI/UI/Xaml/DependencyObjectExtensions.cs +++ b/src/Uno.UI/UI/Xaml/DependencyObjectExtensions.cs @@ -103,6 +103,22 @@ internal static IEnumerable GetParents(this object dependencyObject) } } + internal static bool HasParent(this object dependencyObject, DependencyObject searchedParent) + { + var parent = dependencyObject.GetParent(); + while (parent != null) + { + if(ReferenceEquals(parent, searchedParent)) + { + return true; + } + + parent = parent.GetParent(); + } + + return false; + } + /// /// Set the parent of the specified dependency object /// diff --git a/src/Uno.UI/UI/Xaml/UIElement.PointerCapture.cs b/src/Uno.UI/UI/Xaml/UIElement.PointerCapture.cs index 62bb5260bf50..d991d6fae4c7 100644 --- a/src/Uno.UI/UI/Xaml/UIElement.PointerCapture.cs +++ b/src/Uno.UI/UI/Xaml/UIElement.PointerCapture.cs @@ -46,7 +46,7 @@ public static PointerCapture GetOrCreate(Pointer pointer) public static bool TryGet(Pointer pointer, out PointerCapture capture) => _actives.TryGetValue(pointer, out capture); - public static bool Any(out IEnumerable cloneOfAllCaptures) + public static bool Any(out List cloneOfAllCaptures) { if (_actives.Any()) { diff --git a/src/Uno.UI/UI/Xaml/UIElement.Pointers.cs b/src/Uno.UI/UI/Xaml/UIElement.Pointers.cs index 1b65d8619ad1..b6b0c90ad5ba 100644 --- a/src/Uno.UI/UI/Xaml/UIElement.Pointers.cs +++ b/src/Uno.UI/UI/Xaml/UIElement.Pointers.cs @@ -171,11 +171,17 @@ private void InitializePointers() && visibility != Visibility.Visible && PointerCapture.Any(out var captures)) { - foreach (var capture in captures) + for (var captureIndex = 0; captureIndex < captures.Count; captureIndex++) { - foreach (var target in capture.Targets.ToList()) + var capture = captures[captureIndex]; + + var targets = capture.Targets.ToList(); + + for (var targetIndex = 0; targetIndex < targets.Count; targetIndex++) { - if (target.Element.GetParents().Contains(sender)) + var target = targets[targetIndex]; + + if (target.Element.HasParent(sender)) { target.Element.Release(capture, PointerCaptureKind.Any); }