Browse Source

Simplify unset effective value removal.

Steven Kirk 3 năm trước cách đây
mục cha
commit
20d85df87c

+ 12 - 22
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<AvaloniaProperty>? 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

+ 17 - 6
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;
         }
 
+        /// <summary>
+        /// Removes the element at the specified index from the collection.
+        /// </summary>
+        /// <param name="index">The index.</param>
+        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;
+        }
+
         /// <summary>
         /// Attempts to add the specified key and value to the collection.
         /// </summary>

+ 1 - 1
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);
         }