瀏覽代碼

Merge pull request #2933 from MarchingCube/deferred-setter-notifyhandler

Fix PriorityValue allocating set and notify delegates.
Dariusz Komosiński 6 年之前
父節點
當前提交
0ce5aa7b79
共有 2 個文件被更改,包括 26 次插入18 次删除
  1. 8 6
      src/Avalonia.Base/PriorityValue.cs
  2. 18 12
      src/Avalonia.Base/Utilities/DeferredSetter.cs

+ 8 - 6
src/Avalonia.Base/PriorityValue.cs

@@ -24,13 +24,11 @@ namespace Avalonia
     /// <see cref="IPriorityValueOwner.Changed"/> method on the 
     /// owner object is fired with the old and new values.
     /// </remarks>
-    internal class PriorityValue
+    internal sealed class PriorityValue : ISetAndNotifyHandler<(object,int)>
     {
         private readonly Type _valueType;
         private readonly SingleOrDictionary<int, PriorityLevel> _levels = new SingleOrDictionary<int, PriorityLevel>();
-
         private readonly Func<object, object> _validate;
-        private readonly SetAndNotifyCallback<(object, int)> _setAndNotifyCallback;
         private (object value, int priority) _value;
         private DeferredSetter<object> _setter;
 
@@ -52,7 +50,6 @@ namespace Avalonia
             _valueType = valueType;
             _value = (AvaloniaProperty.UnsetValue, int.MaxValue);
             _validate = validate;
-            _setAndNotifyCallback = SetAndNotify;
         }
 
         /// <summary>
@@ -257,10 +254,15 @@ namespace Avalonia
                 _setter = Owner.GetNonDirectDeferredSetter(Property);
             }
 
-            _setter.SetAndNotifyCallback(Property, _setAndNotifyCallback, ref _value, newValue);
+            _setter.SetAndNotifyCallback(Property, this, ref _value, newValue);
+        }
+
+        void ISetAndNotifyHandler<(object, int)>.HandleSetAndNotify(AvaloniaProperty property, ref (object, int) backing, (object, int) value)
+        {
+            SetAndNotify(ref backing, value);
         }
 
-        private void SetAndNotify(AvaloniaProperty property, ref (object value, int priority) backing, (object value, int priority) update)
+        private void SetAndNotify(ref (object value, int priority) backing, (object value, int priority) update)
         {
             var val = update.value;
             var notification = val as BindingNotification;

+ 18 - 12
src/Avalonia.Base/Utilities/DeferredSetter.cs

@@ -5,15 +5,6 @@ using System;
 
 namespace Avalonia.Utilities
 {
-    /// <summary>
-    /// Callback invoked when deferred setter wants to set a value.
-    /// </summary>
-    /// <typeparam name="TValue">Value type.</typeparam>
-    /// <param name="property">Property being set.</param>
-    /// <param name="backing">Backing field reference.</param>
-    /// <param name="value">New value.</param>
-    internal delegate void SetAndNotifyCallback<TValue>(AvaloniaProperty property, ref TValue backing, TValue value);
-
     /// <summary>
     /// A utility class to enable deferring assignment until after property-changed notifications are sent.
     /// Used to fix #855.
@@ -70,14 +61,14 @@ namespace Avalonia.Utilities
             return false;
         }
 
-        public bool SetAndNotifyCallback<TValue>(AvaloniaProperty property, SetAndNotifyCallback<TValue> setAndNotifyCallback, ref TValue backing, TValue value)
+        public bool SetAndNotifyCallback<TValue>(AvaloniaProperty property, ISetAndNotifyHandler<TValue> setAndNotifyHandler, ref TValue backing, TValue value)
             where TValue : TSetRecord
         {
             if (!_isNotifying)
             {
                 using (new NotifyDisposable(this))
                 {
-                    setAndNotifyCallback(property, ref backing, value);
+                    setAndNotifyHandler.HandleSetAndNotify(property, ref backing, value);
                 }
 
                 if (!_pendingValues.Empty)
@@ -86,7 +77,7 @@ namespace Avalonia.Utilities
                     {
                         while (!_pendingValues.Empty)
                         {
-                            setAndNotifyCallback(property, ref backing, (TValue) _pendingValues.Dequeue());
+                            setAndNotifyHandler.HandleSetAndNotify(property, ref backing, (TValue)_pendingValues.Dequeue());
                         }
                     }
                 }
@@ -119,4 +110,19 @@ namespace Avalonia.Utilities
             }
         }
     }
+
+    /// <summary>
+    /// Handler for set and notify requests.
+    /// </summary>
+    /// <typeparam name="TValue">Value type.</typeparam>
+    internal interface ISetAndNotifyHandler<TValue>
+    {
+        /// <summary>
+        /// Handles deferred setter requests to set a value.
+        /// </summary>
+        /// <param name="property">Property being set.</param>
+        /// <param name="backing">Backing field reference.</param>
+        /// <param name="value">New value.</param>
+        void HandleSetAndNotify(AvaloniaProperty property, ref TValue backing, TValue value);
+    }
 }