// -----------------------------------------------------------------------
//
// Copyright 2014 MIT Licence. See licence.md for more information.
//
// -----------------------------------------------------------------------
namespace Perspex
{
using System;
using System.Collections.Generic;
using System.Reactive.Disposables;
using System.Reactive.Subjects;
using System.Reflection;
///
/// Maintains a list of prioritised bindings together with a current value.
///
///
/// Bindings, in the form of s are added to the object using
/// the method. With the observable is passed a priority, where lower values
/// represent higher priorites. The current is selected from the highest
/// priority binding that doesn't return . Where there
/// are multiple bindings registered with the same priority, the most recently added binding
/// has a higher priority. Each time the value changes to a distinct new value, the
/// observable is fired with the old and new values.
///
public class PriorityValue
{
///
/// The name of the property.
///
private string name;
///
/// The value type.
///
private Type valueType;
///
/// The currently registered binding entries.
///
private LinkedList bindings = new LinkedList();
///
/// The changed observable.
///
private Subject> changed = new Subject>();
///
/// The current value.
///
private object value;
///
/// Initializes a new instance of the class.
///
/// The name of the property.
/// The value type.
public PriorityValue(string name, Type valueType)
{
this.name = name;
this.valueType = valueType;
this.value = PerspexProperty.UnsetValue;
this.ValuePriority = int.MaxValue;
}
///
/// Fired whenever the current changes to a new distinct value.
///
public IObservable> Changed
{
get { return this.changed; }
}
///
/// Gets the current value.
///
public object Value
{
get { return this.value; }
}
///
/// Gets the priority of the binding that is currently active.
///
public int ValuePriority
{
get;
private set;
}
///
/// Checks whether a value is valid for a type.
///
///
///
///
public static bool IsValidValue(object value, Type propertyType)
{
TypeInfo type = propertyType.GetTypeInfo();
if (value == PerspexProperty.UnsetValue)
{
return true;
}
else if (value == null)
{
if (type.IsValueType &&
(!type.IsGenericType || !(type.GetGenericTypeDefinition() == typeof(Nullable<>))))
{
return false;
}
}
else
{
if (!type.IsAssignableFrom(value.GetType().GetTypeInfo()))
{
return false;
}
}
return true;
}
///
/// Adds a new binding.
///
/// The binding.
/// The binding priority.
///
/// A disposable that will remove the binding.
///
public IDisposable Add(IObservable