From cffe103acc1c148b59f7c12f6a4bfff12004d467 Mon Sep 17 00:00:00 2001 From: Steven Kirk Date: Mon, 4 May 2015 09:21:25 +0200 Subject: [PATCH] Added PerspexObservable. Similar to Rx's AnonymousObservable that is created using Observable.Create, but it also implements IDescription. This description is populated when created by PerspexObject.GetObservable. --- Perspex.Base/PerspexObject.cs | 34 +++++++++++++-------- Perspex.Base/Reactive/PerspexObservable.cs | 35 ++++++++++++++++++++++ 2 files changed, 57 insertions(+), 12 deletions(-) create mode 100644 Perspex.Base/Reactive/PerspexObservable.cs diff --git a/Perspex.Base/PerspexObject.cs b/Perspex.Base/PerspexObject.cs index 564698a54b..25994d2093 100644 --- a/Perspex.Base/PerspexObject.cs +++ b/Perspex.Base/PerspexObject.cs @@ -15,7 +15,7 @@ namespace Perspex using Perspex.Diagnostics; using Splat; using System.Reactive.Disposables; - + using Perspex.Reactive; /// /// The priority of a binding. @@ -306,7 +306,7 @@ namespace Perspex { Contract.Requires(property != null); - return Observable.Create(observer => + return new PerspexObservable(observer => { EventHandler handler = (s, e) => { @@ -318,19 +318,19 @@ namespace Perspex this.PropertyChanged += handler; - return () => + return Disposable.Create(() => { this.PropertyChanged -= handler; - }; - }).StartWith(this.GetValue(property)); + }); + }, this.GetObservableDescription(property)).StartWith(this.GetValue(property)); } /// /// Gets an observable for a . /// - /// - /// - /// + /// The property type. + /// The property. + /// An observable. public IObservable GetObservable(PerspexProperty property) { Contract.Requires(property != null); @@ -346,7 +346,7 @@ namespace Perspex /// public IObservable> GetObservableWithHistory(PerspexProperty property) { - return Observable.Create>(observer => + return new PerspexObservable>(observer => { EventHandler handler = (s, e) => { @@ -358,11 +358,11 @@ namespace Perspex this.PropertyChanged += handler; - return () => + return Disposable.Create(() => { this.PropertyChanged -= handler; - }; - }); + }); + }, this.GetObservableDescription(property)); } /// @@ -759,6 +759,16 @@ namespace Perspex } } + /// + /// Gets a description of a property that van be used in observables. + /// + /// The property + /// The description. + private string GetObservableDescription(PerspexProperty property) + { + return string.Format("{0}.{1}", this.GetType().Name, property.Name); + } + /// /// Raises the event. /// diff --git a/Perspex.Base/Reactive/PerspexObservable.cs b/Perspex.Base/Reactive/PerspexObservable.cs new file mode 100644 index 0000000000..ad5b1568bb --- /dev/null +++ b/Perspex.Base/Reactive/PerspexObservable.cs @@ -0,0 +1,35 @@ +// ----------------------------------------------------------------------- +// +// Copyright 2014 MIT Licence. See licence.md for more information. +// +// ----------------------------------------------------------------------- + +namespace Perspex.Reactive +{ + using System; + using System.Reactive; + using System.Reactive.Disposables; + + public sealed class PerspexObservable : ObservableBase, IDescription + { + private readonly Func, IDisposable> subscribe; + + public string Description { get; } + + public PerspexObservable(Func, IDisposable> subscribe, string description) + { + if (subscribe == null) + { + throw new ArgumentNullException("subscribe"); + } + + this.subscribe = subscribe; + this.Description = description; + } + + protected override IDisposable SubscribeCore(IObserver observer) + { + return this.subscribe(observer) ?? Disposable.Empty; + } + } +} \ No newline at end of file