Skip to content

Commit 99d71a7

Browse files
committed
Adapted new notation for passing additional signal dependencies to observers. Instead of putting them behind the function, which is hard to read with lambdas, they are wrapped by a signal pack and put before the function.
The utility function With(x,y,z) can be used
1 parent 2025fc3 commit 99d71a7

4 files changed

Lines changed: 95 additions & 64 deletions

File tree

include/react/Event.h

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -91,10 +91,10 @@ class Events : public REACT_IMPL::EventStreamBase<D,E>
9191
return REACT::Transform(*this, std::forward<F>(f));
9292
}
9393

94-
template <typename F, typename ... TDeps>
95-
Observer<D> Observe(F&& f, const TDeps& ... deps) const
94+
template <typename F>
95+
Observer<D> Observe(F&& f) const
9696
{
97-
return REACT::Observe(*this, std::forward<F>(f), deps ...);
97+
return REACT::Observe(*this, std::forward<F>(f));
9898
}
9999
};
100100

@@ -164,10 +164,10 @@ class Events<D,E&> : public REACT_IMPL::EventStreamBase<D,std::reference_wrapper
164164
return REACT::Transform(*this, std::forward<F>(f));
165165
}
166166

167-
template <typename F, typename ... TDeps>
168-
Observer<D> Observe(F&& f, const TDeps& ... deps) const
167+
template <typename F>
168+
Observer<D> Observe(F&& f) const
169169
{
170-
return REACT::Observe(*this, std::forward<F>(f), deps ...);
170+
return REACT::Observe(*this, std::forward<F>(f));
171171
}
172172
};
173173

include/react/Observer.h

Lines changed: 54 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@
2323
template <typename D, typename S>
2424
class Signal;
2525

26+
template <typename D, typename ... TValues>
27+
class SignalPack;
28+
2629
template <typename D, typename E>
2730
class Events;
2831

@@ -153,6 +156,7 @@ auto Observe(const Events<D,E>& subject, FIn&& func)
153156
return Observer<D>(rawObsPtr, subject.NodePtr());
154157
}
155158

