Inexor
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
SharedVar.hpp
Go to the documentation of this file.
1 #pragma once
2 
3 #include <algorithm>
4 
5 #include <boost/signals2.hpp>
6 
8 namespace inexor {
9 namespace rpc {
10 
54 template<typename T>
55 class SharedVar {
56 private:
57  typedef SharedVar<T> TMe;
58 
59  template<typename... A>
60  using signal = boost::signals2::signal<A...>;
61 
62  T value;
63 public:
64 
72 
73  // Access
74 
75  T& operator *() { return value; }
76  const T& operator *() const { return value; }
77  T* operator ->() { return &value; }
78 
79  // Note: Let's see whether this causes too much problems
80  operator T&() { return value; }
81 
82  // Proxies
83 
84 // explicit SharedVar() : value() {}
85 
86  template<typename... Args>
87  explicit SharedVar(Args&&... args, SharedOption)
88  : value(std::forward<Args>(args)...) {}
89 
90  explicit SharedVar(const SharedVar<T> &otr) : value(otr.value) { onChange.connect(otr.onChange); }
91  //explicit SharedVar(T otr) : value(otr) {}
92  explicit SharedVar(T &otr) : value(otr) {}
93  explicit SharedVar(T &&otr) : value(otr) {}
94  //explicit SharedVar(T otr, SharedOption) : value(otr) {}
95  explicit SharedVar(T &otr, SharedOption) : value(otr) {}
96  explicit SharedVar(T &&otr, SharedOption) : value(otr) {}
97 
98  // Avoid ambiguity when observing a string
99  T operator= (const char *c) {
100  T nu(c);
101  onChange(value, nu);
102  return value = nu;
103  }
104 
105  T operator =(const T &otr) {
106  onChange(value, otr);
107  value = otr;
108  return value;
109  }
110 
111  T operator =(T &&otr) {
112  onChange(value, otr);
113  value = std::move(otr);
114  return value;
115  }
116 
117  // TODO: Put all the operator macro invocations into
118  // own file so we reuse them in the test.
119 
120  // TODO: Component assignment operators (+= -= ..)
121  // TODO: Performance: return by reference for operators
122 
123 #define UNR(op) \
124  T operator op (int) { \
125  T old = value; \
126  T ret = value op; \
127  onChange(old, value); \
128  return ret; \
129  }
130 
131  UNR(++);
132  UNR(--);
133 
134 #undef UNR
135 
136 #define UNL(op) \
137  T operator op () { \
138  T old = value; \
139  T ret = op value; \
140  onChange(old, value); \
141  return ret; \
142  }
143 
144  UNL(++);
145  UNL(--);
146 
147 #undef UNL
148 
149 
150 #define ASGN(op) \
151  template<typename O> \
152  T operator op ## =(const O &otr) { \
153  T old = value; \
154  T ret = value op ## = otr; \
155  onChange(old, value); \
156  return ret; \
157  }
158 
159  ASGN(+);
160  ASGN(-);
161  ASGN(*);
162  ASGN(/);
163  ASGN(%);
164  ASGN(&);
165  ASGN(|);
166  ASGN(^);
167  ASGN(<<);
168  ASGN(>>);
169 
170 #undef ASGN
171 
172 
173  // This is for seriliazation usage only, to not get caught in endless loop when receiving new values
174  // TODO find another way (since other watchers wont be notified as well anymore)
175  void setnosync(const char *c)
176  {
177  value = c;
178  }
179 
180  void setnosync(const T &otr)
181  {
182  value = otr;
183  }
184 
185  void setnosync(T &&otr)
186  {
187  value = std::move(otr);
188  }
189 
190  void sync()
191  {
192  onChange(value, value);
193  }
194 };
195 
196 // Output Operator
197 
198 template<typename T>
199 std::ostream& operator<<(std::ostream& os, const SharedVar<T> &x) {
200  os << *x;
201  return os;
202 }
203 
204 
205 // Specializations for min/max (otherwise they are causing
206 // frequent problems)
207 // TODO: Get rid of ::min, ::max; define these for std::*
208 
209 template<typename T>
210 const T& min(const inexor::rpc::SharedVar<T> &a, const T &b) {
211  return std::min(*a, b);
212 }
213 template<typename T>
214 const T& min(const T &a, const inexor::rpc::SharedVar<T> &b) {
215  return std::min(a, *b);
216 }
217 template<typename T>
219 {
220  return std::min(*a, *b);
221 }
222 
223 template<typename T>
224 const T& max(const inexor::rpc::SharedVar<T> &a, const T &b) {
225  return std::max(*a, b);
226 }
227 template<typename T>
228 const T& max(const T &a, const inexor::rpc::SharedVar<T> &b) {
229  return std::max(a, *b);
230 }
231 template<typename T>
233 {
234  return std::max(*a, *b);
235 }
236 
237 } // ns inexor::rpc
238 } // ns inexor
239 
240 // Import into global namespace.
242 
T value
Definition: SharedVar.hpp:62
const T & max(const inexor::rpc::SharedVar< T > &a, const T &b)
Definition: SharedVar.hpp:224
T & operator*()
Definition: SharedVar.hpp:75
SharedVar(T &&otr)
Definition: SharedVar.hpp:93
SharedVar(T &otr)
Definition: SharedVar.hpp:92
void setnosync(const T &otr)
Definition: SharedVar.hpp:180
SharedVar(T &&otr, SharedOption)
Definition: SharedVar.hpp:96
boost::signals2::signal< A...> signal
Definition: SharedVar.hpp:60
void sync()
Definition: SharedVar.hpp:190
void setnosync(T &&otr)
Definition: SharedVar.hpp:185
T * operator->()
Definition: SharedVar.hpp:77
const T & min(const inexor::rpc::SharedVar< T > &a, const T &b)
Definition: SharedVar.hpp:210
const T & min(const inexor::rpc::SharedVar< T > &a, const inexor::rpc::SharedVar< T > &b)
Definition: SharedVar.hpp:218
SharedVar< T > TMe
Definition: SharedVar.hpp:57
bool move(physent *d, vec &dir)
Definition: physics.cpp:1342
SharedVar(Args &&...args, SharedOption)
Definition: SharedVar.hpp:87
SharedVar(T &otr, SharedOption)
Definition: SharedVar.hpp:95
GLsizei GLboolean const GLfloat * value
Definition: glexts.hpp:57
const T & max(const inexor::rpc::SharedVar< T > &a, const inexor::rpc::SharedVar< T > &b)
Definition: SharedVar.hpp:232
SharedVar(const SharedVar< T > &otr)
Definition: SharedVar.hpp:90
SharedVar wrapper for primitive/immutable objects.
Definition: SharedVar.hpp:55
signal< void(const T &, const T &)> onChange
Event that is fired when a new value is assigned;.
Definition: SharedVar.hpp:71
void setnosync(const char *c)
Definition: SharedVar.hpp:175
Definition: SharedOptions.hpp:6
T operator=(const char *c)
Definition: SharedVar.hpp:99