소스 검색

Have PriorityValue use SetAndNotify infrastructure.

Jeremy Koritzinsky 8 년 전
부모
커밋
36fe461b4a
2개의 변경된 파일40개의 추가작업 그리고 56개의 파일을 삭제
  1. 35 54
      src/Avalonia.Base/PriorityValue.cs
  2. 5 2
      src/Avalonia.Base/Utilities/DelayedSetter.cs

+ 35 - 54
src/Avalonia.Base/PriorityValue.cs

@@ -235,75 +235,56 @@ namespace Avalonia
         /// <param name="priority">The priority level that the value came from.</param>
         private void UpdateValue(object value, int priority)
         {
-            if (!delayedSetter.IsNotifying(this))
+            delayedSetter.SetAndNotify(this, (update, notify) =>
             {
-                value = UpdateValueCore(value, priority);
+                var val = update.value;
+                var notification = val as BindingNotification;
+                object castValue;
 
-                while (delayedSetter.HasPendingSet(this))
+                if (notification != null)
                 {
-                    var pendingSet = delayedSetter.GetFirstPendingSet(this);
-                    UpdateValueCore(pendingSet.value, pendingSet.priority);
+                    val = (notification.HasValue) ? notification.Value : null;
                 }
-            }
-            else if(!object.Equals(value, _value))
-            {
-                delayedSetter.AddPendingSet(this, (value, priority));
-            }
-        }
-
-        private object UpdateValueCore(object value, int priority)
-        {
-            var notification = value as BindingNotification;
-            object castValue;
 
-            if (notification != null)
-            {
-                value = (notification.HasValue) ? notification.Value : null;
-            }
+                if (TypeUtilities.TryConvertImplicit(_valueType, val, out castValue))
+                {
+                    var old = _value;
 
-            if (TypeUtilities.TryConvertImplicit(_valueType, value, out castValue))
-            {
-                var old = _value;
+                    if (_validate != null && castValue != AvaloniaProperty.UnsetValue)
+                    {
+                        castValue = _validate(castValue);
+                    }
 
-                if (_validate != null && castValue != AvaloniaProperty.UnsetValue)
-                {
-                    castValue = _validate(castValue);
-                }
+                    ValuePriority = priority;
+                    _value = castValue;
 
-                ValuePriority = priority;
-                _value = castValue;
+                    if (notification?.HasValue == true)
+                    {
+                        notification.SetValue(castValue);
+                    }
 
-                if (notification?.HasValue == true)
-                {
-                    notification.SetValue(castValue);
-                }
+                    if (notification == null || notification.HasValue)
+                    {
+                        notify(() => Owner?.Changed(this, old, _value));
+                    }
 
-                if (notification == null || notification.HasValue)
-                {
-                    using (delayedSetter.MarkNotifying(this))
+                    if (notification != null)
                     {
-                        Owner?.Changed(this, old, _value);
+                        Owner?.BindingNotificationReceived(this, notification);
                     }
                 }
-
-                if (notification != null)
+                else
                 {
-                    Owner?.BindingNotificationReceived(this, notification);
+                    Logger.Error(
+                        LogArea.Binding,
+                        Owner,
+                        "Binding produced invalid value for {$Property} ({$PropertyType}): {$Value} ({$ValueType})",
+                        Property.Name,
+                        _valueType,
+                        val,
+                        val?.GetType());
                 }
-            }
-            else
-            {
-                Logger.Error(
-                    LogArea.Binding,
-                    Owner,
-                    "Binding produced invalid value for {$Property} ({$PropertyType}): {$Value} ({$ValueType})",
-                    Property.Name,
-                    _valueType,
-                    value,
-                    value?.GetType());
-            }
-
-            return value;
+            }, (value, priority), val => !object.Equals(val.value, _value));
         }
     }
 }

+ 5 - 2
src/Avalonia.Base/Utilities/DelayedSetter.cs

@@ -58,7 +58,7 @@ namespace Avalonia.Utilities
             return setRecords[property].PendingValues.Dequeue();
         }
 
-        public void SetAndNotify(T property, Action<TValue, Action<Action>> setterCallback, TValue value)
+        public void SetAndNotify(T property, Action<TValue, Action<Action>> setterCallback, TValue value, Predicate<TValue> pendingSetCondition)
         {
             Contract.Requires<ArgumentNullException>(setterCallback != null);
             if (!IsNotifying(property))
@@ -81,10 +81,13 @@ namespace Avalonia.Utilities
                     });
                 }
             }
-            else
+            else if(pendingSetCondition?.Invoke(value) ?? true)
             {
                 AddPendingSet(property, value);
             }
         }
+
+        public void SetAndNotify(T property, Action<TValue, Action<Action>> setterCallback, TValue value)
+            => SetAndNotify(property, setterCallback, value, null);
     }
 }