1+
2+ // Copyright Sebastian Jeckel 2014.
3+ // Distributed under the Boost Software License, Version 1.0.
4+ // (See accompanying file LICENSE_1_0.txt or copy at
5+ // http://www.boost.org/LICENSE_1_0.txt)
6+
7+ #include < iostream>
8+ #include < string>
9+ #include < utility>
10+ #include < vector>
11+
12+ #include " react/Domain.h"
13+ #include " react/Signal.h"
14+ #include " react/Event.h"
15+ #include " react/Observer.h"
16+ #include " react/Algorithm.h"
17+
18+ // /////////////////////////////////////////////////////////////////////////////////////////////////
19+ // / Example 1 - Converting events to signals
20+ // /////////////////////////////////////////////////////////////////////////////////////////////////
21+ namespace example1
22+ {
23+ using namespace std ;
24+ using namespace react ;
25+
26+ REACTIVE_DOMAIN (D)
27+
28+ class Sensor
29+ {
30+ public:
31+ USING_REACTIVE_DOMAIN (D)
32+
33+ EventSourceT<int > Samples = MakeEventSource<D,int >();
34+ SignalT<int > LastSample = Hold(Samples, 0 );
35+ };
36+
37+ void Run ()
38+ {
39+ cout << " Example 1 - Converting events to signals" << endl;
40+
41+ Sensor mySensor;
42+
43+ Observe (mySensor.LastSample , [] (int v) {
44+ std::cout << v << std::endl;
45+ });
46+
47+ mySensor.Samples << 20 << 21 << 21 << 22 ; // output: 20, 21, 22
48+
49+ D::DoTransaction ([&] {
50+ mySensor.Samples << 30 << 31 << 31 << 32 ;
51+ }); // output: 32
52+
53+ cout << endl;
54+ }
55+ }
56+
57+ // /////////////////////////////////////////////////////////////////////////////////////////////////
58+ // / Example 2 - Converting signals to events
59+ // /////////////////////////////////////////////////////////////////////////////////////////////////
60+ namespace example2
61+ {
62+ using namespace std ;
63+ using namespace react ;
64+
65+ REACTIVE_DOMAIN (D)
66+
67+ class Employee
68+ {
69+ public:
70+ USING_REACTIVE_DOMAIN (D)
71+
72+ VarSignalT<string> Name = MakeVar<D>(string( " Bob" ));
73+ VarSignalT<int > Salary = MakeVar<D>(3000 );
74+
75+ EventsT<int > SalaryChanged = Monitor(Salary);
76+ };
77+
78+ void Run ()
79+ {
80+ cout << " Example 2 - Converting signals to events" << endl;
81+
82+ Employee bob;
83+
84+ Observe (
85+ bob.SalaryChanged ,
86+ With (bob.Name ),
87+ [] (int newSalary, const string& name) {
88+ cout << name << " now earns " << newSalary << endl;
89+ });
90+
91+ cout << endl;
92+ }
93+ }
94+
95+ // /////////////////////////////////////////////////////////////////////////////////////////////////
96+ // / Example 3 - Creating stateful signals (1)
97+ // /////////////////////////////////////////////////////////////////////////////////////////////////
98+ namespace example3
99+ {
100+ using namespace std ;
101+ using namespace react ;
102+
103+ REACTIVE_DOMAIN (D)
104+
105+ class Counter
106+ {
107+ public:
108+ USING_REACTIVE_DOMAIN (D)
109+
110+ EventSourceT<> Increment = MakeEventSource<D>();
111+
112+ SignalT<int > Count = Iterate(
113+ Increment,
114+ 0 ,
115+ [] (Token, int oldCount) {
116+ return oldCount + 1 ;
117+ });
118+ };
119+
120+ void Run ()
121+ {
122+ cout << " Example 3 - Creating stateful signals (1)" << endl;
123+
124+ Counter myCounter;
125+
126+ // Note: Using function-style operator() instead of .Emit() and .Value()
127+ myCounter.Increment ();
128+ myCounter.Increment ();
129+ myCounter.Increment ();
130+
131+ cout << myCounter.Count () << endl; // output: 3
132+
133+ cout << endl;
134+ }
135+ }
136+
137+ // /////////////////////////////////////////////////////////////////////////////////////////////////
138+ // / Example 4 - Creating stateful signals (2)
139+ // /////////////////////////////////////////////////////////////////////////////////////////////////
140+ namespace example4
141+ {
142+ using namespace std ;
143+ using namespace react ;
144+
145+ REACTIVE_DOMAIN (D)
146+
147+ class Sensor
148+ {
149+ public:
150+ USING_REACTIVE_DOMAIN (D)
151+
152+ EventSourceT<int > Input = MakeEventSource<D,int >();
153+
154+ SignalT<float > Average = Iterate(
155+ Input,
156+ 0 .0f ,
157+ [] (int sample, float oldAvg) {
158+ return (oldAvg + sample) / 2 .0f ;
159+ });
160+ };
161+
162+ void Run ()
163+ {
164+ cout << " Example 4 - Creating stateful signals (2)" << endl;
165+
166+ Sensor mySensor;
167+
168+ mySensor.Input << 10 << 5 << 10 << 8 ;
169+
170+ cout << " Average: " << mySensor.Average () << endl; // output: 3
171+
172+ cout << endl;
173+ }
174+ }
175+
176+ // /////////////////////////////////////////////////////////////////////////////////////////////////
177+ // / Example 5 - Creating stateful signals (3)
178+ // /////////////////////////////////////////////////////////////////////////////////////////////////
179+ namespace example5
180+ {
181+ using namespace std ;
182+ using namespace react ;
183+
184+ REACTIVE_DOMAIN (D)
185+
186+ enum class ECmd { increment, decrement, reset };
187+
188+ class Counter
189+ {
190+ public:
191+ USING_REACTIVE_DOMAIN (D)
192+
193+ EventSourceT<ECmd> Update = MakeEventSource<D,ECmd>();
194+ VarSignalT<int > Delta = MakeVar<D>(1 );
195+ VarSignalT<int > Start = MakeVar<D>(0 );
196+
197+ SignalT<int > Count = Iterate(
198+ Update,
199+ Start.Value(),
200+ With (Delta, Start),
201+ [] (ECmd cmd, int oldCount, int delta, int start) {
202+ if (cmd == ECmd::increment)
203+ return oldCount + delta;
204+ else if (cmd == ECmd::decrement)
205+ return oldCount - delta;
206+ else
207+ return start;
208+ });
209+ };
210+
211+ void Run ()
212+ {
213+ cout << " Example 5 - Creating stateful signals (3)" << endl;
214+
215+ Counter myCounter;
216+
217+ cout << " Start: " << myCounter.Count () << endl; // output: 0
218+
219+ myCounter.Update (ECmd::increment);
220+ myCounter.Update (ECmd::increment);
221+ myCounter.Update (ECmd::increment);
222+
223+ cout << " 3x increment by 1: " << myCounter.Count () << endl; // output: 3
224+
225+ myCounter.Delta <<= 5 ;
226+ myCounter.Update (ECmd::decrement);
227+
228+ cout << " 1x decrement by 5: " << myCounter.Count () << endl; // output: -2
229+
230+ myCounter.Start <<= 100 ;
231+ myCounter.Update (ECmd::reset);
232+
233+ cout << " reset to 100: " << myCounter.Count () << endl; // output: 100
234+
235+ cout << endl;
236+ }
237+ }
238+
239+ // /////////////////////////////////////////////////////////////////////////////////////////////////
240+ // / Example 6 - Avoiding expensive copies
241+ // /////////////////////////////////////////////////////////////////////////////////////////////////
242+ namespace example6
243+ {
244+ using namespace std ;
245+ using namespace react ;
246+
247+ REACTIVE_DOMAIN (D)
248+
249+ class Sensor
250+ {
251+ public:
252+ USING_REACTIVE_DOMAIN (D)
253+
254+ EventSourceT<int > Input = MakeEventSource<D,int >();
255+
256+ VarSignalT<int > Threshold = MakeVar<D>(42 );
257+
258+ SignalT<vector<int >> AllSamples = Iterate(
259+ Input,
260+ vector<int >{},
261+ [] (int input, vector<int >& all) {
262+ all.push_back (input);
263+ });
264+
265+ SignalT<vector<int >> CriticalSamples = Iterate(
266+ Input,
267+ vector<int >{},
268+ With (Threshold),
269+ [] (int input, vector<int >& critical, int threshold) {
270+ if (input > threshold)
271+ critical.push_back (input);
272+ });
273+ };
274+
275+ void Run ()
276+ {
277+ cout << " Example 6 - Avoiding expensive copies" << endl;
278+
279+ Sensor mySensor;
280+
281+ mySensor.Input << 40 << 29 << 43 << 50 ;
282+
283+ cout << " All samples: " ;
284+ for (auto const & v : mySensor.AllSamples ())
285+ cout << v << " " ;
286+ cout << endl;
287+
288+ cout << " Critical samples: " ;
289+ for (auto const & v : mySensor.CriticalSamples ())
290+ cout << v << " " ;
291+ cout << endl;
292+
293+ cout << endl;
294+ }
295+ }
296+
297+ // /////////////////////////////////////////////////////////////////////////////////////////////////
298+ // / Run examples
299+ // /////////////////////////////////////////////////////////////////////////////////////////////////
300+ int main ()
301+ {
302+ example1::Run ();
303+ example2::Run ();
304+ example3::Run ();
305+ example4::Run ();
306+ example5::Run ();
307+ example6::Run ();
308+
309+ return 0 ;
310+ }
0 commit comments