Browse Source

reduce allocation, cache Inherited props,remove duplicate events

pull/2915/head
ahopper 7 years ago
parent
commit
112484d7e4
  1. 37
      src/Avalonia.Base/AvaloniaObject.cs
  2. 44
      src/Avalonia.Base/AvaloniaPropertyRegistry.cs

37
src/Avalonia.Base/AvaloniaObject.cs

@ -82,6 +82,7 @@ namespace Avalonia
set
{
VerifyAccess();
if (_inheritanceParent != value)
{
if (_inheritanceParent != null)
@ -89,25 +90,33 @@ namespace Avalonia
_inheritanceParent.InheritablePropertyChanged -= ParentPropertyChanged;
}
var properties = AvaloniaPropertyRegistry.Instance.GetRegistered(this)
.Concat(AvaloniaPropertyRegistry.Instance.GetRegisteredAttached(this.GetType()));
var inherited = (from property in properties
where property.Inherits
select new
{
Property = property,
Value = GetValue(property),
}).ToList();
var oldInheritanceParent = _inheritanceParent;
_inheritanceParent = value;
var valuestore = _values;
foreach (var i in inherited)
foreach (var property in AvaloniaPropertyRegistry.Instance.GetRegisteredInherited(GetType()))
{
object newValue = GetValue(i.Property);
if (valuestore != null && valuestore.GetValue(property) != AvaloniaProperty.UnsetValue)
{
// if local value set there can be no change
continue;
}
// get the value as it would have been with the previous InheritanceParent
object oldValue;
if (oldInheritanceParent is AvaloniaObject aobj)
{
oldValue = aobj.GetValueOrDefaultUnchecked(property);
}
else
{
oldValue = ((IStyledPropertyAccessor)property).GetDefaultValue(GetType());
}
object newValue = GetDefaultValue(property);
if (!Equals(i.Value, newValue))
if (!Equals(oldValue, newValue))
{
RaisePropertyChanged(i.Property, i.Value, newValue, BindingPriority.LocalValue);
RaisePropertyChanged(property, oldValue, newValue, BindingPriority.LocalValue);
}
}

44
src/Avalonia.Base/AvaloniaPropertyRegistry.cs

@ -26,6 +26,8 @@ namespace Avalonia
new Dictionary<Type, List<AvaloniaProperty>>();
private readonly Dictionary<Type, List<PropertyInitializationData>> _initializedCache =
new Dictionary<Type, List<PropertyInitializationData>>();
private readonly Dictionary<Type, List<AvaloniaProperty>> _inheritedCache =
new Dictionary<Type, List<AvaloniaProperty>>();
/// <summary>
/// Gets the <see cref="AvaloniaPropertyRegistry"/> instance
@ -103,6 +105,46 @@ namespace Avalonia
return result;
}
/// <summary>
/// Gets all inherited <see cref="AvaloniaProperty"/>s registered on a type.
/// </summary>
/// <param name="type">The type.</param>
/// <returns>A collection of <see cref="AvaloniaProperty"/> definitions.</returns>
public IEnumerable<AvaloniaProperty> GetRegisteredInherited(Type type)
{
Contract.Requires<ArgumentNullException>(type != null);
if (_inheritedCache.TryGetValue(type, out var result))
{
return result;
}
result = new List<AvaloniaProperty>();
var visited = new HashSet<AvaloniaProperty>();
foreach (var property in GetRegistered(type))
{
if (property.Inherits)
{
result.Add(property);
visited.Add(property);
}
}
foreach (var property in GetRegisteredAttached(type))
{
if (property.Inherits)
{
if (!visited.Contains(property))
{
result.Add(property);
}
}
}
_inheritedCache.Add(type, result);
return result;
}
/// <summary>
/// Gets all <see cref="AvaloniaProperty"/>s registered on a object.
/// </summary>
@ -230,6 +272,7 @@ namespace Avalonia
_registeredCache.Clear();
_initializedCache.Clear();
_inheritedCache.Clear();
}
/// <summary>
@ -266,6 +309,7 @@ namespace Avalonia
_attachedCache.Clear();
_initializedCache.Clear();
_inheritedCache.Clear();
}
internal void NotifyInitialized(AvaloniaObject o)

Loading…
Cancel
Save