Reactive Extensions in JUCEmartin-finke.de/documents/ADC2017_Finke_ReaX_Slides.pdf · What is Rx?...

60
Reactive Extensions in JUCE Martin Finke ADC 2017

Transcript of Reactive Extensions in JUCEmartin-finke.de/documents/ADC2017_Finke_ReaX_Slides.pdf · What is Rx?...

Page 1: Reactive Extensions in JUCEmartin-finke.de/documents/ADC2017_Finke_ReaX_Slides.pdf · What is Rx? • Programming Style for Bindings (think Value::Listener) • Observable, Observer

Reactive Extensions in JUCE

Martin FinkeADC 2017

Page 2: Reactive Extensions in JUCEmartin-finke.de/documents/ADC2017_Finke_ReaX_Slides.pdf · What is Rx? • Programming Style for Bindings (think Value::Listener) • Observable, Observer
Page 3: Reactive Extensions in JUCEmartin-finke.de/documents/ADC2017_Finke_ReaX_Slides.pdf · What is Rx? • Programming Style for Bindings (think Value::Listener) • Observable, Observer

What is Rx?

Page 4: Reactive Extensions in JUCEmartin-finke.de/documents/ADC2017_Finke_ReaX_Slides.pdf · What is Rx? • Programming Style for Bindings (think Value::Listener) • Observable, Observer

What is Rx?• Programming Style for Bindings (think Value::Listener)

• Observable, Observer

• Language-independent (RxJava, RxJS, Rx.NET, …)

Page 5: Reactive Extensions in JUCEmartin-finke.de/documents/ADC2017_Finke_ReaX_Slides.pdf · What is Rx? • Programming Style for Bindings (think Value::Listener) • Observable, Observer

