Browse Source

Moved observable into property.

pull/4/head
Steven Kirk 12 years ago
parent
commit
469616cc49
  1. 13
      Perspex.UnitTests/PriorityValueTEsts.cs
  2. 2
      Perspex/PerspexObject.cs
  3. 51
      Perspex/PriorityValue.cs

13
Perspex.UnitTests/PriorityValueTEsts.cs

@ -106,7 +106,7 @@ namespace Perspex.UnitTests
var target = new PriorityValue();
bool called = false;
target.Subscribe(value => called = (value.Item1 == PerspexProperty.UnsetValue && (string)value.Item2 == "foo"));
target.Changed.Subscribe(value => called = (value.Item1 == PerspexProperty.UnsetValue && (string)value.Item2 == "foo"));
target.Add(this.Single("foo"), 0);
Assert.IsTrue(called);
@ -120,7 +120,7 @@ namespace Perspex.UnitTests
bool called = false;
target.Add(subject, 0);
target.Subscribe(value => called = ((string)value.Item1 == "foo" && (string)value.Item2 == "bar"));
target.Changed.Subscribe(value => called = ((string)value.Item1 == "foo" && (string)value.Item2 == "bar"));
subject.OnNext("bar");
Assert.IsTrue(called);
@ -186,16 +186,9 @@ namespace Perspex.UnitTests
/// <typeparam name="T">The type of the observable.</typeparam>
/// <param name="value">The value.</param>
/// <returns>The observable.</returns>
/// <remarks>
/// Seems like there should be something that does this in Rx but I couldn't find it.
/// </remarks>
private IObservable<T> Single<T>(T value)
{
return Observable.Create<T>(observer =>
{
observer.OnNext(value);
return Disposable.Create(() => { });
});
return Observable.Never<T>().StartWith(value);
}
}
}

2
Perspex/PerspexObject.cs

@ -480,7 +480,7 @@ namespace Perspex
{
PriorityValue result = new PriorityValue();
result.Subscribe(x =>
result.Changed.Subscribe(x =>
{
object oldValue = (x.Item1 == PerspexProperty.UnsetValue) ?
this.GetDefaultValue(property) :

51
Perspex/PriorityValue.cs

@ -10,11 +10,21 @@ namespace Perspex
using System.Collections.Generic;
using System.Linq;
using System.Reactive.Disposables;
using System.Reactive.Subjects;
/// <summary>
/// Maintains a list of prioritised bindings together with a current value.
/// </summary>
public class PriorityValue : IObservable<Tuple<object, object>>
/// <remarks>
/// Bindings, in the form of <see cref="IObservable<object>"/>s are added to the object using
/// the <see cref="Add"/> method. With the observable is passed a priority, where lower values
/// represent higher priorites. The current <see cref="Value"/> is selected from the highest
/// priority binding that doesn't return <see cref="PerspexProperty.UnsetValue"/>. 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
/// <see cref="Changed"/> observable is fired with the old and new values.
/// </remarks>
public class PriorityValue
{
/// <summary>
/// The currently registered binding entries.
@ -22,10 +32,9 @@ namespace Perspex
private LinkedList<BindingEntry> bindings = new LinkedList<BindingEntry>();
/// <summary>
/// The current observers.
/// The changed observable.
/// </summary>
private List<IObserver<Tuple<object, object>>> observers =
new List<IObserver<Tuple<object, object>>>();
private Subject<Tuple<object, object>> changed = new Subject<Tuple<object, object>>();
/// <summary>
/// The current value.
@ -46,12 +55,11 @@ namespace Perspex
}
/// <summary>
/// Gets the currently active bindings on this object.
/// Fired whenever the current <see cref="Value"/> changes to a new distinct value.
/// </summary>
/// <returns>An enumerable collection of bindings.</returns>
public IEnumerable<BindingEntry> GetBindings()
public IObservable<Tuple<object, object>> Changed
{
return this.bindings;
get { return this.changed; }
}
/// <summary>
@ -100,17 +108,12 @@ namespace Perspex
}
/// <summary>
/// Notifies the provider that an observer is to receive notifications.
/// Gets the currently active bindings on this object.
/// </summary>
/// <param name="observer">The object that is to receive notifications.</param>
/// <returns>
/// A reference to an interface that allows observers to stop receiving notifications
/// before the provider has finished sending them.
/// </returns>
public IDisposable Subscribe(IObserver<Tuple<object, object>> observer)
/// <returns>An enumerable collection of bindings.</returns>
public IEnumerable<BindingEntry> GetBindings()
{
this.observers.Add(observer);
return Disposable.Create(() => this.observers.Remove(observer));
return this.bindings;
}
/// <summary>
@ -136,18 +139,6 @@ namespace Perspex
this.UpdateValue();
}
/// <summary>
/// Notifies all observers of a change in value.
/// </summary>
/// <param name="value">The old and new values.</param>
private void OnNext(Tuple<object, object> value)
{
foreach (var observer in this.observers)
{
observer.OnNext(value);
}
}
/// <summary>
/// Sets the current value and notifies all observers.
/// </summary>
@ -162,7 +153,7 @@ namespace Perspex
if (!EqualityComparer<object>.Default.Equals(old, value))
{
this.value = value;
this.OnNext(Tuple.Create(old, value));
this.changed.OnNext(Tuple.Create(old, value));
}
}

Loading…
Cancel
Save