// Copyright Sebastian Jeckel 2014. // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) #include #include "tbb/tick_count.h" #include "react/Domain.h" #include "react/Signal.h" #include "react/Event.h" #include "react/Observer.h" /////////////////////////////////////////////////////////////////////////////////////////////////// /// Example 1 - Asynchronous transactions /////////////////////////////////////////////////////////////////////////////////////////////////// namespace example1 { using namespace react; using namespace std; REACTIVE_DOMAIN(D, sequential_concurrent) class Sensor { public: USING_REACTIVE_DOMAIN(D) EventSourceT Samples = MakeEventSource(); }; void Run() { cout << "Example 1 - Asynchronous transactions" << endl; Sensor mySensor; Observe(mySensor.Samples, [] (int v) { cout << v << endl; }); TransactionStatus status; AsyncTransaction(status, [&] { mySensor.Samples << 30 << 31 << 31 << 32; }); AsyncTransaction(status, [&] { mySensor.Samples << 40 << 41 << 51 << 62; }); // Waits until both transactions are completed. // This does not mean that both transactions are interleaved. status.Wait(); cout << endl; } } /////////////////////////////////////////////////////////////////////////////////////////////////// /// Example 2 - Transaction merging /////////////////////////////////////////////////////////////////////////////////////////////////// namespace example2 { using namespace react; using namespace std; REACTIVE_DOMAIN(D, sequential_concurrent) class Sensor { public: USING_REACTIVE_DOMAIN(D) EventSourceT Samples = MakeEventSource(); }; const int K = 100000; namespace v1 { void Run() { cout << "Example 2 - Transaction merging (no merging)" << endl; Sensor mySensor; int sum = 0; Observe(mySensor.Samples, [&] (int v) { sum += v; }); TransactionStatus status; cout << "Executing " << K << " async transactions..."; auto t0 = tbb::tick_count::now(); for (int i=0; i < K; i++) { AsyncTransaction(status, [&] { mySensor.Samples << 3 << 4 << 2 << 1; }); } status.Wait(); double d = (tbb::tick_count::now() - t0).seconds(); cout << " done." << endl; cout << " Sum: " << sum << endl; cout << " Time: " << d << endl; cout << endl; } } namespace v2 { void Run() { cout << "Example 2 - Transaction merging (allow merging)" << endl; Sensor mySensor; int sum = 0; Observe(mySensor.Samples, [&] (int v) { sum += v; }); TransactionStatus status; cout << "Executing " << K << " async transactions..."; auto t0 = tbb::tick_count::now(); for (int i=0; i < K; i++) { AsyncTransaction(allow_merging, status, [&] { mySensor.Samples << 3 << 4 << 2 << 1; }); } status.Wait(); double d = (tbb::tick_count::now() - t0).seconds(); cout << " done." << endl; cout << " Sum: " << sum << endl; cout << " Time: " << d << endl; cout << endl; } } } /////////////////////////////////////////////////////////////////////////////////////////////////// /// Example 3 - Continuations (1) /////////////////////////////////////////////////////////////////////////////////////////////////// namespace example3 { using namespace react; using namespace std; REACTIVE_DOMAIN(D, sequential_concurrent) class Widget { public: USING_REACTIVE_DOMAIN(D) VarSignalT Label1 = MakeVar(string( "Change" )); VarSignalT Label2 = MakeVar(string( "me!" )); EventSourceT<> Reset = MakeEventSource(); Widget() : resetCont_ ( MakeContinuation( Reset, [this] (Token) { Label1 <<= string( "Change" ); Label2 <<= string( "me!" ); }) ) {} private: Continuation resetCont_; }; void Run() { cout << "Example 3 - Continuations (1)" << endl; Widget myWidget; Observe(myWidget.Label1, [&] (const string& v) { cout << "Label 1 changed to " << v << endl; }); Observe(myWidget.Label2, [&] (const string& v) { cout << "Label 2 changed to " << v << endl; }); myWidget.Label1 <<= "Hello"; myWidget.Label2 <<= "world"; cout << "Resetting..." << endl; myWidget.Reset(); cout << endl; } } /////////////////////////////////////////////////////////////////////////////////////////////////// /// Run examples /////////////////////////////////////////////////////////////////////////////////////////////////// int main() { example1::Run(); example2::v1::Run(); example2::v2::Run(); example3::Run(); return 0; }