159+
// Token stream version
156160
template
157161
<
158162
typename D,
@@ -198,13 +202,12 @@ template
198202
typename D,
199203
typename FIn,
200204
typename E,
201-
typename TDepValue1,
202205
typename ... TDepValues,
203206
class = std::enable_if<
204207
! std::is_same<E,EventToken>::value>::type
205208
>
206-
auto Observe(const Events<D,E>& subject, FIn&& func,
207-
const Signal<D,TDepValue1>& dep1, const Signal<D,TDepValues>& ... deps)
209+
auto Observe(const Events<D,E>& subject,
210+
SignalPack<D,TDepValues...> depPack, FIn&& func)
208211
-> Observer<D>
209212
{
210213
using REACT_IMPL::IObserver;
@@ -213,25 +216,44 @@ auto Observe(const Events<D,E>& subject, FIn&& func,
213216

214217
using F = std::decay<FIn>::type;
215218

216-
std::unique_ptr<IObserver> obsPtr{
217-
new SyncedObserverNode<D,E,F,TDepValue1,TDepValues ...>{
218-
subject.NodePtr(), std::forward<FIn>(func), dep1.NodePtr(), deps.NodePtr() ...}};
219+
struct NodeBuilder_
220+
{
221+
NodeBuilder_(const Events<D,E>& subject, FIn&& func) :
222+
MySubject{ subject },
223+
MyFunc{ std::forward<FIn>(func) }
224+
{}
225+
226+
auto operator()(const Signal<D,TDepValues>& ... deps)
227+
-> std::unique_ptr<IObserver>
228+
{
229+
return std::unique_ptr<IObserver> {
230+
new SyncedObserverNode<D,E,F,TDepValues ...> {
231+
MySubject.NodePtr(), std::forward<FIn>(MyFunc), deps.NodePtr() ...}};
232+
}
233+
234+
const Events<D,E>& MySubject;
235+
FIn MyFunc;
236+
};
237+
238+
auto obsPtr = REACT_IMPL::apply(
239+
NodeBuilder_{ subject, std::forward<FIn>(func) },
240+
depPack.Data);
219241

220242
auto* rawObsPtr = DomainSpecificObserverRegistry<D>::Instance()
221243
.Register(std::move(obsPtr), subject.NodePtr().get());
222244

223245
return Observer<D>(rawObsPtr, subject.NodePtr());
224246
}
225247

248+
// Token stream version
226249
template
227250
<
228251
typename D,
229252
typename FIn,
230-
typename TDepValue1,
231253
typename ... TDepValues
232254
>
233-
auto Observe(const Events<D,EventToken>& subject, FIn&& func,
234-
const Signal<D,TDepValue1>& dep1, const Signal<D,TDepValues>& ... deps)
255+
auto Observe(const Events<D,EventToken>& subject,
256+
SignalPack<D,TDepValues...> depPack, FIn&& func)
235257
-> Observer<D>
236258
{
237259
using REACT_IMPL::IObserver;
@@ -246,19 +268,36 @@ auto Observe(const Events<D,EventToken>& subject, FIn&& func,
246268
Wrapper_(const Wrapper_& other) = default;
247269
Wrapper_(Wrapper_&& other) : MyFunc{ std::move(other.MyFunc) } {}
248270

249-
void operator()(EventToken, const TDepValue1& arg1, const TDepValues& ... args)
271+
void operator()(EventToken, const TDepValues& ... args)
250272
{
251-
MyFunc(arg1, args ...);
273+
MyFunc(args ...);
252274
}
253275

254276
F MyFunc;
255277
};
256278

257-
Wrapper_ wrapper{ std::forward<FIn>(func) };
279+
struct NodeBuilder_
280+
{
281+
NodeBuilder_(const Events<D,EventToken>& subject, Wrapper_&& wrapper) :
282+
MySubject{ subject },
283+
MyWrapper{ std::move(wrapper) }
284+
{}
258285

259-
std::unique_ptr<IObserver> obsPtr{
260-
new SyncedObserverNode<D,EventToken,Wrapper_,TDepValue1,TDepValues ...>{
261-
subject.NodePtr(), std::move(wrapper), dep1.NodePtr(), deps.NodePtr() ...}};
286+
auto operator()(const Signal<D,TDepValues>& ... deps)
287+
-> std::unique_ptr<IObserver>
288+
{
289+
return std::unique_ptr<IObserver> {
290+
new SyncedObserverNode<D,EventToken,Wrapper_,TDepValues ...> {
291+
MySubject.NodePtr(), std::move(MyWrapper), deps.NodePtr() ...}};
292+
}
293+
294+
const Events<D,EventToken>& MySubject;
295+
Wrapper_&& MyWrapper;
296+
};
297+
298+
auto obsPtr = REACT_IMPL::apply(
299+
NodeBuilder_{ subject, Wrapper_{ std::forward<FIn>(func) } },
300+
depPack.Data);
262301

263302
auto* rawObsPtr = DomainSpecificObserverRegistry<D>::Instance()
264303
.Register(std::move(obsPtr), subject.NodePtr().get());

include/react/Signal.h

Lines changed: 31 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -671,36 +671,42 @@ DECLARE_OP(||, LogicalOr);
671671
#undef DECLARE_OP
672672

673673
///////////////////////////////////////////////////////////////////////////////////////////////////
674-
/// SignalList - Wraps several nodes in a tuple. Create with comma operator.
674+
/// SignalPack - Wraps several nodes in a tuple. Create with comma operator.
675675
///////////////////////////////////////////////////////////////////////////////////////////////////
676676
template
677677
<
678678
typename D,
679679
typename ... TValues
680680
>
681-
class SignalList
681+
class SignalPack
682682
{
683683
public:
684-
SignalList(const Signal<D,TValues>& ... deps) :
685-
data_{ std::tie(deps ...) }
684+
SignalPack(const Signal<D,TValues>& ... deps) :
685+
Data{ std::tie(deps ...) }
686686
{}
687687

688688
template <typename ... TCurValues, typename TAppendValue>
689-
SignalList(const SignalList<D, TCurValues ...>& curArgs, const Signal<D,TAppendValue>& newArg) :
690-
data_{ std::tuple_cat(curArgs.data_, std::tie(newArg)) }
689+
SignalPack(const SignalPack<D, TCurValues ...>& curArgs, const Signal<D,TAppendValue>& newArg) :
690+
Data{ std::tuple_cat(curArgs.Data, std::tie(newArg)) }
691691
{}
692692

693-
private:
694-
std::tuple<const Signal<D, TValues>& ...> data_;
695-
696-
template <typename D, typename ... TValues>
697-
friend class SignalList;
698-
699-
template <typename D, typename F, typename ... TSignals>
700-
friend auto operator->*(const SignalList<D,TSignals ...>&, F&&)
701-
-> Signal<D, typename std::result_of<F(TSignals ...)>::type>;
693+
std::tuple<const Signal<D,TValues>& ...> Data;
702694
};
703695

696+
///////////////////////////////////////////////////////////////////////////////////////////////////
697+
/// With - Utility function to create a SignalPack
698+
///////////////////////////////////////////////////////////////////////////////////////////////////
699+
template
700+
<
701+
typename D,
702+
typename ... TValues
703+
>
704+
auto With(const Signal<D,TValues>& ... deps)
705+
-> SignalPack<D,TValues ...>
706+
{
707+
return SignalPack<D,TValues...>(deps ...);
708+
}
709+
704710
///////////////////////////////////////////////////////////////////////////////////////////////////
705711
/// Comma operator overload to create input pack from 2 signals.
706712
///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -711,9 +717,9 @@ template
711717
typename TRightVal
712718
>
713719
auto operator,(const Signal<D,TLeftVal>& a, const Signal<D,TRightVal>& b)
714-
-> SignalList<D,TLeftVal, TRightVal>
720+
-> SignalPack<D,TLeftVal, TRightVal>
715721
{
716-
return SignalList<D, TLeftVal, TRightVal>(a, b);
722+
return SignalPack<D, TLeftVal, TRightVal>(a, b);
717723
}
718724

719725
///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -725,10 +731,10 @@ template
725731
typename ... TCurValues,
726732
typename TAppendValue
727733
>
728-
auto operator,(const SignalList<D, TCurValues ...>& cur, const Signal<D,TAppendValue>& append)
729-
-> SignalList<D,TCurValues ... , TAppendValue>
734+
auto operator,(const SignalPack<D, TCurValues ...>& cur, const Signal<D,TAppendValue>& append)
735+
-> SignalPack<D,TCurValues ... , TAppendValue>
730736
{
731-
return SignalList<D, TCurValues ... , TAppendValue>(cur, append);
737+
return SignalPack<D, TCurValues ... , TAppendValue>(cur, append);
732738
}
733739

734740
/******************************************/ REACT_END /******************************************/
@@ -778,14 +784,14 @@ template
778784
<
779785
typename D,
780786
typename F,
781-
typename ... TSignals
787+
typename ... TValues
782788
>
783-
auto operator->*(const SignalList<D,TSignals ...>& inputPack, F&& func)
784-
-> Signal<D, typename std::result_of<F(TSignals ...)>::type>
789+
auto operator->*(const SignalPack<D,TValues ...>& inputPack, F&& func)
790+
-> Signal<D, typename std::result_of<F(TValues ...)>::type>
785791
{
786792
return apply(
787-
REACT_IMPL::ApplyHelper<D,F,TSignals ...>::MakeSignal,
788-
std::tuple_cat(std::forward_as_tuple(std::forward<F>(func)), inputPack.data_));
793+
REACT_IMPL::ApplyHelper<D,F,TValues ...>::MakeSignal,
794+
std::tuple_cat(std::forward_as_tuple(std::forward<F>(func)), inputPack.Data));
789795
}
790796

791797
///////////////////////////////////////////////////////////////////////////////////////////////////

src/test/ObserverTest.h

Lines changed: 4 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -144,38 +144,24 @@ TYPED_TEST_P(ObserverTest, SyncedObserveTest)
144144
auto src1 = MyDomain::MakeEventSource();
145145
auto src2 = MyDomain::MakeEventSource<int>();
146146

147-
Observe(src1, [] (int sum, int prod, int diff) {
147+
Observe(src1, With(sum,prod,diff), [] (int sum, int prod, int diff) {
148148
ASSERT_EQ(sum, 33);
149149
ASSERT_EQ(prod, 242);
150150
ASSERT_EQ(diff, 11);
151-
}, sum,prod,diff);
152-
153-
Observe(src2, [] (int e, int sum, int prod, int diff) {
154-
ASSERT_EQ(e, 42);
155-
ASSERT_EQ(sum, 33);
156-
ASSERT_EQ(prod, 242);
157-
ASSERT_EQ(diff, 11);
158-
}, sum,prod,diff);
159-
160-
src1.Observe([] (int sum, int prod, int diff) {
161-
ASSERT_EQ(sum, 33);
162-
ASSERT_EQ(prod, 242);
163-
ASSERT_EQ(diff, 11);
164-
}, sum,prod,diff);
151+
});
165152

166-
src2.Observe([] (int e, int sum, int prod, int diff) {
153+
Observe(src2, With(sum,prod,diff), [] (int e, int sum, int prod, int diff) {
167154
ASSERT_EQ(e, 42);
168155
ASSERT_EQ(sum, 33);
169156
ASSERT_EQ(prod, 242);
170157
ASSERT_EQ(diff, 11);
171-
}, sum,prod,diff);
158+
});
172159

173160
in1 <<= 22;
174161
in2 <<= 11;
175162

176163
src1.Emit();
177164
src2.Emit(42);
178-
179165
}
180166

181167
///////////////////////////////////////////////////////////////////////////////////////////////////

0 commit comments

Comments
 (0)