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

23
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>

2
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);
}

Loading…
Cancel
Save