Skip to content

Commit 8055cd6

Browse files
committed
Eliminated unnecessary copying for Signals.
Added proof-of-concept for RValue-based node merging.
1 parent 8d63bcf commit 8055cd6

8 files changed

Lines changed: 262 additions & 61 deletions

File tree

‎include/react/ReactiveBase.h‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ REACT_END
5151
REACT_IMPL_BEGIN
5252

5353
template <typename L, typename R>
54-
bool Equals(L lhs, R rhs)
54+
bool Equals(const L& lhs, const R& rhs)
5555
{
5656
return lhs == rhs;
5757
}

‎include/react/Signal.h‎

Lines changed: 74 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -68,12 +68,12 @@ class RSignal : public Reactive< REACT_IMPL::SignalNode<D,S>>
6868
{
6969
}
7070

71-
const S Value() const
71+
const S& Value() const
7272
{
73-
return (*ptr_)();
73+
return ptr_->ValueRef();
7474
}
7575

76-
S operator()(void) const
76+
const S& operator()(void) const
7777
{
7878
return Value();
7979
}
@@ -239,13 +239,16 @@ inline auto MakeSignal(TFunc func, const RSignal<D,TArgs>& ... args)
239239
template \
240240
< \
241241
typename D, \
242-
typename TVal \
242+
template <typename D_, typename V_> class TSignal, \
243+
typename TVal, \
244+
class = std::enable_if< \
245+
IsSignalT<D,TSignal<D,TVal>>::value>::type \
243246
> \
244-
inline auto operator ## op(const RSignal<D,TVal>& arg) \
247+
inline auto operator ## op(const TSignal<D,TVal>& arg) \
245248
-> RSignal<D,TVal> \
246249
{ \
247250
return RSignal<D,TVal>( \
248-
std::make_shared<REACT_IMPL::FunctionNode<D,TVal,TVal>>( \
251+
std::make_shared<REACT_IMPL::FunctionNode<D,TVal,TVal>>( \
249252
arg.GetPtr(), [] (TVal a) { return op a; }, false)); \
250253
}
251254

@@ -261,66 +264,63 @@ DECLARE_OP(-);
261264
template \
262265
< \
263266
typename D, \
264-
template <typename D_, typename V_> class TLeftHandle, \
265-
template <typename D_, typename V_> class TRightHandle, \
267+
template <typename D_, typename V_> class TLeftSignal, \
268+
template <typename D_, typename V_> class TRightSignal, \
266269
typename TLeftVal, \
267270
typename TRightVal, \
268-
class = std::enable_if<std::is_base_of< \
269-
RSignal<D,TLeftVal>, \
270-
TLeftHandle<D,TLeftVal>>::value>::type, \
271-
class = std::enable_if<std::is_base_of< \
272-
RSignal<D,TRightVal>, \
273-
TRightHandle<D,TLeftVal>>::value>::type \
271+
class = std::enable_if< \
272+
IsSignalT<D,TLeftSignal<D,TLeftVal>>::value>::type, \
273+
class = std::enable_if< \
274+
IsSignalT<D,TRightSignal<D,TRightVal>>::value>::type \
274275
> \
275-
inline auto operator ## op(const TLeftHandle<D,TLeftVal>& lhs, \
276-
const TRightHandle<D,TRightVal>& rhs) \
276+
inline auto operator ## op(const TLeftSignal<D,TLeftVal>& lhs, \
277+
const TRightSignal<D,TRightVal>& rhs) \
277278
-> RSignal<D,TLeftVal> \
278279
{ \
279280
return RSignal<D,TLeftVal>( \
280281
std::make_shared<REACT_IMPL::FunctionNode<D,TLeftVal,TLeftVal,TRightVal>>( \
281-
lhs.GetPtr(), rhs.GetPtr(), [] (TLeftVal a, TRightVal b) { return a op b; }, false)); \
282+
lhs.GetPtr(), rhs.GetPtr(), [] (const TLeftVal& a, const TRightVal& b) { \
283+
return a op b; }, false)); \
282284
} \
283285
\
284286
template \
285287
< \
286288
typename D, \
287-
template <typename D_, typename V_> class TLeftHandle, \
289+
template <typename D_, typename V_> class TLeftSignal, \
288290
typename TLeftVal, \
289291
typename TRightVal, \
290-
class = std::enable_if<std::is_base_of< \
291-
RSignal<D,TLeftVal>, \
292-
TLeftHandle<D,TLeftVal>>::value>::type, \
292+
class = std::enable_if< \
293+
IsSignalT<D,TLeftSignal<D,TLeftVal>>::value>::type, \
293294
class = std::enable_if< \
294295
std::is_integral<TRightVal>::value>::type \
295296
> \
296-
inline auto operator ## op(const TLeftHandle<D,TLeftVal>& lhs, \
297+
inline auto operator ## op(const TLeftSignal<D,TLeftVal>& lhs, \
297298
const TRightVal& rhs) \
298299
-> RSignal<D,TLeftVal> \
299300
{ \
300301
return RSignal<D,TLeftVal>( \
301-
std::make_shared<REACT_IMPL::FunctionNode<D,TLeftVal,TLeftVal>>( \
302-
lhs.GetPtr(), [=] (TLeftVal a) { return a op rhs; }, false)); \
302+
std::make_shared<REACT_IMPL::FunctionNode<D,TLeftVal,TLeftVal>>( \
303+
lhs.GetPtr(), [=] (const TLeftVal& a) { return a op rhs; }, false)); \
303304
} \
304305
\
305306
template \
306307
< \
307308
typename D, \
308-
template <typename D_, typename V_> class TRightHandle, \
309309
typename TLeftVal, \
310+
template <typename D_, typename V_> class TRightSignal, \
310311
typename TRightVal, \
311-
class = std::enable_if<std::is_base_of< \
312-
RSignal<D,TRightVal>, \
313-
TRightHandle<D,TRightVal>>::value>::type, \
314312
class = std::enable_if< \
315-
std::is_integral<TLeftVal>::value>::type \
313+
std::is_integral<TLeftVal>::value>::type, \
314+
class = std::enable_if< \
315+
IsSignalT<D,TRightSignal<D,TRightVal>>::value>::type \
316316
> \
317317
inline auto operator ## op(const TLeftVal& lhs, \
318-
const TRightHandle<D,TRightVal>& rhs) \
318+
const TRightSignal<D,TRightVal>& rhs) \
319319
-> RSignal<D,TRightVal> \
320320
{ \
321321
return RSignal<D,TRightVal>( \
322-
std::make_shared<REACT_IMPL::FunctionNode<D,TRightVal,TRightVal>>( \
323-
rhs.GetPtr(), [=] (TRightVal a) { return lhs op a; }, false)); \
322+
std::make_shared<REACT_IMPL::FunctionNode<D,TRightVal,TRightVal>>( \
323+
rhs.GetPtr(), [=] (const TRightVal& a) { return lhs op a; }, false)); \
324324
}
325325

