Skip to content

Commit 694dc88

Browse files
committed
Implemented rvalue-based node merging for event streams.
1 parent 68870d7 commit 694dc88

5 files changed

Lines changed: 729 additions & 258 deletions

File tree

include/react/EventStream.h

Lines changed: 200 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
#include <thread>
1212
#include <type_traits>
13+
#include <utility>
1314
#include <vector>
1415

1516
#include "ReactiveBase.h"
@@ -123,6 +124,39 @@ class EventSource : public Events<D,E>
123124
}
124125
};
125126

127+
///////////////////////////////////////////////////////////////////////////////////////////////////
128+
/// TempEvents
129+
///////////////////////////////////////////////////////////////////////////////////////////////////
130+
template
131+
<
132+
typename D,
133+
typename E,
134+
typename TOp
135+
>
136+
class TempEvents : public Events<D,E>
137+
{
138+
protected:
139+
using NodeT = REACT_IMPL::EventOpNode<D,E,TOp>;
140+
141+
public:
142+
TempEvents() :
143+
Events()
144+
{}
145+
146+
explicit TempEvents(const std::shared_ptr<NodeT>& ptr) :
147+
Events(ptr)
148+
{}
149+
150+
explicit TempEvents(std::shared_ptr<NodeT>&& ptr) :
151+
Events(std::move(ptr))
152+
{}
153+
154+
TOp StealOp()
155+
{
156+
return std::move(std::static_pointer_cast<NodeT>(ptr_)->StealOp());
157+
}
158+
};
159+
126160
///////////////////////////////////////////////////////////////////////////////////////////////////
127161
/// MakeEventSource
128162
///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -149,32 +183,107 @@ template
149183
<
150184
typename D,
151185
typename TArg1,
152-
typename ... TArgs
186+
typename ... TArgs,
187+
typename E = TArg1,
188+
typename TOp = REACT_IMPL::EventMergeOp<E,
189+
REACT_IMPL::EventStreamNodePtr<D,TArg1>,
190+
REACT_IMPL::EventStreamNodePtr<D,TArgs> ...>
153191
>
154-
inline auto Merge(const Events<D,TArg1>& arg1,
155-
const Events<D,TArgs>& ... args)
156-
-> Events<D,TArg1>
192+
auto Merge(const Events<D,TArg1>& arg1, const Events<D,TArgs>& ... args)
193+
-> TempEvents<D,E,TOp>
157194
{
158195
static_assert(sizeof...(TArgs) > 0,
159196
"react::Merge requires at least 2 arguments.");
160197

161-
typedef TArg1 E;
162-
return Events<D,E>(
163-
std::make_shared<REACT_IMPL::EventMergeNode<D, E, TArg1, TArgs ...>>(
198+
return TempEvents<D,E,TOp>(
199+
std::make_shared<REACT_IMPL::EventOpNode<D,E,TOp>>(
164200
arg1.GetPtr(), args.GetPtr() ...));
165201
}
166202

203+
template
204+
<
205+
typename TLeftEvents,
206+
typename TRightEvents,
207+
typename D = TLeftEvents::DomainT,
208+
typename TLeftVal = TLeftEvents::ValueT,
209+
typename TRightVal = TRightEvents::ValueT,
210+
typename E = TLeftVal,
211+
typename TOp = REACT_IMPL::EventMergeOp<E,
212+
REACT_IMPL::EventStreamNodePtr<D,TLeftVal>,
213+
REACT_IMPL::EventStreamNodePtr<D,TRightVal>>,
214+
class = std::enable_if<
215+
IsEvent<TLeftEvents>::value>::type,
216+
class = std::enable_if<
217+
IsEvent<TRightEvents>::value>::type
218+
>
219+
auto operator|(const TLeftEvents& lhs, const TRightEvents& rhs)
220+
-> TempEvents<D,E,TOp>
221+
{
222+
return TempEvents<D,E,TOp>(
223+
std::make_shared<REACT_IMPL::EventOpNode<D,E,TOp>>(
224+
lhs.GetPtr(), rhs.GetPtr()));
225+
}
226+
167227
template
168228
<
169229
typename D,
170-
typename TLeftArg,
171-
typename TRightArg
230+
typename TLeftVal,
231+
typename TLeftOp,
232+
typename TRightVal,
233+
typename TRightOp,
234+
typename E = TLeftVal,
235+
typename TOp = REACT_IMPL::EventMergeOp<E,TLeftOp,TRightOp>
172236
>
173-
inline auto operator|(const Events<D,TLeftArg>& lhs,
174-
const Events<D,TRightArg>& rhs)
175-
-> Events<D, TLeftArg>
237+
auto operator|(TempEvents<D,TLeftVal,TLeftOp>&& lhs, TempEvents<D,TRightVal,TRightOp>&& rhs)
238+
-> TempEvents<D,E,TOp>
176239
{
177-
return Merge(lhs,rhs);
240+
return TempEvents<D,E,TOp>(
241+
std::make_shared<REACT_IMPL::EventOpNode<D,E,TOp>>(
242+
lhs.StealOp(), rhs.StealOp()));
243+
}
244+
245+
template
246+
<
247+
typename D,
248+
typename TLeftVal,
249+
typename TLeftOp,
250+
typename TRightEvents,
251+
typename TRightVal = TRightEvents::ValueT,
252+
typename E = TLeftVal,
253+
typename TOp = REACT_IMPL::EventMergeOp<E,
254+
TLeftOp,
255+
REACT_IMPL::EventStreamNodePtr<D,TRightVal>>,
256+
class = std::enable_if<
257+
IsEvent<TRightEvents>::value>::type
258+
>
259+
auto operator|(TempEvents<D,TLeftVal,TLeftOp>&& lhs, const TRightEvents& rhs)
260+
-> TempEvents<D,E,TOp>
261+
{
262+
return TempEvents<D,E,TOp>(
263+
std::make_shared<REACT_IMPL::EventOpNode<D,E,TOp>>(
264+
lhs.StealOp(), rhs.GetPtr()));
265+
}
266+
267+
template
268+
<
269+
typename TLeftEvents,
270+
typename D,
271+
typename TRightVal,
272+
typename TRightOp,
273+
typename TLeftVal = TLeftEvents::ValueT,
274+
typename E = TLeftVal,
275+
typename TOp = REACT_IMPL::EventMergeOp<E,
276+
REACT_IMPL::EventStreamNodePtr<D,TRightVal>,
277+
TRightOp>,
278+
class = std::enable_if<
279+
IsEvent<TLeftEvents>::value>::type
280+
>
281+
auto operator|(const TLeftEvents& lhs, TempEvents<D,TRightVal,TRightOp>&& rhs)
282+
-> TempEvents<D,E,TOp>
283+
{
284+
return TempEvents<D,E,TOp>(
285+
std::make_shared<REACT_IMPL::EventOpNode<D,E,TOp>>(
286+
lhs.GetPtr(), rhs.StealOp()));
178287
}
179288

180289
///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -184,14 +293,47 @@ template
184293
<
185294
typename D,
186295
typename E,
187-
typename F
296+
typename FIn,
297+
typename F = std::decay<FIn>::type,
298+
typename TOp = REACT_IMPL::EventFilterOp<E,F,
299+
REACT_IMPL::EventStreamNodePtr<D,E>>
188300
>
189-
inline auto Filter(const Events<D,E>& src, F&& filter)
190-
-> Events<D,E>
301+
auto Filter(const Events<D,E>& src, FIn&& filter)
302+
-> TempEvents<D,E,TOp>
191303
{
192-
return Events<D,E>(
193-
std::make_shared<REACT_IMPL::EventFilterNode<D,E,F>>(
194-
src.GetPtr(), std::forward<F>(filter)));
304+
return TempEvents<D,E,TOp>(
305+
std::make_shared<REACT_IMPL::EventOpNode<D,E,TOp>>(
306+
std::forward<FIn>(filter), src.GetPtr()));
307+
}
308+
309+
template
310+
<
311+
typename D,
312+
typename E,
313+
typename TOpIn,
314+
typename FIn,
315+
typename F = std::decay<FIn>::type,
316+
typename TOpOut = REACT_IMPL::EventFilterOp<E,F,TOpIn>
317+
>
318+
auto Filter(TempEvents<D,E,TOpIn>&& src, FIn&& filter)
319+
-> TempEvents<D,E,TOpOut>
320+
{
321+
return TempEvents<D,E,TOpOut>(
322+
std::make_shared<REACT_IMPL::EventOpNode<D,E,TOpOut>>(
323+
std::forward<FIn>(filter), src.StealOp()));
324+
}
325+
326+
template
327+
<
328+
typename TEvents,
329+
typename F,
330+
class = std::enable_if<
331+
IsEvent<TEvents>::value>::type
332+
>
333+
auto operator&(TEvents&& src, F&& filter)
334+
-> decltype(Filter(std::forward<TEvents>(src), std::forward<F>(filter)))
335+
{
336+
return Filter(std::forward<TEvents>(src), std::forward<F>(filter));
195337
}
196338

197339
///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -200,17 +342,48 @@ inline auto Filter(const Events<D,E>& src, F&& filter)
200342
template
201343
<
202344
typename D,
203-
typename TIn,
204-
typename F
345+
typename E,
346+
typename FIn,
347+
typename F = std::decay<FIn>::type,
348+
typename TOp = REACT_IMPL::EventTransformOp<E,F,
349+
REACT_IMPL::EventStreamNodePtr<D,E>>
350+
>
351+
auto Transform(const Events<D,E>& src, FIn&& func)
352+
-> TempEvents<D,E,TOp>
353+
{
354+
return TempEvents<D,E,TOp>(
355+
std::make_shared<REACT_IMPL::EventOpNode<D,E,TOp>>(
356+
std::forward<FIn>(func), src.GetPtr()));
357+
}
358+
359+
template
360+
<
361+
typename D,
362+
typename E,
363+
typename TOpIn,
364+
typename FIn,
365+
typename F = std::decay<FIn>::type,
366+
typename TOpOut = REACT_IMPL::EventTransformOp<E,F,TOpIn>
205367
>
206-
inline auto Transform(const Events<D,TIn>& src, F&& func)
207-
-> Events<D, typename std::result_of<F(TIn)>::type>
368+
auto Transform(TempEvents<D,E,TOpIn>&& src, FIn&& func)
369+
-> TempEvents<D,E,TOpOut>
208370
{
209-
using TOut = typename std::result_of<F(TIn)>::type;
371+
return TempEvents<D,E,TOpOut>(
372+
std::make_shared<REACT_IMPL::EventOpNode<D,E,TOpOut>>(
373+
std::forward<FIn>(func), src.StealOp()));
374+
}
210375

211-
return Events<D,TOut>(
212-
std::make_shared<REACT_IMPL::EventTransformNode<D,TIn,TOut,F>>(
213-
src.GetPtr(), std::forward<F>(func)));
376+
template
377+
<
378+
typename TEvents,
379+
typename F,
380+
class = std::enable_if<
381+
IsEvent<TEvents>::value>::type
382+
>
383+
auto operator->*(TEvents&& src, F&& func)
384+
-> decltype(Transform(std::forward<TEvents>(src), std::forward<F>(func)))
385+
{
386+
return Transform(std::forward<TEvents>(src), std::forward<F>(func));
214387
}
215388

216389
/******************************************/ REACT_END /******************************************/

include/react/Traits.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,9 @@ class Events;
3131
template <typename D, typename E>
3232
class EventSource;
3333

34+
template <typename D, typename E, typename TOp>
35+
class TempEvents;
36+
3437
enum class EventToken;
3538

3639
template
@@ -71,6 +74,9 @@ struct IsEvent<Events<D,T>> { static const bool value = true; };
7174
template <typename D, typename T>
7275
struct IsEvent<EventSource<D,T>> { static const bool value = true; };
7376

77+
template <typename D, typename T, typename TOp>
78+
struct IsEvent<TempEvents<D,T,TOp>> { static const bool value = true; };
79+
7480
///////////////////////////////////////////////////////////////////////////////////////////////////
7581
/// IsReactive
7682
///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -92,6 +98,9 @@ struct IsReactive<Events<D,T>> { static const bool value = true; };
9298
template <typename D, typename T>
9399
struct IsReactive<EventSource<D,T>> { static const bool value = true; };
94100

101+
template <typename D, typename T, typename TOp>
102+
struct IsReactive<TempEvents<D,T,TOp>> { static const bool value = true; };
103+
95104
///////////////////////////////////////////////////////////////////////////////////////////////////
96105
/// RemoveInput
97106
///////////////////////////////////////////////////////////////////////////////////////////////////

0 commit comments

Comments
 (0)