Browse Source

Use custom rx for observing properties.

pull/1690/head
Steven Kirk 9 years ago
committed by Steven Kirk
parent
commit
0f1664a846
  1. 46
      src/Avalonia.Base/AvaloniaObjectExtensions.cs
  2. 42
      src/Avalonia.Base/Reactive/AvaloniaObservable.cs
  3. 46
      src/Avalonia.Base/Reactive/AvaloniaPropertyObservable.cs

46
src/Avalonia.Base/AvaloniaObjectExtensions.cs

@ -41,27 +41,7 @@ namespace Avalonia
Contract.Requires<ArgumentNullException>(o != null);
Contract.Requires<ArgumentNullException>(property != null);
return new AvaloniaObservable<object>(
observer =>
{
EventHandler<AvaloniaPropertyChangedEventArgs> handler = (s, e) =>
{
if (e.Property == property)
{
observer.OnNext(e.NewValue);
}
};
observer.OnNext(o.GetValue(property));
o.PropertyChanged += handler;
return Disposable.Create(() =>
{
o.PropertyChanged -= handler;
});
},
GetDescription(o, property));
return new AvaloniaPropertyObservable<object>(o, property);
}
/// <summary>
@ -79,7 +59,7 @@ namespace Avalonia
Contract.Requires<ArgumentNullException>(o != null);
Contract.Requires<ArgumentNullException>(property != null);
return o.GetObservable((AvaloniaProperty)property).Cast<T>();
return new AvaloniaPropertyObservable<T>(o, property);
}
/// <summary>
@ -100,25 +80,9 @@ namespace Avalonia
Contract.Requires<ArgumentNullException>(o != null);
Contract.Requires<ArgumentNullException>(property != null);
return new AvaloniaObservable<Tuple<T, T>>(
observer =>
{
EventHandler<AvaloniaPropertyChangedEventArgs> handler = (s, e) =>
{
if (e.Property == property)
{
observer.OnNext(Tuple.Create((T)e.OldValue, (T)e.NewValue));
}
};
o.PropertyChanged += handler;
return Disposable.Create(() =>
{
o.PropertyChanged -= handler;
});
},
GetDescription(o, property));
return new AvaloniaPropertyObservable<T>(o, property)
.Buffer(2, 1)
.Select(x => Tuple.Create(x[0], x[1]));
}
/// <summary>

42
src/Avalonia.Base/Reactive/AvaloniaObservable.cs

@ -1,42 +0,0 @@
// Copyright (c) The Avalonia Project. All rights reserved.
// Licensed under the MIT license. See licence.md file in the project root for full license information.
using System;
using System.Reactive;
using System.Reactive.Disposables;
namespace Avalonia.Reactive
{
/// <summary>
/// An <see cref="IObservable{T}"/> with an additional description.
/// </summary>
/// <typeparam name="T">The type of the elements in the sequence.</typeparam>
public class AvaloniaObservable<T> : ObservableBase<T>, IDescription
{
private readonly Func<IObserver<T>, IDisposable> _subscribe;
/// <summary>
/// Initializes a new instance of the <see cref="AvaloniaObservable{T}"/> class.
/// </summary>
/// <param name="subscribe">The subscribe function.</param>
/// <param name="description">The description of the observable.</param>
public AvaloniaObservable(Func<IObserver<T>, IDisposable> subscribe, string description)
{
Contract.Requires<ArgumentNullException>(subscribe != null);
_subscribe = subscribe;
Description = description;
}
/// <summary>
/// Gets the description of the observable.
/// </summary>
public string Description { get; }
/// <inheritdoc/>
protected override IDisposable SubscribeCore(IObserver<T> observer)
{
return _subscribe(observer) ?? Disposable.Empty;
}
}
}

46
src/Avalonia.Base/Reactive/AvaloniaPropertyObservable.cs

@ -0,0 +1,46 @@
using System;
namespace Avalonia.Reactive
{
public class AvaloniaPropertyObservable<T> : LightweightObservableBase<T>, IDescription
{
private readonly IAvaloniaObject _target;
private readonly AvaloniaProperty _property;
private T _value;
public AvaloniaPropertyObservable(
IAvaloniaObject target,
AvaloniaProperty property)
{
_target = target;
_property = property;
}
public string Description => $"{_target.GetType().Name}.{_property.Name}";
protected override void Initialize()
{
_value = (T)_target.GetValue(_property);
_target.PropertyChanged += PropertyChanged;
}
protected override void Deinitialize()
{
_target.PropertyChanged -= PropertyChanged;
}
protected override void Subscribed(IObserver<T> observer, bool first)
{
observer.OnNext(_value);
}
private void PropertyChanged(object sender, AvaloniaPropertyChangedEventArgs e)
{
if (e.Property == _property)
{
_value = (T)e.NewValue;
PublishNext(_value);
}
}
}
}
Loading…
Cancel
Save