Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

sunpeng196/cpp.react

Open more actions menu
 
 

Repository files navigation

C++React

C++React is reactive programming library for C++11.

Generally speaking, it provides abstractions to handle change propagation and data processing for a push-based event model. A more practical description is that it enables coordinated, multi-layered - and potentially parallel - execution of callbacks. All this happens implicitly, based on declarative definitions, with guarantees regarding

  • update minimality - nothing is re-calculated or processed unnecessarily;
  • glitch freedom - no transiently inconsistent data sets;
  • thread safety - no data races for parallel execution by avoiding side effects.

The core abstractions of the library are

  • signals, reactive variables that are automatically re-calculated when their dependencies change, and
  • event streams as composable first class objects.

Signals specifically deal with aspects of time-varying state, whereas event streams facilitate event processing in general.

Additional features include

  • a publish/subscribe mechanism for callbacks with side effects;
  • a set of operations and algorithms to combine signals and events;
  • a domain model to encapsulate multiple reactive systems;
  • transactions to group related events, supporting both synchronous and asynchrounous execution.

Documentation

If you're interested in learning about C++React, have a look at its documentation.

Using the library

This library is a work-in-progress. It should not be considered release quality yet and its API might still change. It is, however, in a perfectly usable state and has already received a fair amount of testing and tuning.

Dependencies

Compiling

C++React has been tested with the following compilers:

  • Visual Studio 2013.2
  • GCC 4.8.2
  • Clang 3.4

To build with Visual Studio, use the pre-made solution found in project/msvc/.

To build with GCC or Clang, use CMake:

mkdir build
cd build
cmake ..
make

For more details, refer to the Build instructions.

Features by example

Signals

Signals are self-updating reactive variables. They can be combined in expressions to create new signals, which are automatically re-calculated when their dependencies change.

using namespace std;
using namespace react;

// Defines a reactive domain that uses single-threaded, sequential updating
REACTIVE_DOMAIN(D, sequential)

// Defines aliases for types of the given domain,
// e.g. using VarSignalT<X> = VarSignal<D,X>
USING_REACTIVE_DOMAIN(D)

// Two reactive variables that can be manipulated imperatively
// to input external changes
VarSignalT<int> width  = MakeVar<D>(1);
VarSignalT<int> height = MakeVar<D>(2);

// A signal that depends on width and height and multiplies their values
SignalT<int> area = MakeSignal(
    With(width, height),
    [] (int w, int h) {
        return w * h;
    });

Signal values can be accessed imperatively:

cout << "area: " << area.Value() << endl; // => area: 2

// Width changed, so area is re-calculated automatically
width.Set(10);

cout << "area: " << area.Value() << endl; // => area: 20

Or, instead of using Value() to pull the new value, callback functions can be registered to receive notifications on a change:

Observe(area, [] (int newValue) {
	cout << "area changed: " << newValue << endl;
});

Overloaded operators for signal types allow to omit MakeSignal for a more concise syntax:

// Lift as reactive expression - equivalent to previous example
SignalT<int> area = width * height;

Event streams

Unlike signals, event streams are not centered on changing state, but represent flows of discrete values. They are first-class objects and can be merged, filtered, transformed or composed to more complex types:

using namespace std;
using namespace react;

REACTIVE_DOMAIN(D, sequential)
USING_REACTIVE_DOMAIN(D)

// Two event sources
EventSourceT<Token> leftClick  = MakeEventSource<D>();
EventSourceT<Token> rightClick = MakeEventSource<D>();

// Merge both event streams
EventsT<Token> anyClick = leftClick | rightClick;

// React to events
Observe(anyClick, [] (Token) {
    cout << "clicked!" << endl;
});
leftClick.Emit(); // => clicked!
rightClick.Emit(); // => clicked!

Parallelism and concurrency

When enabling it through the concurrency policy, updates are automatically parallelized:

REACTIVE_DOMAIN(D, parallel)

VarSignalT<int> in = MakeVar<D>(0);

SignalT<int> op1 = MakeSignal(in,
    [] (int in) {
        int result = doCostlyOperation1(in);
        return result;
    });

SignalT<int> op2 = MakeSignal(in,
    [] (int in) {
        int result = doCostlyOperation2(in);
        return result;
    });

// op1 and op2 can be re-calculated in parallel
SignalT<int> out = op1 + op2;

Acknowledgements

The API of C++React has been inspired by the following two research papers:

About

C++React: A reactive programming library for C++11.

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages

  • C++ 99.7%
  • CMake 0.3%
Morty Proxy This is a proxified and sanitized view of the page, visit original site.