Friday, September 6, 2013

RxC++ ReactiveCommand

I rewrote the ReactiveCommand class (from Paul Betts ReactiveUI library for C#) to demonstrate how to bind async commands to Xaml Buttons. This is a work in progress (it does not use data binding yet, is missing some error handling and there is no reason that it should be specific to the Xaml UI framework - should work with WIN32 button etc..), but I did build it for use in this Windows 8.1 sample.

ReactiveCommand models calls to the Execute function as a Sequence of the value passed to each Execute. All subscriptions to it are called on the UI thread. There can be many subscriptions directly to ReactiveCommand, there can also be many async functions registered.

Each async function registered takes the value passed to Execute does work and returns a result. Each call to RegisterAsyncCommand returns a new Sequence of the results from each call to the registered function. All subscriptions to the Sequence of results are called on the UI thread.

ReactiveCommand also provides Sequences of bools, that can be subscribed, that represent its state. When the CanExecute Sequence is bound to the enabled property of the button the state of the ReactiveCommand is communicated into the ui.

By default ReactiveCommand will ignore Execute until all the subscribers (sync and async) to the previous Execute call have finished. This can be changed during construction.

Here is some (out-of-order) usage from the sample.

Subscription - async version (Scenario1.Xaml.cpp):

Subscription - sync version (Scenario1.Xaml.cpp):

Binding (Scenario1.Xaml.cpp):

Creation (Scenario1.Xaml.cpp):

Create state sequences that are used by these ReactiveCommand (Scenario1.Xaml.cpp):

Thursday, September 5, 2013

DeferOperation

I have been working on RxC++ for a few months now. I have added Schedulers and lots of operators. Now I am trying to apply Rx to a C++ Windows Store app.

I was told that Deferrals did not compose well with Rx. This motivated me to design the DeferOperation operator.

DeferOperation demonstrates how Rx can be extended by a few engineers to provide services for many. Another way to say this is that Rx allows Async Algorithms to be written once, carefully, so that many others can re-use them.


These are all references to the Windows 8.1 Accelerometer sample I am modifying.

Usage (App.Xaml.Cpp):

DeferOperation defaults to the ui thread by reading the context off of the Window, but when the suspending event is fired the Window is not valid, so this uses the current thread scheduler explicitly. publish and connect_forever ensure that the work is done even if nothing subscribes the result.


The implementation follows.

The core of the DeferOperation operator is (cpprx/rx-winrt.hpp):

sop is the first lambda from the usage (cpprx/rx-winrt.hpp):

sob is the second lambda from the usage (the OperationPattern is passed so that the SuspendingOperation and the Deferral are available to the sequence if it wants to see the Deadline or Complete early, for example) (cpprx/rx-winrt.hpp)
Using will retrieve the resource (OperationPattern), subscribe to the result of sob and Dispose the resource when the subscription completes or errors.

OperationPattern provides the abstraction needed by Using. It will call get and complete the deferral (cpprx/rx-winrt.hpp):