326326
DECLARE_OP(+);
@@ -331,36 +331,69 @@ DECLARE_OP(%);
331331

332332
#undef DECLARE_OP
333333

334+
//template
335+
//<
336+
// typename D,
337+
// template <typename D_, typename V_> class TLeftSignal,
338+
// template <typename D_, typename V_> class TRightSignal,
339+
// typename TLeftVal,
340+
// typename TRightVal,
341+
// class = std::enable_if<
342+
// IsSignalT<D,TLeftSignal<D,TLeftVal>>::value>::type,
343+
// class = std::enable_if<
344+
// IsSignalT<D,TRightSignal<D,TRightVal>>::value>::type
345+
//>
346+
//auto operator+(TLeftSignal<D,TLeftVal>&& lhs,
347+
// const TRightSignal<D,TRightVal>& rhs)
348+
// -> RSignal<D,TLeftVal>
349+
//{
350+
// lhs.GetPtr()->MergeOp(
351+
// rhs.GetPtr(), [] (const TLeftVal& a, const TRightVal& b) { return a + b; });
352+
// return std::move(lhs);
353+
//}
354+
355+
334356
////////////////////////////////////////////////////////////////////////////////////////
335357
/// Comparison operators
336358
////////////////////////////////////////////////////////////////////////////////////////
337359
#define DECLARE_OP(op) \
338360
template \
339361
< \
340362
typename D, \
363+
template <typename D_, typename V_> class TLeftSignal, \
364+
template <typename D_, typename V_> class TRightSignal, \
341365
typename TLeftVal, \
342-
typename TRightVal \
366+
typename TRightVal, \
367+
class = std::enable_if< \
368+
IsSignalT<D,TLeftSignal<D,TLeftVal>>::value>::type, \
369+
class = std::enable_if< \
370+
IsSignalT<D,TRightSignal<D,TRightVal>>::value>::type \
343371
> \
344-
inline auto operator ## op(const RSignal<D,TLeftVal>& lhs, \
345-
const RSignal<D,TRightVal>& rhs) \
372+
inline auto operator ## op(const TLeftSignal<D,TLeftVal>& lhs, \
373+
const TRightSignal<D,TRightVal>& rhs) \
346374
-> RSignal<D,bool> \
347375
{ \
348376
return RSignal<D,bool>( \
349-
std::make_shared<REACT_IMPL::FunctionNode<D,bool,TLeftVal,TRightVal>>( \
377+
std::make_shared<REACT_IMPL::FunctionNode<D,bool,TLeftVal,TRightVal>>( \
350378
lhs.GetPtr(), rhs.GetPtr(), [] (TLeftVal a, TRightVal b) { return a op b; }, false)); \
351379
} \
352380
\
353381
template \
354382
< \
355383
typename D, \
384+
template <typename D_, typename V_> class TLeftSignal, \
356385
typename TLeftVal, \
357-
typename TRightVal \
386+
typename TRightVal, \
387+
class = std::enable_if< \
388+
IsSignalT<D,TLeftSignal<D,TLeftVal>>::value>::type, \
389+
class = std::enable_if< \
390+
std::is_integral<TRightVal>::value>::type \
358391
> \
359-
inline auto operator ## op(const RSignal<D,TLeftVal>& lhs, const TRightVal& rhs) \
392+
inline auto operator ## op(const TLeftSignal<D,TLeftVal>& lhs, const TRightVal& rhs) \
360393
-> RSignal<D,bool> \
361394
{ \
362395
return RSignal<D,bool>( \
363-
std::make_shared<REACT_IMPL::FunctionNode<D,bool,TLeftVal>>( \
396+
std::make_shared<REACT_IMPL::FunctionNode<D,bool,TLeftVal>>( \
364397
lhs.GetPtr(), [=] (TLeftVal a) { return a op rhs; }, false)); \
365398
}
366399

@@ -386,7 +419,7 @@ inline auto operator ## op(const RSignal<D,TVal>& arg) \
386419
-> RSignal<D,bool> \
387420
{ \
388421
return RSignal<D,TVal>( \
389-
std::make_shared<REACT_IMPL::FunctionNode<D,bool,TVal>>( \
422+
std::make_shared<REACT_IMPL::FunctionNode<D,bool,TVal>>( \
390423
arg.GetPtr(), [] (TVal a) { return op a; }, false)); \
391424
}
392425

@@ -423,7 +456,7 @@ inline auto operator ## op(const RSignal<D,TLeftVal>& lhs, const TRightVal& rhs)
423456
-> RSignal<D,bool> \
424457
{ \
425458
return RSignal<D,bool>( \
426-
std::make_shared<REACT_IMPL::FunctionNode<D,bool,TLeftVal>>( \
459+
std::make_shared<REACT_IMPL::FunctionNode<D,bool,TLeftVal>>( \
427460
lhs.GetPtr(), [=] (TLeftVal a) { return a op rhs; }, false)); \
428461
}
429462

‎include/react/graph/ConversionNodes.h‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -219,7 +219,7 @@ class SnapshotNode : public SignalNode<D,S>
219219
{
220220
public:
221221
SnapshotNode(const SignalNodePtr<D,S>& target, const EventStreamNodePtr<D,E>& trigger, bool registered) :
222-
SignalNode<D, S>(target->Value(), true),
222+
SignalNode<D, S>(target->ValueRef(), true),
223223
target_{ target },
224224
trigger_{ trigger }
225225
{
@@ -246,9 +246,9 @@ class SnapshotNode : public SignalNode<D,S>
246246
trigger_->SetCurrentTurn(turn);
247247

248248
D::Log().template Append<NodeEvaluateBeginEvent>(GetObjectId(*this), turn.Id(), std::this_thread::get_id().hash());
249-
S newValue = value_;
249+
S newValue = std::move(value_);
250250
if (! trigger_->Events().empty())
251-
newValue = target_->Value();
251+
newValue = target_->ValueRef();
252252
D::Log().template Append<NodeEvaluateEndEvent>(GetObjectId(*this), turn.Id(), std::this_thread::get_id().hash());
253253

254254
if (newValue != value_)
@@ -434,7 +434,7 @@ class EventFlattenNode : public EventStreamNode<D, TInner>
434434
SetCurrentTurn(turn, true);
435435
inner_->SetCurrentTurn(turn);
436436

437-
auto newInner = outer_->Value().GetPtr();
437+
auto newInner = outer_->ValueRef().GetPtr();
438438

439439
if (newInner != inner_)
440440
{

0 commit comments

Comments
 (0)