RxCpp (http://github.com/Reactive-Extensions/RxCpp)

• Microsoft Open Technologies (Kirk Shoop, …)

• Header-only, Template Metaprogramming

• Compile Times

Page 6: Reactive Extensions in JUCEmartin-finke.de/documents/ADC2017_Finke_ReaX_Slides.pdf · What is Rx? • Programming Style for Bindings (think Value::Listener) • Observable, Observer

ReaX (http://github.com/martinfinke/ReaX)

RxCpp (http://github.com/Reactive-Extensions/RxCpp)

• Microsoft Open Technologies (Kirk Shoop, …)

• Header-only, Template Metaprogramming

• Compile Times

• Uses RxCpp

• Connects with JUCE Classes

Page 7: Reactive Extensions in JUCEmartin-finke.de/documents/ADC2017_Finke_ReaX_Slides.pdf · What is Rx? • Programming Style for Bindings (think Value::Listener) • Observable, Observer

Example

Page 8: Reactive Extensions in JUCEmartin-finke.de/documents/ADC2017_Finke_ReaX_Slides.pdf · What is Rx? • Programming Style for Bindings (think Value::Listener) • Observable, Observer

Example

Page 9: Reactive Extensions in JUCEmartin-finke.de/documents/ADC2017_Finke_ReaX_Slides.pdf · What is Rx? • Programming Style for Bindings (think Value::Listener) • Observable, Observer

class MainComponent : public Component, private Slider::Listener {public: MainComponent() { drive.addListener(this); } private: Slider drive; void sliderValueChanged(Slider*) override {}};

Page 10: Reactive Extensions in JUCEmartin-finke.de/documents/ADC2017_Finke_ReaX_Slides.pdf · What is Rx? • Programming Style for Bindings (think Value::Listener) • Observable, Observer

class MainComponent : public Component, private Slider::Listener {public: MainComponent() { drive.addListener(this); } private: Label description; Slider drive; void sliderValueChanged(Slider*) override { update(); } void update() { description.setText(driveToString(drive.getValue())); } static String driveToString(double drive);};

Page 11: Reactive Extensions in JUCEmartin-finke.de/documents/ADC2017_Finke_ReaX_Slides.pdf · What is Rx? • Programming Style for Bindings (think Value::Listener) • Observable, Observer

class MainComponent : public Component, private Slider::Listener {public: MainComponent() { drive.addListener(this); update(); } private: Label description; Slider drive; void sliderValueChanged(Slider*) override { update(); } void update() { description.setText(driveToString(drive.getValue())); } static String driveToString(double drive);};

Page 12: Reactive Extensions in JUCEmartin-finke.de/documents/ADC2017_Finke_ReaX_Slides.pdf · What is Rx? • Programming Style for Bindings (think Value::Listener) • Observable, Observer

class MainComponent : public Component, private Slider::Listener, private Button::Listener {public: MainComponent() { drive.addListener(this); turbo.addListener(this); update(); } private: Label description; Slider drive; ToggleButton turbo; void sliderValueChanged(Slider*) override { update(); }

void buttonStateChanged(Button*) override { update(); }

Page 13: Reactive Extensions in JUCEmartin-finke.de/documents/ADC2017_Finke_ReaX_Slides.pdf · What is Rx? • Programming Style for Bindings (think Value::Listener) • Observable, Observer

void update() { double combined = applyTurbo(drive.getValue(), turbo.getToggleState()); description.setText(driveToString(combined)); } static String driveToString(double drive); static double applyTurbo(double drive, bool turbo);};

Page 14: Reactive Extensions in JUCEmartin-finke.de/documents/ADC2017_Finke_ReaX_Slides.pdf · What is Rx? • Programming Style for Bindings (think Value::Listener) • Observable, Observer

drive.rx.value turbo.rx.toggleState

applyTurbo

driveToString

description.rx.text

Page 15: Reactive Extensions in JUCEmartin-finke.de/documents/ADC2017_Finke_ReaX_Slides.pdf · What is Rx? • Programming Style for Bindings (think Value::Listener) • Observable, Observer

drive.rx.valueturbo.rx.toggleStateapplyTurbo

driveToString

description.rx.text

.combineLatest( , )

Page 16: Reactive Extensions in JUCEmartin-finke.de/documents/ADC2017_Finke_ReaX_Slides.pdf · What is Rx? • Programming Style for Bindings (think Value::Listener) • Observable, Observer

drive.rx.valueturbo.rx.toggleStateapplyTurbo

driveToString

description.rx.text

.combineLatest( , )

.map( )

Page 17: Reactive Extensions in JUCEmartin-finke.de/documents/ADC2017_Finke_ReaX_Slides.pdf · What is Rx? • Programming Style for Bindings (think Value::Listener) • Observable, Observer

drive.rx.valueturbo.rx.toggleStateapplyTurbo

driveToString

description.rx.text

.combineLatest( , )

.map( )

.subscribe( );

Page 18: Reactive Extensions in JUCEmartin-finke.de/documents/ADC2017_Finke_ReaX_Slides.pdf · What is Rx? • Programming Style for Bindings (think Value::Listener) • Observable, Observer

drive.rx.valueturbo.rx.toggleStateapplyTurbo

driveToStringdescription.rx.text

.combineLatest( , )

.map( )

.subscribe( );

Page 19: Reactive Extensions in JUCEmartin-finke.de/documents/ADC2017_Finke_ReaX_Slides.pdf · What is Rx? • Programming Style for Bindings (think Value::Listener) • Observable, Observer

MainComponent() {

}

drive.rx.valueturbo.rx.toggleStateapplyTurbo

driveToStringdescription.rx.text

.combineLatest( , )

.map( )

.subscribe( );

Page 20: Reactive Extensions in JUCEmartin-finke.de/documents/ADC2017_Finke_ReaX_Slides.pdf · What is Rx? • Programming Style for Bindings (think Value::Listener) • Observable, Observer

class MainComponent : public Component {public: MainComponent() {

}

private: Reactive<Label> description; Reactive<Slider> drive; Reactive<ToggleButton> turbo;

static String driveToString(double drive); static double applyTurbo(double drive, bool turbo);};

.combineLatest( , ) .map( ) .subscribe( );

drive.rx.valueturbo.rx.toggleState

description.rx.text

applyTurbodriveToString

Page 21: Reactive Extensions in JUCEmartin-finke.de/documents/ADC2017_Finke_ReaX_Slides.pdf · What is Rx? • Programming Style for Bindings (think Value::Listener) • Observable, Observer

class MainComponent : public Component {public: MainComponent() {

}

private: Reactive<Label> description; Reactive<Slider> drive; Reactive<ToggleButton> turbo;

static String driveToString(double drive); static double applyTurbo(double drive, bool turbo);};

.combineLatest( , ) .map( ) .subscribe( );

drive.rx.valueturbo.rx.toggleState

description.rx.text

applyTurbodriveToString

Page 22: Reactive Extensions in JUCEmartin-finke.de/documents/ADC2017_Finke_ReaX_Slides.pdf · What is Rx? • Programming Style for Bindings (think Value::Listener) • Observable, Observer

.combineLatest( ,drive.rx.value

turbo.rx.toggleStateapplyTurbodriveToString

description.rx.text.map( ).subscribe(

)

);

Page 23: Reactive Extensions in JUCEmartin-finke.de/documents/ADC2017_Finke_ReaX_Slides.pdf · What is Rx? • Programming Style for Bindings (think Value::Listener) • Observable, Observer

Observable<double> dr = ;.combineLatest( ,

drive.rx.valueturbo.rx.toggleStateapplyTurbo

driveToStringdescription.rx.text

.map( )

.subscribe(

)

);

dr

Page 24: Reactive Extensions in JUCEmartin-finke.de/documents/ADC2017_Finke_ReaX_Slides.pdf · What is Rx? • Programming Style for Bindings (think Value::Listener) • Observable, Observer

tbObservable<bool> tb = ;Observable<double> dr = ;

.combineLatest( ,

drive.rx.valueturbo.rx.toggleState

applyTurbodriveToString

description.rx.text.map( ).subscribe(

)

);

dr

Page 25: Reactive Extensions in JUCEmartin-finke.de/documents/ADC2017_Finke_ReaX_Slides.pdf · What is Rx? • Programming Style for Bindings (think Value::Listener) • Observable, Observer

tbObservable<bool> tb = ;Observable<double> dr = ;

.combineLatest( ,

drive.rx.valueturbo.rx.toggleState

applyTurbodriveToString

description.rx.text.map( ).subscribe(

)

);

dr

An Observable emits values over time.

Page 26: Reactive Extensions in JUCEmartin-finke.de/documents/ADC2017_Finke_ReaX_Slides.pdf · What is Rx? • Programming Style for Bindings (think Value::Listener) • Observable, Observer

tbObservable<bool> tb = ;Observable<double> dr = ;

.combineLatest( ,

drive.rx.valueturbo.rx.toggleState

applyTurbodriveToString

description.rx.text.map( ).subscribe(

)

);

dr

Page 27: Reactive Extensions in JUCEmartin-finke.de/documents/ADC2017_Finke_ReaX_Slides.pdf · What is Rx? • Programming Style for Bindings (think Value::Listener) • Observable, Observer

Observable<double> cd = ;.combineLatest( ,applyTurbo tbObservable<bool> tb = ;Observable<double> dr = ;drive.rx.value

turbo.rx.toggleState

driveToStringdescription.rx.text

.map( )

.subscribe(

)

);

drcd

Page 28: Reactive Extensions in JUCEmartin-finke.de/documents/ADC2017_Finke_ReaX_Slides.pdf · What is Rx? • Programming Style for Bindings (think Value::Listener) • Observable, Observer

Observable<double> cd = ;.combineLatest( ,applyTurbo

static double applyTurbo(double drive, bool turbo);

tbObservable<bool> tb = ;Observable<double> dr = ;drive.rx.value

turbo.rx.toggleState

driveToStringdescription.rx.text

.map( )

.subscribe(

)

);

drcd

Page 29: Reactive Extensions in JUCEmartin-finke.de/documents/ADC2017_Finke_ReaX_Slides.pdf · What is Rx? • Programming Style for Bindings (think Value::Listener) • Observable, Observer

Observable<double> cd = ;.combineLatest( ,applyTurbo

static double applyTurbo(double drive, bool turbo);

tbObservable<bool> tb = ;Observable<double> dr = ;drive.rx.value

turbo.rx.toggleState

driveToStringdescription.rx.text

.map( )

.subscribe(

)

);

drcd

Page 30: Reactive Extensions in JUCEmartin-finke.de/documents/ADC2017_Finke_ReaX_Slides.pdf · What is Rx? • Programming Style for Bindings (think Value::Listener) • Observable, Observer

Observable<double> cd = ;.combineLatest( ,applyTurbo

static double applyTurbo(double drive, bool turbo);

tbObservable<bool> tb = ;Observable<double> dr = ;drive.rx.value

turbo.rx.toggleState

driveToStringdescription.rx.text

.map( )

.subscribe(

)

);

drcd

Page 31: Reactive Extensions in JUCEmartin-finke.de/documents/ADC2017_Finke_ReaX_Slides.pdf · What is Rx? • Programming Style for Bindings (think Value::Listener) • Observable, Observer

Observable<double> cd = ;.combineLatest( ,applyTurbo

static double applyTurbo(double drive, bool turbo);

tbObservable<bool> tb = ;Observable<double> dr = ;drive.rx.value

turbo.rx.toggleState

driveToStringdescription.rx.text

.map( )

.subscribe(

)

);

drcd

Page 32: Reactive Extensions in JUCEmartin-finke.de/documents/ADC2017_Finke_ReaX_Slides.pdf · What is Rx? • Programming Style for Bindings (think Value::Listener) • Observable, Observer

Observable<double> cd = ;.combineLatest( ,applyTurbo

static double applyTurbo(double drive, bool turbo);

tbObservable<bool> tb = ;Observable<double> dr = ;drive.rx.value

turbo.rx.toggleState

driveToStringdescription.rx.text

.map( )

.subscribe(

)

);

drcd

Page 33: Reactive Extensions in JUCEmartin-finke.de/documents/ADC2017_Finke_ReaX_Slides.pdf · What is Rx? • Programming Style for Bindings (think Value::Listener) • Observable, Observer

Observable<double> cd = ;.combineLatest( ,applyTurbo

static double applyTurbo(double drive, bool turbo);

tbObservable<bool> tb = ;Observable<double> dr = ;drive.rx.value

turbo.rx.toggleState

driveToStringdescription.rx.text

.map( )

.subscribe(

)

);

drcd

Page 34: Reactive Extensions in JUCEmartin-finke.de/documents/ADC2017_Finke_ReaX_Slides.pdf · What is Rx? • Programming Style for Bindings (think Value::Listener) • Observable, Observer

Observable<double> cd = ;.combineLatest( ,applyTurbo

static double applyTurbo(double drive, bool turbo);

tbObservable<bool> tb = ;Observable<double> dr = ;drive.rx.value

turbo.rx.toggleState

driveToStringdescription.rx.text

.map( )

.subscribe(

)

);

drcd

Page 35: Reactive Extensions in JUCEmartin-finke.de/documents/ADC2017_Finke_ReaX_Slides.pdf · What is Rx? • Programming Style for Bindings (think Value::Listener) • Observable, Observer

Observable<String> st = ;Observable<double> cd = ;.combineLatest( ,applyTurbo tbObservable<bool> tb = ;Observable<double> dr = ;drive.rx.value

turbo.rx.toggleState

driveToStringdescription.rx.text

.map( ).subscribe(

)

);

drcd

st

Page 36: Reactive Extensions in JUCEmartin-finke.de/documents/ADC2017_Finke_ReaX_Slides.pdf · What is Rx? • Programming Style for Bindings (think Value::Listener) • Observable, Observer

Observable<String> st = ;Observable<double> cd = ;.combineLatest( ,applyTurbo tbObservable<bool> tb = ;Observable<double> dr = ;drive.rx.value

turbo.rx.toggleState

driveToStringdescription.rx.text

.map( ).subscribe(

)

);

drcd

st

static String driveToString(double drive);

Page 37: Reactive Extensions in JUCEmartin-finke.de/documents/ADC2017_Finke_ReaX_Slides.pdf · What is Rx? • Programming Style for Bindings (think Value::Listener) • Observable, Observer

Observable<String> st = ;Observable<double> cd = ;.combineLatest( ,applyTurbo tbObservable<bool> tb = ;Observable<double> dr = ;drive.rx.value

turbo.rx.toggleState

driveToStringdescription.rx.text

.map( ).subscribe(

)

);

drcd

st

static String driveToString(double drive);

Page 38: Reactive Extensions in JUCEmartin-finke.de/documents/ADC2017_Finke_ReaX_Slides.pdf · What is Rx? • Programming Style for Bindings (think Value::Listener) • Observable, Observer

Observable<String> st = ;Observable<double> cd = ;.combineLatest( ,applyTurbo tbObservable<bool> tb = ;Observable<double> dr = ;drive.rx.value

turbo.rx.toggleState

driveToStringdescription.rx.text

.map( ).subscribe(

)

);

drcd

st

static String driveToString(double drive);

Page 39: Reactive Extensions in JUCEmartin-finke.de/documents/ADC2017_Finke_ReaX_Slides.pdf · What is Rx? • Programming Style for Bindings (think Value::Listener) • Observable, Observer

Observable<String> st = ;Observable<double> cd = ;.combineLatest( ,applyTurbo tbObservable<bool> tb = ;Observable<double> dr = ;drive.rx.value

turbo.rx.toggleState

driveToStringdescription.rx.text

.map( ).subscribe(

)

);

drcd

st

static String driveToString(double drive);

Page 40: Reactive Extensions in JUCEmartin-finke.de/documents/ADC2017_Finke_ReaX_Slides.pdf · What is Rx? • Programming Style for Bindings (think Value::Listener) • Observable, Observer

Observable<String> st = ;Observable<double> cd = ;.combineLatest( ,applyTurbo tbObservable<bool> tb = ;Observable<double> dr = ;drive.rx.value

turbo.rx.toggleState

driveToStringdescription.rx.text

.map( ).subscribe(

)

);

drcd

st

static String driveToString(double drive);

Page 41: Reactive Extensions in JUCEmartin-finke.de/documents/ADC2017_Finke_ReaX_Slides.pdf · What is Rx? • Programming Style for Bindings (think Value::Listener) • Observable, Observer

Observable<String> st = ;Observable<double> cd = ;.combineLatest( ,applyTurbo tbObservable<bool> tb = ;Observable<double> dr = ;drive.rx.value

turbo.rx.toggleState

driveToStringdescription.rx.text

.map( ).subscribe(

)

);

drcd

st

Operators create new Observables from Observables.

map

Page 42: Reactive Extensions in JUCEmartin-finke.de/documents/ADC2017_Finke_ReaX_Slides.pdf · What is Rx? • Programming Style for Bindings (think Value::Listener) • Observable, Observer

Observable<String> st = ;Observable<double> cd = ;.combineLatest( ,applyTurbo tbObservable<bool> tb = ;Observable<double> dr = ;drive.rx.value

turbo.rx.toggleState

driveToStringdescription.rx.text

.map( ).subscribe(

)

);

drcd

st

Page 43: Reactive Extensions in JUCEmartin-finke.de/documents/ADC2017_Finke_ReaX_Slides.pdf · What is Rx? • Programming Style for Bindings (think Value::Listener) • Observable, Observer

Observer<String> labelText = ;Observable<String> st = ;Observable<double> cd = ;.combineLatest( ,applyTurbo tbObservable<bool> tb = ;Observable<double> dr = ;drive.rx.value

turbo.rx.toggleState

driveToStringdescription.rx.text

.map( )

.subscribe(

)

);

drcd

st labelText

Page 44: Reactive Extensions in JUCEmartin-finke.de/documents/ADC2017_Finke_ReaX_Slides.pdf · What is Rx? • Programming Style for Bindings (think Value::Listener) • Observable, Observer

Observer<String> labelText = ;Observable<String> st = ;Observable<double> cd = ;.combineLatest( ,applyTurbo tbObservable<bool> tb = ;Observable<double> dr = ;drive.rx.value

turbo.rx.toggleState

driveToStringdescription.rx.text

.map( )

.subscribe(

)

);

drcd

st labelText

Observers receive values from Observables.

Page 45: Reactive Extensions in JUCEmartin-finke.de/documents/ADC2017_Finke_ReaX_Slides.pdf · What is Rx? • Programming Style for Bindings (think Value::Listener) • Observable, Observer

Observabletemplate<typename T>

class Observable {

public: template<typename U>

Observable<U> map(std::function<U(T)> function);

Subscription subscribe(Observer<T> observer);

};…

Page 46: Reactive Extensions in JUCEmartin-finke.de/documents/ADC2017_Finke_ReaX_Slides.pdf · What is Rx? • Programming Style for Bindings (think Value::Listener) • Observable, Observer

Observertemplate<typename T>class Observer {public: void onNext(T value); };

Page 47: Reactive Extensions in JUCEmartin-finke.de/documents/ADC2017_Finke_ReaX_Slides.pdf · What is Rx? • Programming Style for Bindings (think Value::Listener) • Observable, Observer

Subjecttemplate<typename T>class Subject : public Observer<T>, public Observable<T> {};

Page 48: Reactive Extensions in JUCEmartin-finke.de/documents/ADC2017_Finke_ReaX_Slides.pdf · What is Rx? • Programming Style for Bindings (think Value::Listener) • Observable, Observer

Subjecttemplate<typename T>class Subject : public Observer<T>, public Observable<T> {};

Subject<int> numbers; numbers.subscribe([](int number) { }); numbers.onNext(17); // Calls the lambda

Page 49: Reactive Extensions in JUCEmartin-finke.de/documents/ADC2017_Finke_ReaX_Slides.pdf · What is Rx? • Programming Style for Bindings (think Value::Listener) • Observable, Observer

Sounds familiar?JUCE Rx

Value Subject

Value::Listener Observer

addListener() subscribe()

valueChanged() onNext()

Page 50: Reactive Extensions in JUCEmartin-finke.de/documents/ADC2017_Finke_ReaX_Slides.pdf · What is Rx? • Programming Style for Bindings (think Value::Listener) • Observable, Observer

🔊🎹

Page 51: Reactive Extensions in JUCEmartin-finke.de/documents/ADC2017_Finke_ReaX_Slides.pdf · What is Rx? • Programming Style for Bindings (think Value::Listener) • Observable, Observer

Rx and Audio/MIDI

🔊🎹

Page 52: Reactive Extensions in JUCEmartin-finke.de/documents/ADC2017_Finke_ReaX_Slides.pdf · What is Rx? • Programming Style for Bindings (think Value::Listener) • Observable, Observer

Rx and Audio/MIDI

• Real-time Thread → Real-time Thread: ⛔Use MidiKeyboardState, MidiMessageCollector, …

Page 53: Reactive Extensions in JUCEmartin-finke.de/documents/ADC2017_Finke_ReaX_Slides.pdf · What is Rx? • Programming Style for Bindings (think Value::Listener) • Observable, Observer

Rx and Audio/MIDI

• Real-time Thread → Real-time Thread: ⛔Use MidiKeyboardState, MidiMessageCollector, …

• Real-time Thread → Main Thread: ✅LockFreeSource

Page 54: Reactive Extensions in JUCEmartin-finke.de/documents/ADC2017_Finke_ReaX_Slides.pdf · What is Rx? • Programming Style for Bindings (think Value::Listener) • Observable, Observer

Rx and Audio/MIDI

• Real-time Thread → Real-time Thread: ⛔Use MidiKeyboardState, MidiMessageCollector, …

• Real-time Thread → Main Thread: ✅LockFreeSource

• Main Thread → Real-time Thread: ✅LockFreeTarget

Page 55: Reactive Extensions in JUCEmartin-finke.de/documents/ADC2017_Finke_ReaX_Slides.pdf · What is Rx? • Programming Style for Bindings (think Value::Listener) • Observable, Observer

LockFreeTargettemplate<typename T>class LockFreeTarget : public Observer<T> {public: // Call from real-time thread: bool tryDequeue(T& value); bool tryDequeueAll(T& value);};

Page 56: Reactive Extensions in JUCEmartin-finke.de/documents/ADC2017_Finke_ReaX_Slides.pdf · What is Rx? • Programming Style for Bindings (think Value::Listener) • Observable, Observer

Where To Go Next

http://reactivex.io/rxjs/

Page 57: Reactive Extensions in JUCEmartin-finke.de/documents/ADC2017_Finke_ReaX_Slides.pdf · What is Rx? • Programming Style for Bindings (think Value::Listener) • Observable, Observer

Where To Go Next

http://reactivex.io/rxjs/

Page 58: Reactive Extensions in JUCEmartin-finke.de/documents/ADC2017_Finke_ReaX_Slides.pdf · What is Rx? • Programming Style for Bindings (think Value::Listener) • Observable, Observer

Where To Go Next

http://rxmarbles.com

Page 59: Reactive Extensions in JUCEmartin-finke.de/documents/ADC2017_Finke_ReaX_Slides.pdf · What is Rx? • Programming Style for Bindings (think Value::Listener) • Observable, Observer

Where To Go Next

http://rxmarbles.com

Page 60: Reactive Extensions in JUCEmartin-finke.de/documents/ADC2017_Finke_ReaX_Slides.pdf · What is Rx? • Programming Style for Bindings (think Value::Listener) • Observable, Observer

Try it, you'll like it!

http://github.com/martinfinke/ReaX