Browse Source

Merge pull request #3669 from MarchingCube/avalonia-property-registry-delinq

Make AvaloniaPropertyRegistry return IReadOnlyList from lookup functions
Steven Kirk 5 years ago
parent
commit
25f1dd834e
2 changed files with 52 additions and 42 deletions
  1. 5 1
      src/Avalonia.Base/AvaloniaObject.cs
  2. 47 41
      src/Avalonia.Base/AvaloniaPropertyRegistry.cs

+ 5 - 1
src/Avalonia.Base/AvaloniaObject.cs

@@ -80,8 +80,12 @@ namespace Avalonia
                     _inheritanceParent?.RemoveInheritanceChild(this);
                     _inheritanceParent = value;
 
-                    foreach (var property in AvaloniaPropertyRegistry.Instance.GetRegisteredInherited(GetType()))
+                    var properties = AvaloniaPropertyRegistry.Instance.GetRegisteredInherited(GetType());
+                    var propertiesCount = properties.Count;
+
+                    for (var i = 0; i < propertiesCount; i++)
                     {
+                        var property = properties[i];
                         if (valuestore?.IsSet(property) == true)
                         {
                             // If local value set there can be no change.

+ 47 - 41
src/Avalonia.Base/AvaloniaPropertyRegistry.cs

@@ -3,9 +3,7 @@
 
 using System;
 using System.Collections.Generic;
-using System.Linq;
 using System.Runtime.CompilerServices;
-using Avalonia.Data;
 
 namespace Avalonia
 {
@@ -28,8 +26,6 @@ namespace Avalonia
             new Dictionary<Type, List<AvaloniaProperty>>();
         private readonly Dictionary<Type, List<AvaloniaProperty>> _directCache =
             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>>();
 
@@ -49,7 +45,7 @@ namespace Avalonia
         /// </summary>
         /// <param name="type">The type.</param>
         /// <returns>A collection of <see cref="AvaloniaProperty"/> definitions.</returns>
-        public IEnumerable<AvaloniaProperty> GetRegistered(Type type)
+        public IReadOnlyList<AvaloniaProperty> GetRegistered(Type type)
         {
             Contract.Requires<ArgumentNullException>(type != null);
 
@@ -83,7 +79,7 @@ namespace Avalonia
         /// </summary>
         /// <param name="type">The type.</param>
         /// <returns>A collection of <see cref="AvaloniaProperty"/> definitions.</returns>
-        public IEnumerable<AvaloniaProperty> GetRegisteredAttached(Type type)
+        public IReadOnlyList<AvaloniaProperty> GetRegisteredAttached(Type type)
         {
             Contract.Requires<ArgumentNullException>(type != null);
 
@@ -114,7 +110,7 @@ namespace Avalonia
         /// </summary>
         /// <param name="type">The type.</param>
         /// <returns>A collection of <see cref="AvaloniaProperty"/> definitions.</returns>
-        public IEnumerable<AvaloniaProperty> GetRegisteredDirect(Type type)
+        public IReadOnlyList<AvaloniaProperty> GetRegisteredDirect(Type type)
         {
             Contract.Requires<ArgumentNullException>(type != null);
 
@@ -145,7 +141,7 @@ namespace Avalonia
         /// </summary>
         /// <param name="type">The type.</param>
         /// <returns>A collection of <see cref="AvaloniaProperty"/> definitions.</returns>
-        public IEnumerable<AvaloniaProperty> GetRegisteredInherited(Type type)
+        public IReadOnlyList<AvaloniaProperty> GetRegisteredInherited(Type type)
         {
             Contract.Requires<ArgumentNullException>(type != null);
 
@@ -157,16 +153,27 @@ namespace Avalonia
             result = new List<AvaloniaProperty>();
             var visited = new HashSet<AvaloniaProperty>();
 
-            foreach (var property in GetRegistered(type))
+            var registered = GetRegistered(type);
+            var registeredCount = registered.Count;
+
+            for (var i = 0; i < registeredCount; i++)
             {
+                var property = registered[i];
+
                 if (property.Inherits)
                 {
                     result.Add(property);
                     visited.Add(property);
                 }
             }
-            foreach (var property in GetRegisteredAttached(type))
+
+            var registeredAttached = GetRegisteredAttached(type);
+            var registeredAttachedCount = registeredAttached.Count;
+
+            for (var i = 0; i < registeredAttachedCount; i++)
             {
+                var property = registeredAttached[i];
+
                 if (property.Inherits)
                 {
                     if (!visited.Contains(property))
@@ -185,7 +192,7 @@ namespace Avalonia
         /// </summary>
         /// <param name="o">The object.</param>
         /// <returns>A collection of <see cref="AvaloniaProperty"/> definitions.</returns>
-        public IEnumerable<AvaloniaProperty> GetRegistered(IAvaloniaObject o)
+        public IReadOnlyList<AvaloniaProperty> GetRegistered(IAvaloniaObject o)
         {
             Contract.Requires<ArgumentNullException>(o != null);
 
@@ -229,8 +236,13 @@ namespace Avalonia
                 throw new InvalidOperationException("Attached properties not supported.");
             }
 
-            foreach (AvaloniaProperty x in GetRegistered(type))
+            var registered = GetRegistered(type);
+            var registeredCount = registered.Count;
+
+            for (var i = 0; i < registeredCount; i++)
             {
+                AvaloniaProperty x = registered[i];
+
                 if (x.Name == name)
                 {
                     return x;
@@ -276,8 +288,13 @@ namespace Avalonia
                 return property;
             }
 
-            foreach (var p in GetRegisteredDirect(o.GetType()))
+            var registeredDirect = GetRegisteredDirect(o.GetType());
+            var registeredDirectCount = registeredDirect.Count;
+
+            for (var i = 0; i < registeredDirectCount; i++)
             {
+                var p = registeredDirect[i];
+
                 if (p == property)
                 {
                     return (DirectPropertyBase<T>)p;
@@ -308,8 +325,23 @@ namespace Avalonia
             Contract.Requires<ArgumentNullException>(type != null);
             Contract.Requires<ArgumentNullException>(property != null);
 
-            return Instance.GetRegistered(type).Any(x => x == property) ||
-                Instance.GetRegisteredAttached(type).Any(x => x == property);
+            static bool ContainsProperty(IReadOnlyList<AvaloniaProperty> properties, AvaloniaProperty property)
+            {
+                var propertiesCount = properties.Count;
+
+                for (var i = 0; i < propertiesCount; i++)
+                {
+                    if (properties[i] == property)
+                    {
+                        return true;
+                    }
+                }
+
+                return false;
+            }
+
+            return ContainsProperty(Instance.GetRegistered(type), property) ||
+                   ContainsProperty(Instance.GetRegisteredAttached(type), property);
         }
 
         /// <summary>
@@ -374,7 +406,6 @@ namespace Avalonia
             }
             
             _registeredCache.Clear();
-            _initializedCache.Clear();
             _inheritedCache.Clear();
         }
 
@@ -411,32 +442,7 @@ namespace Avalonia
             }
             
             _attachedCache.Clear();
-            _initializedCache.Clear();
             _inheritedCache.Clear();
         }
-
-        private readonly struct PropertyInitializationData
-        {
-            public AvaloniaProperty Property { get; }
-            public object Value { get; }
-            public bool IsDirect { get; }
-            public IDirectPropertyAccessor DirectAccessor { get; }
-
-            public PropertyInitializationData(AvaloniaProperty property, IDirectPropertyAccessor directAccessor)
-            {
-                Property = property;
-                Value = null;
-                IsDirect = true;
-                DirectAccessor = directAccessor;
-            }
-
-            public PropertyInitializationData(AvaloniaProperty property, IStyledPropertyAccessor styledAccessor, Type type)
-            {
-                Property = property;
-                Value = styledAccessor.GetDefaultValue(type);
-                IsDirect = false;
-                DirectAccessor = null;
-            }
-        }
     }
 }