Skip to content

Commit dfa7cb8

Browse files
committed
Added support for signals of references.
1 parent 8055cd6 commit dfa7cb8

8 files changed

Lines changed: 84 additions & 31 deletions

File tree

include/react/ReactiveBase.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,4 +56,10 @@ bool Equals(const L& lhs, const R& rhs)
5656
return lhs == rhs;
5757
}
5858

59+
template <typename L, typename R>
60+
bool Equals(const std::reference_wrapper<L>& lhs, const std::reference_wrapper<R>& rhs)
61+
{
62+
return lhs.get() == rhs.get();
63+
}
64+
5965
REACT_IMPL_END

include/react/ReactiveDomain.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,12 @@ class RSignal;
2323
template <typename D, typename S>
2424
class RVarSignal;
2525

26+
template <typename D, typename S>
27+
using RRefSignal = RSignal<D,std::reference_wrapper<S>>;
28+
29+
template <typename D, typename S>
30+
using RVarRefSignal = RVarSignal<D,std::reference_wrapper<S>>;
31+
2632
template <typename D, typename E>
2733
class REvents;
2834

@@ -233,6 +239,12 @@ class DomainBase
233239
template <typename S>
234240
using VarSignal = RVarSignal<D,S>;
235241

242+
template <typename S>
243+
using RefSignal = RRefSignal<D,S>;
244+
245+
template <typename S>
246+
using VarRefSignal = RVarRefSignal<D,S>;
247+
236248
template <typename E = EventToken>
237249
using Events = REvents<D,E>;
238250

include/react/ReactiveObject.h

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,12 @@ class ReactiveObject
1919
template <typename S>
2020
using VarSignal = RVarSignal<D,S>;
2121

22+
template <typename S>
23+
using RefSignal = RRefSignal<D,S>;
24+
25+
template <typename S>
26+
using VarRefSignal = RVarRefSignal<D,S>;
27+
2228
template <typename E = EventToken>
2329
using Events = REvents<D,E>;
2430

@@ -87,12 +93,27 @@ class ReactiveObject
8793
}
8894

8995
////////////////////////////////////////////////////////////////////////////////////////
90-
/// DYNAMIC_REF
96+
/// Flatten macros
9197
////////////////////////////////////////////////////////////////////////////////////////
92-
#define DYNAMIC_REF(obj, name) \
93-
Flatten( \
94-
MakeSignal( \
95-
[] (Identity<decltype(obj)>::Type::ValueT r) { return r->name; }, obj))
98+
// Todo: Add safety wrapper + static assert to check for this for ReactiveObject
99+
#define REACTIVE_REF(obj, name) \
100+
Flatten( \
101+
MakeSignal( \
102+
[] (Identity<decltype(obj)>::Type::ValueT::type& r) \
103+
{ \
104+
return r.name; \
105+
}, \
106+
obj))
107+
108+
#define REACTIVE_PTR(obj, name) \
109+
Flatten( \
110+
MakeSignal( \
111+
[] (Identity<decltype(obj)>::Type::ValueT r) \
112+
{ \
113+
REACT_ASSERT(r != nullptr); \
114+
return r->name; \
115+
}, \
116+
obj))
96117
};
97118

98119
} //~namespace react

include/react/Signal.h

Lines changed: 20 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -85,20 +85,6 @@ class RSignal : public Reactive< REACT_IMPL::SignalNode<D,S>>
8585
}
8686
};
8787

88-
REACT_END
89-
90-
REACT_IMPL_BEGIN
91-
92-
template <typename D, typename L, typename R>
93-
bool Equals(const RSignal<D,L>& lhs, const RSignal<D,R>& rhs)
94-
{
95-
return lhs.Equals(rhs);
96-
}
97-
98-
REACT_IMPL_END
99-
100-
REACT_BEGIN
101-
10288
////////////////////////////////////////////////////////////////////////////////////////
10389
/// RVarSignal
10490
////////////////////////////////////////////////////////////////////////////////////////
@@ -142,6 +128,26 @@ class RVarSignal : public RSignal<D,S>
142128
}
143129
};
144130

131+
REACT_END
132+
133+
REACT_IMPL_BEGIN
134+
135+
template <typename D, typename L, typename R>
136+
bool Equals(const RSignal<D,L>& lhs, const RSignal<D,R>& rhs)
137+
{
138+
return lhs.Equals(rhs);
139+
}
140+
141+
template <typename D, typename L, typename R>
142+
bool Equals(const RVarSignal<D,L>& lhs, const RVarSignal<D,R>& rhs)
143+
{
144+
return lhs.Equals(rhs);
145+
}
146+
147+
REACT_IMPL_END
148+
149+
REACT_BEGIN
150+
145151
////////////////////////////////////////////////////////////////////////////////////////
146152
/// IsSignalT
147153
////////////////////////////////////////////////////////////////////////////////////////

