Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/rxui5-backports' into rxui4
Browse files Browse the repository at this point in the history
  • Loading branch information
anaisbetts committed Aug 29, 2013
2 parents 69f4b7a + 27b82cd commit b987c54
Show file tree
Hide file tree
Showing 9 changed files with 195 additions and 76 deletions.
13 changes: 10 additions & 3 deletions ReactiveUI.Xaml/ReactiveAsyncCommand.cs
Expand Up @@ -108,9 +108,7 @@ void commonCtor(int maximumConcurrent, IScheduler scheduler, IObservable<bool> c
CanExecuteObservable.Subscribe(x => {
this.Log().Debug("Setting canExecuteLatest to {0}", x);
_canExecuteLatest = x;
if (CanExecuteChanged != null) {
CanExecuteChanged(this, new EventArgs());
}
raiseCanExecuteChanged(EventArgs.Empty);
});

if (canExecute != null) {
Expand Down Expand Up @@ -210,6 +208,15 @@ void marshalFailures(Action block)
{
marshalFailures(_ => block(), Unit.Default);
}

protected virtual void raiseCanExecuteChanged(EventArgs e)
{
EventHandler handler = this.CanExecuteChanged;
if (handler != null) {
handler(this, e);
}
}

}

public static class ReactiveAsyncCommandMixins
Expand Down
10 changes: 9 additions & 1 deletion ReactiveUI.Xaml/ReactiveCommand.cs
Expand Up @@ -116,7 +116,7 @@ void commonCtor(IScheduler scheduler, bool initialCondition = true)

_canExecuteSubject = new ScheduledSubject<bool>(RxApp.DeferredScheduler);
canExecuteLatest = new ObservableAsPropertyHelper<bool>(_canExecuteSubject,
b => { if (CanExecuteChanged != null) CanExecuteChanged(this, EventArgs.Empty); },
b => { raiseCanExecuteChanged(EventArgs.Empty); },
initialCondition, scheduler);

_canExecuteProbed = new Subject<object>();
Expand Down Expand Up @@ -192,6 +192,14 @@ void marshalFailures(Action block)
{
marshalFailures(_ => block(), Unit.Default);
}

protected virtual void raiseCanExecuteChanged(EventArgs e)
{
EventHandler handler = this.CanExecuteChanged;
if (handler != null) {
handler(this, e);
}
}
}

public static class ReactiveCommandMixins
Expand Down
13 changes: 13 additions & 0 deletions ReactiveUI/Interfaces.cs
Expand Up @@ -294,6 +294,19 @@ public interface IMessageBus : IEnableLogger
/// <returns></returns>
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>
Expand Down
21 changes: 19 additions & 2 deletions ReactiveUI/MessageBus.cs
Expand Up @@ -52,7 +52,24 @@ public void RegisterScheduler<T>(IScheduler scheduler, string contract = null)
/// message bus.</returns>
public IObservable<T> Listen<T>(string contract = null)
{
this.Log().Info("Listening to {0}:{1}", typeof (T), contract);
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);
}
Expand Down Expand Up @@ -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);
});

Expand Down
30 changes: 30 additions & 0 deletions ReactiveUI/ObservableAsPropertyHelper.cs
Expand Up @@ -186,6 +186,36 @@ public static class OAPHCreationHelperMixin

return ret;
}

/// <summary>
/// Converts an Observable to an ObservableAsPropertyHelper and
/// automatically provides the onChanged method to raise the property
/// changed notification.
/// </summary>
/// <param name="source">The ReactiveObject that has the property</param>
/// <param name="property">An Expression representing the property (i.e.
/// 'x => x.SomeProperty'</param>
/// <param name="initialValue">The initial value of the property.</param>
/// <param name="scheduler">The scheduler that the notifications will be
/// provided on - this should normally be a Dispatcher-based scheduler
/// (and is by default)</param>
/// <returns>An initialized ObservableAsPropertyHelper; use this as the
/// backing field for your property.</returns>
public static ObservableAsPropertyHelper<TRet> ToProperty<TObj, TRet>(
this IObservable<TRet> This,
TObj source,
Expression<Func<TObj, TRet>> property,
out ObservableAsPropertyHelper<TRet> result,
TRet initialValue = default(TRet),
IScheduler scheduler = null)
where TObj : ReactiveObject
{
var ret = source.ObservableToProperty(This, property, initialValue, scheduler);

result = ret;
return ret;
}

}
}

Expand Down

0 comments on commit b987c54

Please sign in to comment.