MADARA  3.2.3
Tracker.h
Go to the documentation of this file.
1 
2 
3 #ifndef INCL_MADARA_RCW_TRACKER_H
4 #define INCL_MADARA_RCW_TRACKER_H
5 
13 #include <string>
14 #include <vector>
15 #include <map>
16 #include <list>
17 #include <type_traits>
18 #include <initializer_list>
21 #include "madara/utility/StdInt.h"
22 #include "madara/MadaraExport.h"
27 #include "BaseTracker.h"
28 
29 namespace madara { namespace knowledge { namespace rcw
30 {
33  template<class T, class R, bool RD = true, bool WR = true, class dummy = void>
34  class Tracker
35  {
36  static_assert(sizeof(T) < 0, "Type unsupported for adding to Transaction");
37  };
38 
40  template<class T, class R>
41  class Tracker<T, R, false, false, void>
42  : public BaseTracker
43  {
44  private:
45  static_assert(sizeof(T) < 0, "Cannot create tracker that can neither read nor write");
46  };
47 
50  template<class T>
51  class Tracker<T, VariableReference, true, true, typename std::enable_if<
52  supports_get_value<T>::value &&
53  supports_knowledge_cast<T>::value &&
54  supports_self_eq<T>::value &&
55  !supports_is_dirty<T>::value>::type>
56  : public BaseTracker
57  {
58  private:
59  typedef typename std::decay<decltype(get_value(std::declval<T>()))>::type V;
60 
61  T *tracked_;
62  V orig_;
63 
64  static const bool can_read = true;
65  static const bool can_write = true;
66 
67  Tracker(T *tracked, VariableReference ref)
68  : BaseTracker(ref), tracked_(tracked), orig_() {}
69 
70  virtual void pull()
71  {
72  orig_ = knowledge_cast<V>(get());
73  set_value(*tracked_, orig_);
74  }
75 
76  virtual void push(KnowledgeBase &kb)
77  {
78  if (get_value(*tracked_) != get_value(orig_)) {
79  Tracker::force_push(kb);
80  }
81  }
82 
83  virtual void force_push(KnowledgeBase &kb)
84  {
85  set(kb, knowledge_cast(get_value(*tracked_)));
86  post_set(kb);
87  }
88 
89  virtual const char *get_name() const
90  {
91  return ref_.get_name();
92  }
93 
94  virtual const void *get_tracked() const
95  {
96  return (void*)tracked_;
97  }
98 
99  friend class Transaction;
100  };
101 
103  template<class T>
104  class Tracker<T, VariableReference, true, false, typename std::enable_if<
105  supports_get_value<T>::value &&
106  supports_knowledge_cast<T>::value>::type>
107  : public BaseTracker
108  {
109  private:
110  typedef typename std::decay<decltype(get_value(std::declval<T>()))>::type V;
111 
112  T *tracked_;
113 
114  static const bool can_read = true;
115  static const bool can_write = false;
116 
117  Tracker(T *tracked, VariableReference ref)
118  : BaseTracker(ref), tracked_(tracked) {}
119 
120  virtual void pull()
121  {
122  set_value(*tracked_, knowledge_cast<V>(get()));
123  }
124 
125  virtual void push(KnowledgeBase &) {}
126 
127  virtual void force_push(KnowledgeBase &) {}
128 
129  virtual const char *get_name() const
130  {
131  return ref_.get_name();
132  }
133 
134  virtual const void *get_tracked() const
135  {
136  return (void*)tracked_;
137  }
138 
139  friend class Transaction;
140  };
141 
144  template<class T>
145  class Tracker<T, VariableReference, false, true, typename std::enable_if<
146  supports_get_value<T>::value &&
147  supports_knowledge_cast<T>::value &&
148  supports_self_eq<T>::value &&
149  !supports_is_dirty<T>::value>::type>
150  : public BaseTracker
151  {
152  private:
153  typedef typename std::decay<decltype(get_value(std::declval<T>()))>::type V;
154 
155  T *tracked_;
156  // Note that we don't store original value, since we set to default value
157  // on a pull, and can compare to that on push to see if it has changed.
158 
159  static const bool can_read = false;
160  static const bool can_write = true;
161 
162  Tracker(T *tracked, VariableReference ref)
163  : BaseTracker(ref), tracked_(tracked) {}
164 
165  virtual void pull()
166  {
167  set_value(*tracked_, V());
168  }
169 
170  virtual void push(KnowledgeBase &kb)
171  {
172  if (get_value(*tracked_) != V()) {
173  Tracker::force_push(kb);
174  }
175  }
176 
177  virtual void force_push(KnowledgeBase &kb)
178  {
179  set(kb, knowledge_cast(get_value(*tracked_)));
180  post_set(kb);
181  }
182 
183  virtual const char *get_name() const
184  {
185  return ref_.get_name();
186  }
187 
188  virtual const void *get_tracked() const
189  {
190  return (void*)tracked_;
191  }
192 
193  friend class Transaction;
194  };
195 
198  template<class T>
199  class Tracker<T, VariableReference, true, true, typename std::enable_if<
200  supports_get_value<T>::value &&
201  supports_knowledge_cast<T>::value &&
202  supports_is_dirty<T>::value &&
203  !supports_indexed_is_dirty<T>::value>::type >
204  : public BaseTracker
205  {
206  private:
207  T *tracked_;
208 
209  static const bool can_read = true;
210  static const bool can_write = true;
211 
212  typedef typename std::decay<decltype(get_value(std::declval<T>()))>::type V;
213 
214  Tracker(T *tracked, VariableReference ref)
215  : BaseTracker(ref), tracked_(tracked) {}
216 
217  virtual void pull()
218  {
219  V val = knowledge_cast<V>(get());
220  set_value(*tracked_, val);
221  clear_dirty(*tracked_);
222  }
223 
224  virtual void push(KnowledgeBase &kb)
225  {
226  if (is_dirty(*tracked_)) {
227  Tracker::force_push(kb);
228  }
229  }
230 
231  virtual void force_push(KnowledgeBase &kb)
232  {
233  set(kb, knowledge_cast(get_value(*tracked_)));
234  post_set(kb);
235  }
236 
237  virtual const char *get_name() const
238  {
239  return ref_.get_name();
240  }
241 
242  virtual const void *get_tracked() const
243  {
244  return (void*)tracked_;
245  }
246 
247  friend class Transaction;
248  };
249 
252  template<class T>
253  class Tracker<T, VariableReference, false, true, typename std::enable_if<
254  supports_get_value<T>::value &&
255  supports_knowledge_cast<T>::value &&
256  supports_is_dirty<T>::value &&
257  !supports_indexed_is_dirty<T>::value>::type >
258  : public BaseTracker
259  {
260  private:
261  T *tracked_;
262 
263  typedef typename std::decay<decltype(get_value(std::declval<T>()))>::type V;
264 
265  static const bool can_read = false;
266  static const bool can_write = true;
267 
268  Tracker(T *tracked, VariableReference ref)
269  : BaseTracker(ref), tracked_(tracked) {}
270 
271  virtual void pull()
272  {
273  set_value(*tracked_, V());
274  clear_dirty(*tracked_);
275  }
276 
277  virtual void push(KnowledgeBase &kb)
278  {
279  if (is_dirty(*tracked_)) {
280  Tracker::force_push(kb);
281  }
282  }
283 
284  virtual void force_push(KnowledgeBase &kb)
285  {
286  set(kb, knowledge_cast(get_value(*tracked_)));
287  post_set(kb);
288  }
289 
290  virtual const char *get_name() const
291  {
292  return ref_.get_name();
293  }
294 
295  virtual const void *get_tracked() const
296  {
297  return (void*)tracked_;
298  }
299 
300  friend class Transaction;
301  };
302 
305  template<class T, bool RD, bool WR>
306  class Tracker<T, VariableReference, RD, WR, typename std::enable_if<
307  supports_indexed_get_value<T>::value &&
308  supports_size<T>::value &&
309  !supports_is_all_dirty<T>::value &&
310  !supports_is_size_dirty<T>::value &&
311  supports_indexed_is_dirty<T>::value>::type >
312  : public BaseTracker
313  {
314  private:
315  static_assert(RD == true, "Write-only not supported for containers of tracked items");
316 
317  T *tracked_;
318  size_t orig_size_;
319 
320  typedef typename std::decay<decltype(get_value(std::declval<T>(), 0))>::type V;
321 
322  static const bool can_read = RD;
323  static const bool can_write = WR;
324 
325  Tracker(T *tracked, VariableReference ref)
326  : BaseTracker(ref), tracked_(tracked), orig_size_() {}
327 
328  virtual void pull()
329  {
330  std::vector<double> val = get().to_doubles();
331  orig_size_ = val.size();
332  size_t n = orig_size_;
333  tracked_->resize(n);
334  for (size_t i = 0; i < n; ++i) {
335  set_value(*tracked_, i, (V) val[i]);
336  clear_dirty(*tracked_, i);
337  }
338  }
339 
340  virtual void push(KnowledgeBase &kb)
341  {
342  if (can_write) {
343  size_t n = tracked_->size();
344  if (tracked_->size() != orig_size_) {
345  get_mut().resize(n);
346  }
347  for (size_t i = 0; i < n; ++i) {
348  if (is_dirty(*tracked_, i)) {
349  set_index(kb, i, get_value(*tracked_, i));
350  }
351  }
352  post_set(kb);
353  }
354  }
355 
356  virtual void force_push(KnowledgeBase &kb)
357  {
358  if (can_write) {
359  size_t n = tracked_->size();
360  if (tracked_->size() != orig_size_) {
361  get_mut().resize(n);
362  }
363  for (size_t i = 0; i < n; ++i) {
364  set_index(kb, i, get_value(*tracked_, i));
365  }
366  post_set(kb);
367  }
368  }
369 
370  virtual const char *get_name() const
371  {
372  return ref_.get_name();
373  }
374 
375  virtual const void *get_tracked() const
376  {
377  return (void*)tracked_;
378  }
379 
380  friend class Transaction;
381  };
382 
385  template<class T, bool RD, bool WR>
386  class Tracker<T, VariableReference, RD, WR, typename std::enable_if<
387  supports_get_value<T>::value &&
388  supports_indexed_get_value<T>::value &&
389  supports_size<T>::value &&
390  supports_knowledge_cast<T>::value &&
391  supports_is_dirty<T>::value &&
392  supports_is_all_dirty<T>::value &&
393  supports_is_size_dirty<T>::value &&
394  supports_indexed_is_dirty<T>::value>::type >
395  : public BaseTracker
396  {
397  private:
398  T *tracked_;
399 
400  typedef typename std::decay<decltype(get_value(std::declval<T>()))>::type V;
401 
402  static const bool can_read = RD;
403  static const bool can_write = WR;
404 
405  Tracker(T *tracked, VariableReference ref)
406  : BaseTracker(ref), tracked_(tracked) {}
407 
408  virtual void pull()
409  {
410  if (can_read) {
411  V val = knowledge_cast<V>(get());
412  set_value(*tracked_, val);
413  } else {
414  set_value(*tracked_, V());
415  }
416  clear_dirty(*tracked_);
417  }
418 
419  virtual void push(KnowledgeBase &kb)
420  {
421  if (can_write) {
422  if (is_all_dirty(*tracked_)) {
423  return Tracker::force_push(kb);
424  }
425  size_t n = tracked_->size();
426  if (is_size_dirty(*tracked_) && n < get().size()) {
427  get_mut().resize(n);
428  }
429  for (size_t i = 0; i < n; ++i) {
430  if (is_dirty(*tracked_, i)) {
431  set_index(kb, i, get_value(*tracked_, i));
432  }
433  }
434  post_set(kb);
435  }
436  }
437 
438  virtual void force_push(KnowledgeBase &kb)
439  {
440  if (can_write) {
441  set(kb, knowledge_cast(get_value(*tracked_)));
442  post_set(kb);
443  }
444  }
445 
446  virtual const char *get_name() const
447  {
448  return ref_.get_name();
449  }
450 
451  virtual const void *get_tracked() const
452  {
453  return (void*)tracked_;
454  }
455 
456  friend class Transaction;
457  };
458 } } } // end namespace madara::knowledge::rcw
459 
460 #endif // INCL_MADARA_RCW_TRACKER_H
helper type for specifying template type parameters using a function argument instead of inside expli...
Definition: KnowledgeCast.h:72
bool is_size_dirty(const Tracked< std::vector< T >> &t)
Return size changed dirty flag of Tracked vector.
Definition: Tracked.h:836
Manages a Read-Compute-Write cycle for registered variables.
Definition: Transaction.h:43
Base type for Trackers.
Definition: BaseTracker.h:63
STL namespace.
Optimized reference to a variable within the knowledge base.
bool is_dirty(const Tracked< T > &t)
Returns dirty flag of Tracked types.
Definition: Tracked.h:533
bool is_all_dirty(const Tracked< std::vector< T >> &t)
Return global dirty flag of Tracked vector.
Definition: Tracked.h:829
void clear_dirty(Tracked< T > &t)
Clears dirty flag of Tracked types.
Definition: Tracked.h:540
This class provides a distributed knowledge base to users.
Definition: KnowledgeBase.h:45
Tracker which puts variable values into a single KnowledgeRecord.
Definition: Tracker.h:34
const T & get_value(const T &t)
Fallback definition of get_value; simply passes through the value.
Definition: BaseTracker.h:34
Provides functions and classes for the distributed knowledge base.
Out knowledge_cast(const KnowledgeRecord &in)
Convert a KnowledgeRecord into a specified type.
void set_value(T &t, const T &v)
Fallback definition of set_value; simply passes through the value.
Definition: BaseTracker.h:41
Copyright (c) 2015 Carnegie Mellon University.