include/react/graph/SignalNodes.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,8 @@ class VarNode : public SignalNode<D,S>
108108
public:
109109
template <typename T>
110110
VarNode(T&& value, bool registered) :
111-
SignalNode<D,S>(std::forward<T>(value), true)
111+
SignalNode<D,S>(std::forward<T>(value), true),
112+
newValue_{ value_ }
112113
{
113114
if (!registered)
114115
registerNode();
@@ -250,9 +251,9 @@ class FunctionNode : public SignalNode<D,S>
250251
}
251252

252253
static inline auto unpackValues(const SignalNodePtr<D,TArgs>& ... args)
253-
-> std::tuple<std::reference_wrapper<const TArgs> ...>
254+
-> decltype(std::tie(args->ValueRef() ...))
254255
{
255-
return std::make_tuple(std::cref(args->ValueRef()) ...);
256+
return std::tie(args->ValueRef() ...);
256257
}
257258
};
258259

src/benchmark/BenchmarkLifeSim.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,7 @@ class Animal : public ReactiveObject<D>
186186
});
187187
}
188188

189-
Events<int> FoodReceived = DYNAMIC_REF(CurrentRegion, FoodOutput);
189+
Events<int> FoodReceived = REACTIVE_PTR(CurrentRegion, FoodOutput);
190190

191191
Signal<int> Age = Iterate(0, theTime.NewDay, Incrementer<int>());
192192

src/sandbox/Main.cpp

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#include <iostream>
2+
#include <functional>
23

34
#include "react/Signal.h"
45
#include "react/EventStream.h"
@@ -162,6 +163,11 @@ class Person : public ReactiveObject<D>
162163
else cout << ":D" << endl;
163164
});
164165
}
166+
167+
bool operator==(const Person& other) const
168+
{
169+
return this == &other;
170+
}
165171
};
166172

167173
void ObjectExample1()
@@ -183,15 +189,14 @@ void ObjectExample1()
183189
class PersonManager : public ReactiveObject<D>
184190
{
185191
public:
186-
VarSignal<Person*> CurrentPerson;
192+
VarRefSignal<Person> CurrentPerson;
187193

188194
Observer healthObs;
189195

190196
PersonManager(Person& p) :
191-
CurrentPerson{ MakeVar(&p) }
197+
CurrentPerson{ MakeVar(std::ref(p)) }
192198
{
193-
// Todo: Safety, doesn't work for VarSignal etc.
194-
healthObs = DYNAMIC_REF(CurrentPerson, Health).Observe([] (int v) {
199+
healthObs = REACTIVE_REF(CurrentPerson, Health).Observe([] (int v) {
195200
cout << "Manager: Health changed to " << v << endl;
196201
});
197202
}
@@ -209,7 +214,7 @@ void ObjectExample2()
209214
person1.Age <<= 30;
210215
person2.Age <<= 15;
211216

212-
mgmt.CurrentPerson <<= &person2;
217+
mgmt.CurrentPerson <<= std::ref(person2);
213218

214219
person1.Age <<= 40;
215220
person2.Age <<= 25;

src/test/MoveTest.h

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -93,18 +93,20 @@ TYPED_TEST_P(MoveTest, Copy1)
9393
auto c = MyDomain::MakeVar(CopyCounter{100,&stats1});
9494
auto d = MyDomain::MakeVar(CopyCounter{1000,&stats1});
9595

96-
ASSERT_EQ(stats1.copyCount, 0);
96+
// 4x move to value_
97+
// 4x copy to newValue_ (can't be unitialized for references)
98+
ASSERT_EQ(stats1.copyCount, 4);
9799
ASSERT_EQ(stats1.moveCount, 4);
98100

99101
auto x = a + b + c + d;
100102

101-
ASSERT_EQ(stats1.copyCount, 0);
103+
ASSERT_EQ(stats1.copyCount, 4);
102104
ASSERT_EQ(stats1.moveCount, 7);
103105
ASSERT_EQ(x().v, 1111);
104106

105107
a <<= CopyCounter{2,&stats1};
106108

107-
ASSERT_EQ(stats1.copyCount, 0);
109+
ASSERT_EQ(stats1.copyCount, 4);
108110
ASSERT_EQ(stats1.moveCount, 12);
109111
ASSERT_EQ(x().v, 1112);
110112
}

0 commit comments

Comments
 (0)