From 20d85df87c42bb92f96d06db0f73dd47cf39966c Mon Sep 17 00:00:00 2001 From: Steven Kirk Date: Sat, 15 Oct 2022 12:48:15 +0200 Subject: [PATCH] Simplify unset effective value removal. --- src/Avalonia.Base/PropertyStore/ValueStore.cs | 34 +++++++------------ .../Utilities/AvaloniaPropertyDictionary.cs | 23 +++++++++---- .../PropertyStore/ValueStoreTests_Frames.cs | 2 +- 3 files changed, 30 insertions(+), 29 deletions(-) diff --git a/src/Avalonia.Base/PropertyStore/ValueStore.cs b/src/Avalonia.Base/PropertyStore/ValueStore.cs index 903146ad2b..19d80adaf5 100644 --- a/src/Avalonia.Base/PropertyStore/ValueStore.cs +++ b/src/Avalonia.Base/PropertyStore/ValueStore.cs @@ -690,6 +690,13 @@ namespace Avalonia.PropertyStore effectiveValue.SetAndRaise(this, entry, priority); } + private void RemoveEffectiveValue(AvaloniaProperty property, int index) + { + _effectiveValues.RemoveAt(index); + if (property.Inherits && --_inheritedValueCount == 0) + OnInheritanceAncestorChanged(InheritanceAncestor); + } + private bool RemoveEffectiveValue(AvaloniaProperty property) { if (_effectiveValues.Remove(property)) @@ -869,13 +876,10 @@ namespace Avalonia.PropertyStore var entry = frame.GetEntry(j); var property = entry.Property; - // Unsubscribe and skip if we already have a value/base value for this property. - if (_effectiveValues.TryGetValue(property, out var effectiveValue) == true && + // Skip if we already have a value/base value for this property. + if (_effectiveValues.TryGetValue(property, out var effectiveValue) && effectiveValue.BasePriority < BindingPriority.Unset) - { - entry.Unsubscribe(); continue; - } if (!entry.HasValue) continue; @@ -897,30 +901,16 @@ namespace Avalonia.PropertyStore } // Remove all effective values that are still unset. - PooledList? remove = null; - - count = _effectiveValues.Count; - - for (var i = 0; i < count; ++i) + for (var i = _effectiveValues.Count - 1; i >= 0; --i) { _effectiveValues.GetKeyValue(i, out var key, out var e); e.EndReevaluation(); if (e.Priority == BindingPriority.Unset) { - remove ??= new(); - remove.Add(key); - } - } - - if (remove is not null) - { - foreach (var v in remove) - { - if (RemoveEffectiveValue(v, out var e)) - e.DisposeAndRaiseUnset(this, v); + RemoveEffectiveValue(key, i); + e.DisposeAndRaiseUnset(this, key); } - remove.Dispose(); } } finally diff --git a/src/Avalonia.Base/Utilities/AvaloniaPropertyDictionary.cs b/src/Avalonia.Base/Utilities/AvaloniaPropertyDictionary.cs index 5c7d7d8605..18c03fb031 100644 --- a/src/Avalonia.Base/Utilities/AvaloniaPropertyDictionary.cs +++ b/src/Avalonia.Base/Utilities/AvaloniaPropertyDictionary.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; +using static Avalonia.Rendering.Composition.Animations.PropertySetSnapshot; namespace Avalonia.Utilities { @@ -159,9 +160,7 @@ namespace Avalonia.Utilities { if (TryGetEntry(property.Id, out var index)) { - Array.Copy(_entries, index + 1, _entries, index, _entryCount - index - 1); - _entryCount--; - _entries[_entryCount] = default; + RemoveAt(index); return true; } @@ -183,9 +182,7 @@ namespace Avalonia.Utilities if (TryGetEntry(property.Id, out var index)) { value = _entries[index].Value; - Array.Copy(_entries, index + 1, _entries, index, _entryCount - index - 1); - _entryCount--; - _entries[_entryCount] = default; + RemoveAt(index); return true; } @@ -193,6 +190,20 @@ namespace Avalonia.Utilities return false; } + /// + /// Removes the element at the specified index from the collection. + /// + /// The index. + public void RemoveAt(int index) + { + if (_entries is null) + throw new IndexOutOfRangeException(); + + Array.Copy(_entries, index + 1, _entries, index, _entryCount - index - 1); + _entryCount--; + _entries[_entryCount] = default; + } + /// /// Attempts to add the specified key and value to the collection. /// diff --git a/tests/Avalonia.Base.UnitTests/PropertyStore/ValueStoreTests_Frames.cs b/tests/Avalonia.Base.UnitTests/PropertyStore/ValueStoreTests_Frames.cs index 0c87083f8d..48bc21dc5f 100644 --- a/tests/Avalonia.Base.UnitTests/PropertyStore/ValueStoreTests_Frames.cs +++ b/tests/Avalonia.Base.UnitTests/PropertyStore/ValueStoreTests_Frames.cs @@ -69,8 +69,8 @@ namespace Avalonia.Base.UnitTests.PropertyStore Assert.Equal(new PropertyChange[] { - new(Class1.FooProperty, "foo", "foodefault"), new(Class1.BarProperty, "bar", "bardefault"), + new(Class1.FooProperty, "foo", "foodefault"), }, result); }