Browse Source

Simplify unset effective value removal.

pull/8600/head
Steven Kirk 4 years ago
parent
commit
20d85df87c
  1. 34
      src/Avalonia.Base/PropertyStore/ValueStore.cs
  2. 23
      src/Avalonia.Base/Utilities/AvaloniaPropertyDictionary.cs
  3. 2
      tests/Avalonia.Base.UnitTests/PropertyStore/ValueStoreTests_Frames.cs

34
src/Avalonia.Base/PropertyStore/ValueStore.cs

@ -690,6 +690,13 @@ namespace Avalonia.PropertyStore
effectiveValue.SetAndRaise(this, entry, priority); 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) private bool RemoveEffectiveValue(AvaloniaProperty property)
{ {
if (_effectiveValues.Remove(property)) if (_effectiveValues.Remove(property))
@ -869,13 +876,10 @@ namespace Avalonia.PropertyStore
var entry = frame.GetEntry(j); var entry = frame.GetEntry(j);
var property = entry.Property; var property = entry.Property;
// Unsubscribe and skip if we already have a value/base value for this property. // Skip if we already have a value/base value for this property.
if (_effectiveValues.TryGetValue(property, out var effectiveValue) == true && if (_effectiveValues.TryGetValue(property, out var effectiveValue) &&
effectiveValue.BasePriority < BindingPriority.Unset) effectiveValue.BasePriority < BindingPriority.Unset)
{
entry.Unsubscribe();
continue; continue;
}
if (!entry.HasValue) if (!entry.HasValue)
continue; continue;
@ -897,30 +901,16 @@ namespace Avalonia.PropertyStore
} }
// Remove all effective values that are still unset. // Remove all effective values that are still unset.
PooledList<AvaloniaProperty>? remove = null; for (var i = _effectiveValues.Count - 1; i >= 0; --i)
count = _effectiveValues.Count;
for (var i = 0; i < count; ++i)
{ {
_effectiveValues.GetKeyValue(i, out var key, out var e); _effectiveValues.GetKeyValue(i, out var key, out var e);
e.EndReevaluation(); e.EndReevaluation();
if (e.Priority == BindingPriority.Unset) if (e.Priority == BindingPriority.Unset)
{ {
remove ??= new(); RemoveEffectiveValue(key, i);
remove.Add(key); e.DisposeAndRaiseUnset(this, key);
}
}
if (remove is not null)
{
foreach (var v in remove)
{
if (RemoveEffectiveValue(v, out var e))
e.DisposeAndRaiseUnset(this, v);
} }
remove.Dispose();
} }
} }
finally finally

23
src/Avalonia.Base/Utilities/AvaloniaPropertyDictionary.cs

@ -1,6 +1,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis; using System.Diagnostics.CodeAnalysis;
using static Avalonia.Rendering.Composition.Animations.PropertySetSnapshot;
namespace Avalonia.Utilities namespace Avalonia.Utilities
{ {
@ -159,9 +160,7 @@ namespace Avalonia.Utilities
{ {
if (TryGetEntry(property.Id, out var index)) if (TryGetEntry(property.Id, out var index))
{ {
Array.Copy(_entries, index + 1, _entries, index, _entryCount - index - 1); RemoveAt(index);
_entryCount--;
_entries[_entryCount] = default;
return true; return true;
} }
@ -183,9 +182,7 @@ namespace Avalonia.Utilities
if (TryGetEntry(property.Id, out var index)) if (TryGetEntry(property.Id, out var index))
{ {
value = _entries[index].Value; value = _entries[index].Value;
Array.Copy(_entries, index + 1, _entries, index, _entryCount - index - 1); RemoveAt(index);
_entryCount--;
_entries[_entryCount] = default;
return true; return true;
} }
@ -193,6 +190,20 @@ namespace Avalonia.Utilities
return false; 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> /// <summary>
/// Attempts to add the specified key and value to the collection. /// Attempts to add the specified key and value to the collection.
/// </summary> /// </summary>

2
tests/Avalonia.Base.UnitTests/PropertyStore/ValueStoreTests_Frames.cs

@ -69,8 +69,8 @@ namespace Avalonia.Base.UnitTests.PropertyStore
Assert.Equal(new PropertyChange[] Assert.Equal(new PropertyChange[]
{ {
new(Class1.FooProperty, "foo", "foodefault"),
new(Class1.BarProperty, "bar", "bardefault"), new(Class1.BarProperty, "bar", "bardefault"),
new(Class1.FooProperty, "foo", "foodefault"),
}, result); }, result);
} }

Loading…
Cancel
Save