Skip to content
Browse files

Merge remote-tracking branch 'origin/rxui5-master' into portable

  • Loading branch information...
2 parents 1a02145 + 531a7b4 commit 1527c65b1c7c1f9e8d51154cb66d00128967fc03 @paulcbetts paulcbetts committed Mar 27, 2013
View
6 ReactiveUI.Tests/ReactiveCollectionTest.cs
@@ -24,8 +24,8 @@ public void CollectionCountChangedTest()
var before_output = new List<int>();
var output = new List<int>();
- fixture.CollectionCountChanging.Subscribe(before_output.Add);
- fixture.CollectionCountChanged.Subscribe(output.Add);
+ fixture.CountChanging.Subscribe(before_output.Add);
+ fixture.CountChanged.Subscribe(output.Add);
fixture.Add(10);
fixture.Add(20);
@@ -47,7 +47,7 @@ public void CollectionCountChangedFiresWhenClearing()
{
var items = new ReactiveCollection<object>(new []{new object()});
bool countChanged = false;
- items.CollectionCountChanged.Subscribe(_ => {countChanged = true;});
+ items.CountChanged.Subscribe(_ => {countChanged = true;});
items.Clear();
View
2 ReactiveUI.Xaml/RoutedViewHost.cs
@@ -55,7 +55,7 @@ public RoutedViewHost()
if (RxApp.InUnitTestRunner()) return;
this.WhenAny(x => x.Router.NavigationStack, x => x.Value)
- .SelectMany(x => x.CollectionCountChanged.StartWith(x.Count).Select(_ => x.LastOrDefault()))
+ .SelectMany(x => x.CountChanged.StartWith(x.Count).Select(_ => x.LastOrDefault()))
.Subscribe(vm => {
if (vm == null) {
Content = DefaultContent;
View
19 ReactiveUI/Interfaces.cs
@@ -149,18 +149,18 @@ public interface IReactiveCollection : IEnumerable, INotifyCollectionChanged
/// Fires whenever the number of items in a collection has changed,
/// providing the new Count.
/// </summary>
- IObservable<int> CollectionCountChanged { get; }
+ IObservable<int> CountChanged { get; }
/// <summary>
/// Fires before a collection is about to change, providing the previous
/// Count.
/// </summary>
- IObservable<int> CollectionCountChanging { get; }
+ IObservable<int> CountChanging { get; }
/// <summary>
/// Fires when a collection becomes or stops being empty.
/// </summary>
- IObservable<bool> IsEmpty { get; }
+ IObservable<bool> IsEmptyChanged { get; }
//
// Change Tracking
@@ -296,6 +296,19 @@ public interface IMessageBus : IEnableLogger
IObservable<T> Listen<T>(string contract = null);
/// <summary>
+ /// ListenIncludeLatest provides an Observable that will fire whenever a Message is
+ /// provided for this object via RegisterMessageSource or SendMessage and fire the
+ /// last provided Message immediately if applicable, or null.
+ /// </summary>
+ /// <typeparam name="T">The type of the message to listen to.</typeparam>
+ /// <param name="contract">A unique string to distinguish messages with
+ /// identical types (i.e. "MyCoolViewModel") - if the message type is
+ /// only used for one purpose, leave this as null.</param>
+ /// <returns>An Observable representing the notifications posted to the
+ /// message bus.</returns>
+ IObservable<T> ListenIncludeLatest<T>(string contract = null);
+
+ /// <summary>
/// Determines if a particular message Type is registered.
/// </summary>
/// <param name="type">The type of the message.</param>
View
19 ReactiveUI/MessageBus.cs
@@ -54,6 +54,23 @@ public IObservable<T> Listen<T>(string contract = null)
{
this.Log().Info("Listening to {0}:{1}", typeof (T), contract);
+ return SetupSubjectIfNecessary<T>(contract).Skip(1);
+ }
+
+ /// <summary>
+ /// Listen provides an Observable that will fire whenever a Message is
+ /// provided for this object via RegisterMessageSource or SendMessage.
+ /// </summary>
+ /// <typeparam name="T">The type of the message to listen to.</typeparam>
+ /// <param name="contract">A unique string to distinguish messages with
+ /// identical types (i.e. "MyCoolViewModel") - if the message type is
+ /// only used for one purpose, leave this as null.</param>
+ /// <returns>An Observable representing the notifications posted to the
+ /// message bus.</returns>
+ public IObservable<T> ListenIncludeLatest<T>(string contract = null)
+ {
+ this.Log().Info("Listening to {0}:{1}", typeof(T), contract);
+
return SetupSubjectIfNecessary<T>(contract);
}
@@ -126,7 +143,7 @@ ISubject<T> SetupSubjectIfNecessary<T>(string contract)
return;
}
- ret = new ScheduledSubject<T>(GetScheduler(tuple));
+ ret = new ScheduledSubject<T>(GetScheduler(tuple), null, new BehaviorSubject<T>(default(T)));
mb[tuple] = new NotAWeakReference(ret);
});
View
20 ReactiveUI/ReactiveCollection.cs
@@ -97,14 +97,19 @@ void setupRx(IEnumerable<T> initialContents = null, IScheduler scheduler = null,
// NB: ObservableCollection has a Secret Handshake with WPF where
// they fire an INPC notification with the token "Item[]". Emulate
// it here
- CollectionCountChanging.Subscribe(_ => {
+ CountChanging.Subscribe(_ => {
if (PropertyChanging != null) PropertyChanging(this, new PropertyChangingEventArgs("Count"));
});
- CollectionCountChanged.Subscribe(_ => {
+ CountChanged.Subscribe(_ => {
if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs("Count"));
});
+ IsEmptyChanged.Subscribe(_ =>
+ {
+ if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs("IsEmpty"));
+ });
+
Changing.Subscribe(_ => {
if (PropertyChanging != null) PropertyChanging(this, new PropertyChangingEventArgs("Item[]"));
});
@@ -116,6 +121,11 @@ void setupRx(IEnumerable<T> initialContents = null, IScheduler scheduler = null,
rxObjectsSetup = true;
}
+ public bool IsEmpty
+ {
+ get { return this.Count == 0; }
+ }
+
/*
* Collection<T> core methods
@@ -374,15 +384,15 @@ public IDisposable SuppressChangeNotifications()
}
}
- public IObservable<int> CollectionCountChanging {
+ public IObservable<int> CountChanging {
get { return _changing.Select(_ => _inner.Count).DistinctUntilChanged(); }
}
- public IObservable<int> CollectionCountChanged {
+ public IObservable<int> CountChanged {
get { return _changed.Select(_ => _inner.Count).DistinctUntilChanged(); }
}
- public IObservable<bool> IsEmpty {
+ public IObservable<bool> IsEmptyChanged {
get { return _changed.Select(_ => _inner.Count == 0).DistinctUntilChanged(); }
}
View
4 ReactiveUI/RoutingState.cs
@@ -69,7 +69,7 @@ void setupRx()
if (rxObjectsSetup) return;
NavigateBack = new ReactiveCommand(
- NavigationStack.CollectionCountChanged.StartWith(_NavigationStack.Count).Select(x => x > 1));
+ NavigationStack.CountChanged.StartWith(_NavigationStack.Count).Select(x => x > 1));
NavigateBack.Subscribe(_ =>
NavigationStack.RemoveAt(NavigationStack.Count - 1));
@@ -129,7 +129,7 @@ public static IRoutableViewModel GetCurrentViewModel(this IRoutingState This)
/// </summary>
public static IObservable<IRoutableViewModel> ViewModelObservable(this IRoutingState This)
{
- return This.NavigationStack.CollectionCountChanged
+ return This.NavigationStack.CountChanged
.Select(_ => This.GetCurrentViewModel())
.StartWith(This.GetCurrentViewModel());
}
View
2 ReactiveUI/RxRouting.cs
@@ -125,7 +125,7 @@ public static IDisposable WhenNavigatedTo(this IRoutableViewModel This, Func<IDi
IDisposable inner = null;
var router = This.HostScreen.Router;
- return router.NavigationStack.CollectionCountChanged.Subscribe(_ => {
+ return router.NavigationStack.CountChanged.Subscribe(_ => {
if (router.GetCurrentViewModel() == This) {
if (inner != null) inner.Dispose();
inner = onNavigatedTo();
View
13 ReactiveUI/ScheduledSubject.cs
@@ -9,26 +9,31 @@ namespace ReactiveUI
{
public class ScheduledSubject<T> : ISubject<T>
{
- public ScheduledSubject(IScheduler scheduler, IObserver<T> defaultObserver = null)
+ public ScheduledSubject(IScheduler scheduler, IObserver<T> defaultObserver = null, ISubject<T> defaultSubject = null)
{
_scheduler = scheduler;
_defaultObserver = defaultObserver;
+ _subject = defaultSubject ?? new Subject<T>();
- if (defaultObserver != null) {
+ if (defaultObserver != null)
+ {
_defaultObserverSub = _subject.ObserveOn(_scheduler).Subscribe(_defaultObserver);
}
}
readonly IObserver<T> _defaultObserver;
readonly IScheduler _scheduler;
- readonly Subject<T> _subject = new Subject<T>();
+ readonly ISubject<T> _subject;
int _observerRefCount = 0;
IDisposable _defaultObserverSub;
public void Dispose()
{
- _subject.Dispose();
+ if (_subject is IDisposable)
+ {
+ ((IDisposable)_subject).Dispose();
+ }
}
public void OnCompleted()

0 comments on commit 1527c65

Please sign in to comment.
Something went wrong with that request. Please try again.