MIRA
PropertyNode.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2012 by
3  * MetraLabs GmbH (MLAB), GERMANY
4  * and
5  * Neuroinformatics and Cognitive Robotics Labs (NICR) at TU Ilmenau, GERMANY
6  * All rights reserved.
7  *
8  * Contact: info@mira-project.org
9  *
10  * Commercial Usage:
11  * Licensees holding valid commercial licenses may use this file in
12  * accordance with the commercial license agreement provided with the
13  * software or, alternatively, in accordance with the terms contained in
14  * a written agreement between you and MLAB or NICR.
15  *
16  * GNU General Public License Usage:
17  * Alternatively, this file may be used under the terms of the GNU
18  * General Public License version 3.0 as published by the Free Software
19  * Foundation and appearing in the file LICENSE.GPL3 included in the
20  * packaging of this file. Please review the following information to
21  * ensure the GNU General Public License version 3.0 requirements will be
22  * met: http://www.gnu.org/copyleft/gpl.html.
23  * Alternatively you may (at your option) use any later version of the GNU
24  * General Public License if such license has been publicly approved by
25  * MLAB and NICR (or its successors, if any).
26  *
27  * IN NO EVENT SHALL "MLAB" OR "NICR" BE LIABLE TO ANY PARTY FOR DIRECT,
28  * INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF
29  * THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF "MLAB" OR
30  * "NICR" HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  *
32  * "MLAB" AND "NICR" SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING,
33  * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
34  * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
35  * ON AN "AS IS" BASIS, AND "MLAB" AND "NICR" HAVE NO OBLIGATION TO
36  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS OR MODIFICATIONS.
37  */
38 
47 #ifndef _MIRA_PROPERTYNODE_H_
48 #define _MIRA_PROPERTYNODE_H_
49 
50 #include <boost/interprocess/sync/scoped_lock.hpp>
51 
53 #include <serialization/adapters/std/pair>
56 #include <platform/Typename.h>
57 #include <thread/ScopedAccess.h>
58 #include <utils/IsCopyAssignable.h>
59 
60 namespace mira {
61 
63 
64 // forward declarations
65 class PropertySerializer;
66 class RootPropertyNode;
67 
69 typedef std::set<PropertyNodeListener*> PropertyNodeListenerList;
70 
71 template <typename T>
73 
75 {
76 public:
78  PropertyNodeInfo(const std::string& id, const std::string& name,
79  const std::string& comment, const Typename& type,
80  bool isReadOnly, bool isVolatile) :
84 
85  // special copy constructor, that clones the property hint
87  mID(info.mID), mName(info.mName), mComment(info.mComment),
88  mHint(info.mHint.clone()), mType(info.mType),
90 
91 public:
93  {
94  mID = info.mID;
95  mName = info.mName;
96  mComment = info.mComment;
97  mHint = info.mHint.clone();
98  mType = info.mType;
99  mIsReadOnly = info.mIsReadOnly;
100  mIsVolatile = info.mIsVolatile;
101 
102  return *this;
103  }
104 
105 public:
106 
107  template<typename Reflector>
108  void reflectCommon(Reflector& r)
109  {
110  serialization::VersionType v = r.version(2, this);
111  r.member("ID", mID, "");
112  r.member("Name", mName, "");
113  r.member("Comment", mComment, "");
114  r.member("Type", mType, "The typename");
115  r.member("IsReadOnly", mIsReadOnly, "");
116  if (v > 1)
117  r.member("IsVolatile", mIsVolatile, "");
118  }
119 
120  template<typename Reflector>
121  void reflectRead(Reflector& r)
122  {
123  reflectCommon(r);
125  r.member("Hint", hints, "The property hints", REFLECT_CTRLFLAG_TEMP_TRACKING);
126  }
127 
128  template<typename Reflector>
129  void reflectWrite(Reflector& r)
130  {
131  reflectCommon(r);
133  r.member("Hint", hints, "The property hints", REFLECT_CTRLFLAG_TEMP_TRACKING);
134  mHint.fromList(hints);
135  }
136 
138 
139 public:
140 
142  const std::string& id() const { return mID; }
143 
145  const std::string& name() const { return mName; }
146 
148  const std::string& comment() const { return mComment; }
149 
151  const Typename& type() const { return mType; }
152 
158  template <typename T>
159  T getHint(const std::string& attribute, const T& defaultValue = T()) const {
160  return mHint.get(attribute, defaultValue);
161  }
162 
164  bool hasHint(const std::string& attribute) const {
165  return mHint.has(attribute);
166  }
167 
169  bool isReadOnly() const {return mIsReadOnly;}
170 
172  bool isVolatile() const {return mIsVolatile;}
173 
174 
175 protected:
176  friend class PropertySerializer;
177 
179  void setName(const std::string& name) {
180  mName = name;
181  }
182 
183  void setVolatile(bool isVolatile) {
185  }
186 
187 protected:
188  std::string mID;
189  std::string mName;
190  std::string mComment;
193  bool mIsReadOnly;
194  bool mIsVolatile;
195 };
196 
213 {
214  friend class PropertySerializer; // needs to call addChild, etc
215 
216 public:
217  typedef std::vector<PropertyNode*> NodeList;
218 
219 public:
221  PropertyNodeInfo(info), mParent(NULL) {}
222 
223  PropertyNode(const std::string& id, const std::string& name,
224  const std::string& comment, const Typename& type,
225  bool isReadOnly, bool isVolatile) :
227  mParent(NULL) {}
228 
229  virtual ~PropertyNode();
230 
231 public:
232 
234  virtual PropertyNode* parent() { return mParent; }
235 
237  virtual const PropertyNode* parent() const { return mParent; }
238 
240  virtual NodeList& children() { return mChildren; }
241 
243  virtual const NodeList& children() const { return mChildren; }
244 
255  const PropertyNode* findChildNode(const std::vector<std::string>& ids,
256  std::size_t level = 0) const;
257 
262  PropertyNode* findChildNode(const std::vector<std::string>& ids,
263  std::size_t level = 0);
264 
276  const PropertyNode* findChildNode(const std::string& id) const;
277 
281  PropertyNode* findChildNode(const std::string& id);
282 
283 public:
284 
293  std::string fullID(PropertyNode* p = NULL) const
294  {
295  std::string s = id();
296  boost::algorithm::replace_all(s, ".", "\\");
297  for(const PropertyNode* n = parent(); n!=NULL && n!=p; n=n->parent())
298  s = boost::algorithm::replace_all_copy(n->id(), ".", "\\") + "." + s;
299  return s;
300  }
301 
302 public:
303 
311  virtual void setFromJSON(const json::Value& value,
312  const Duration& timeout = Duration::milliseconds(100)) = 0;
313 
317  virtual json::Value getAsJSON() const = 0;
318 
319 public:
320 
327  virtual void setFromString(const std::string& value,
328  const Duration& timeout = Duration::milliseconds(100));
329 
333  virtual std::string getAsString() const;
334 
335 public:
336 
341  template <typename T>
343 
348  template <typename T>
349  const TypedPropertyNode<T>* toTyped() const;
350 
351 public:
352 
356  virtual void synchronize() = 0;
357 
358 public:
359 
360  virtual RootPropertyNode* getRootNode();
361  virtual const RootPropertyNode* getRootNode() const;
362 
363 protected:
364 
370  void addChild(PropertyNode* child, int index = -1);
371 
376  void removeChild(int index) { removeChild(index, std::next(mChildren.begin(), index)); }
377 
382  void removeChildren(int index, int count) { removeChildren(index, std::next(mChildren.begin(), index), count); }
383 
389  void removeChild(int index, NodeList::iterator it);
390 
397  void removeChildren(int index, NodeList::iterator it, int count);
398 
403  void removeAllChildren();
404 
409  void moveChild(int index, int destination) {
410  moveChild(index, std::next(mChildren.begin(), index),
411  destination, std::next(mChildren.begin(), destination)); }
412 
418  void moveChild(int index, NodeList::iterator it, int destination, NodeList::iterator destIt);
419 
420 protected:
421 
423  virtual void beginAddChildren(PropertyNodeListenerList& listeners, int index, int count);
424  virtual void endAddChildren(PropertyNodeListenerList& listeners);
425 
427  virtual void beginRemoveChildren(PropertyNodeListenerList& listeners, int index, NodeList::iterator it, int count);
428  virtual void endRemoveChildren(PropertyNodeListenerList& listeners);
429 
431  virtual void beginMoveChildren(PropertyNodeListenerList& listeners, int index, NodeList::iterator it, int count, int destination);
432  virtual void endMoveChildren(PropertyNodeListenerList& listeners);
433 
434 private:
435 
437  PropertyNode* mParent;
438 
440  NodeList mChildren;
441 };
442 
444 
446 {
447 public:
449 
450  virtual void beginAddChildren(const PropertyNode* node, int index, int count) = 0;
451  virtual void endAddChildren() = 0;
452 
453  virtual void beginRemoveChildren(const PropertyNode* node, int index, int count) = 0;
454  virtual void endRemoveChildren() = 0;
455 
456  virtual void beginMoveChildren(const PropertyNode* node, int index, int count, int destination) = 0;
457  virtual void endMoveChildren() = 0;
458 };
459 
461 
464 // Deriving from PropertyNode allows to use PropertyNode's mParent to refer
465 // to an instance of RootPropertyNode, instead of adding another pointer in
466 // PropertyNode (in each instance, even though it is only required in the root).
467 {
468 public:
469 
471 
472 public:
473 
474  void addChild(PropertyNode* child, int index = -1);
475 
476  void removeChild(int index, NodeList::iterator it);
477  void removeChild(int index);
478  void removeAllChildren();
479 
480 private:
481 
482  // These are not meant to ever be called
483  void setFromJSON(const json::Value& value, const Duration& timeout) override;
484  json::Value getAsJSON() const override;
485  void synchronize() override;
486 
487 protected:
488 
489  RootPropertyNode* getRootNode() override;
490  const RootPropertyNode* getRootNode() const override;
491 
492 public:
493 
494  void registerListener(PropertyNodeListener* listener);
496 
497 protected:
498  friend class PropertyNode;
500 
501  ScopedAccess<ProtectedListenerList> getListeners(bool alreadyLocked = false);
502 
503 private:
504  ProtectedListenerList mListeners;
505 
506 public:
507  using MutexType = boost::recursive_timed_mutex;
508  using LockType = boost::interprocess::scoped_lock<MutexType>;
509 
519  LockType getLock();
520 
527  LockType tryGetLock(const Duration& timeout = Duration::milliseconds(10));
528 
529 private:
530  MutexType mMutex;
531 };
532 
534 
547 template <typename T>
548 class TypedPropertyNode : public PropertyNode
549 {
550 public:
551 
553  typedef T value_type; // STL conform typedef
554 
555 public:
556 
558  PropertyNode(info) {
559  assert(info.type()==typeName<value_type>());
560  }
561 
562  TypedPropertyNode(const std::string& id, const std::string& name,
563  const std::string& comment, bool isReadOnly, bool isVolatile) :
565 
566 public:
567 
574  virtual void set(const value_type& value,
575  const Duration& timeout = Duration::milliseconds(100)) = 0;
576 
580  virtual value_type get() const = 0;
581 
582 protected:
584  return root ? root->getLock() : RootPropertyNode::LockType();
585  }
586 
588  return getLock(getRootNode());
589  }
590 
592  return root ? root->tryGetLock(timeout) : RootPropertyNode::LockType();
593  }
594 
596  return tryGetLock(getRootNode(), timeout);
597  }
598 
599 protected:
600  template<typename Type = T>
601  static constexpr bool mayHaveChildNodes();
602 
603 };
604 
606 
607 // LockedPropertyNodeAccess encapsulates locking all access to a TypedPropertyNode's
608 // internal reference/pointer/accessor.
609 // Optionally, when (const!) access is attempted but not possible (because the node is locked
610 // by another thread), it can return a backup of the previous value. The backup value is
611 // automatically updated with each successful read (const access).
612 
613 template <typename NodeType, typename ValueType>
614 class LockedPropertyNodeAccessCommon : boost::noncopyable
615 {
616 public:
617  struct NoLock{};
618 protected:
619  LockedPropertyNodeAccessCommon(NodeType* parent, const ValueType& ref)
620  : p(parent), r(ref), needLock(false)
621  {
622  if (p->isVolatile()) {
623  if (auto root = parent->getRootNode()) {
624  needLock = true;
625  lock = root->tryGetLock();
626  }
627  }
628  }
629 
630  LockedPropertyNodeAccessCommon(NodeType* parent, const ValueType& ref, NoLock)
631  : p(parent), r(ref), needLock(false) {}
632 
633 protected:
634  NodeType* p;
635  const ValueType& r;
636  bool needLock;
637  boost::interprocess::scoped_lock<RootPropertyNode::MutexType> lock;
638 };
639 
640 template <typename NodeType, typename ValueType,
641  bool ValueTypePointer = false, bool UseBackup = false>
642 class LockedPropertyNodeAccess : public LockedPropertyNodeAccessCommon<NodeType, ValueType>
643 {
644 public:
646  using NoLock = typename Base::NoLock;
647 
648 public:
649  LockedPropertyNodeAccess(NodeType* parent, const ValueType& ref)
650  : LockedPropertyNodeAccessCommon<NodeType, ValueType>(parent, ref) {}
651 
652  LockedPropertyNodeAccess(NodeType* parent, const ValueType& ref, NoLock)
653  : LockedPropertyNodeAccessCommon<NodeType, ValueType>(parent, ref, NoLock()) {}
654 
655 public:
656  const ValueType& operator*() const {
657  if (this->needLock && !this->lock.owns())
658  MIRA_THROW(XIO, "Property is not available (yet?)")
659 
660  return this->r;
661  }
662 
663  ValueType& operator*() {
664  if (this->needLock && !this->lock.owns())
665  MIRA_THROW(XIO, "PropertyNode is locked by another thread");
666 
667  return const_cast<ValueType&>(this->r);
668  }
669 };
670 
671 // specialize for ValueTypePointer=false, UseBackup=true --> invalid
672 template <typename NodeType, typename ValueType>
673 class LockedPropertyNodeAccess<NodeType, ValueType, false, true> {
674  static_assert(sizeof(ValueType)==0, // assertion must depend on template parameter!
675  "LockedPropertyNodeAccess: combination ValueTypePointer=false, UseBackup=true not implemented");
676 };
677 
678 // specialize for ValueTypePointer=true, UseBackup=false
679 template <typename NodeType, typename ValueType>
680 class LockedPropertyNodeAccess<NodeType, ValueType, true, false>
681  : public LockedPropertyNodeAccessCommon<NodeType, ValueType*>
682 {
683 protected:
684  typedef ValueType* PointerType;
685 
686 public:
688  using NoLock = typename Base::NoLock;
689 
690 public:
691  LockedPropertyNodeAccess(NodeType* parent, const PointerType& ref)
692  : LockedPropertyNodeAccessCommon<NodeType, PointerType>(parent, ref) {}
693 
694  LockedPropertyNodeAccess(NodeType* parent, const PointerType& ref, NoLock)
695  : LockedPropertyNodeAccessCommon<NodeType, PointerType>(parent, ref, NoLock()) {}
696 
697 public:
698  const ValueType& operator*() const {
699  if (this->needLock && !this->lock.owns())
700  MIRA_THROW(XIO, "Property is not available (yet?)")
701 
702  return *this->r;
703  }
704 
705  ValueType& operator*() {
706  if (this->needLock && !this->lock.owns())
707  MIRA_THROW(XIO, "PropertyNode is locked by another thread");
708 
709  return const_cast<ValueType&>(*this->r);
710  }
711 };
712 
713 // specialize for ValueTypePointer=true, UseBackup=true
714 template <typename NodeType, typename ValueType>
715 class LockedPropertyNodeAccess<NodeType, ValueType, true, true>
716  : public LockedPropertyNodeAccessCommon<NodeType, ValueType*>
717 {
718 protected:
719  typedef ValueType* PointerType;
720 public:
722  using NoLock = typename Base::NoLock;
723 
724 public:
725  LockedPropertyNodeAccess(NodeType* parent, const PointerType& ref)
726  : LockedPropertyNodeAccessCommon<NodeType, PointerType>(parent, ref) {}
727 
728  LockedPropertyNodeAccess(NodeType* parent, const PointerType& ref, NoLock)
729  : LockedPropertyNodeAccessCommon<NodeType, PointerType>(parent, ref, NoLock()) {}
730 
731 public:
732  const ValueType& operator*() const {
733  if (this->needLock && !this->lock.owns()) {
734 
735  if (this->p->mBackupValue)
736  return *this->p->mBackupValue;
737 
738  MIRA_THROW(XIO, "Property is not available (yet?)")
739  }
740 
741  this->p->mBackupValue.reset(new ValueType(*this->r));
742  return *this->r;
743  }
744 
745  ValueType& operator*() {
746  if (this->needLock && !this->lock.owns())
747  MIRA_THROW(XIO, "PropertyNode is locked by another thread");
748 
749  return const_cast<ValueType&>(*this->r);
750  }
751 };
752 
754 
755 template <typename T>
757 {
758  typedef TypedPropertyNode<T> Base;
759 public:
760  typedef typename Base::value_type value_type;
761 public:
762  TypedPropertyNodeImplGetSetMixinBase(const std::string& id, const std::string& name,
763  const std::string& comment, value_type& value,
764  bool isReadOnly, bool isVolatile) :
765  Base(id, name, comment, isReadOnly, isVolatile), mValue(&value) {}
766 
767 protected:
768  // all access to mValue (except update()) goes through LockedAccess,
769  // ensures locking the PropertyNode if required
772  friend LockedAccess;
773  using NoLock = typename LockedAccess::NoLock;
774 
775  const LockedAccess valueAccess() const {
776  return LockedAccess(const_cast<TypedPropertyNodeImplGetSetMixinBase*>(this), mValue);
777  }
778 
780  return LockedAccess(this, mValue);
781  }
782 
784  return LockedAccess(const_cast<TypedPropertyNodeImplGetSetMixinBase*>(this), mValue, NoLock());
785  }
786 
788  return LockedAccess(this, mValue, NoLock());
789  }
790 
791 protected:
792 
793  void setValue(value_type& nodeValue, const value_type& newValue) {
794  nodeValue = newValue;
795  }
796 
797 protected:
798  friend class PropertySerializer;
799 
804  void update(T& value) {
805  mValue = &value;
806  }
807 
808 private:
809  value_type* mValue;
810  std::unique_ptr<value_type> mBackupValue; // value_type may not be default constructible
811 };
812 
818 template <typename T, bool /* = true */>
820 {
822 public:
823  typedef typename Base::value_type value_type;
824 public:
825  TypedPropertyNodeImplGetSetMixin(const std::string& id, const std::string& name,
826  const std::string& comment, value_type& value,
827  bool isReadOnly, bool isVolatile) :
828  Base(id, name, comment, value, isReadOnly, isVolatile) {}
829 
830 protected:
831 
832  void setValue(value_type& nodeValue, const value_type& newValue) {
840  Base::setValue(nodeValue, newValue);
841  }
842 
843 public:
844 
845  value_type get() const override {
846  return *Base::valueAccess();
847  }
848 };
849 
850 template <typename T>
852 {
854 public:
855  typedef typename Base::value_type value_type;
856 public:
857  TypedPropertyNodeImplGetSetMixin(const std::string& id, const std::string& name,
858  const std::string& comment, value_type& value,
859  bool isReadOnly, bool isVolatile) :
860  Base(id, name, comment, value, isReadOnly, isVolatile) {}
861 
862 protected:
863 
864  void setValue(value_type& nodeValue, const value_type& newValue) {
865  MIRA_THROW(XLogical, "Cannot set value of property, since the underlying class does not provide an assignment operator");
866  }
867 
868 public:
869 
870  value_type get() const override {
871  MIRA_THROW(XLogical, "Cannot get value of property, since the underlying class does not provide an assignment operator");
872  }
873 };
874 
879 template <typename T>
880 class TypedPropertyNodeImpl : public TypedPropertyNodeImplGetSetMixin<T,IsCopyAssignable<T>::value>
881 {
883 public:
884  typedef typename Base::value_type value_type;
885  using NoLock = typename Base::NoLock;
886 public:
887  TypedPropertyNodeImpl(const std::string& id, const std::string& name,
888  const std::string& comment, value_type& value,
889  bool isReadOnly, bool isVolatile) :
890  Base(id, name, comment, value, isReadOnly, isVolatile) {}
891 public:
892 
893  void setFromJSON(const json::Value& json, const Duration& timeout) override {
894  if(this->isReadOnly())
895  MIRA_THROW(XLogical, "Cannot set value of read-only property.");
896 
897  JSONDeserializer ds(json);
898 
899  // atomic types do not need to call synchronize()
900  if constexpr(!Base::mayHaveChildNodes()) {
901  ds.deserialize(*this->valueAccess());
902  return;
903  }
904 
905  auto root = this->getRootNode();
906  auto lock = this->tryGetLock(root, timeout);
907  if (root && !lock.owns())
908  MIRA_THROW(XIO, "PropertyNode is locked by another thread");
909 
910  auto nodeValueAccess = this->valueAccess(NoLock());
911  ds.deserialize(*nodeValueAccess);
912  synchronize(*nodeValueAccess); // synchronizes this node and its children with the
913  // actual underlying data representation that
914  // might have been changed by the above deserialization
915  }
916 
917  json::Value getAsJSON() const override {
918  JSONSerializer s(true);
919  return s.serialize(*this->valueAccess());
920  }
921 
922 public:
923 
924  void set(const value_type& newValue, const Duration& timeout) override{
925  if(this->isReadOnly())
926  MIRA_THROW(XLogical, "Cannot set value of read-only property.");
927 
928  // atomic types do not need to call synchronize()
929  if constexpr(!Base::mayHaveChildNodes()) {
930  Base::setValue(*this->valueAccess(), newValue);
931  return;
932  }
933 
934  auto root = this->getRootNode();
935  auto lock = this->tryGetLock(root, timeout);
936  if (root && !lock.owns())
937  MIRA_THROW(XIO, "PropertyNode is locked by another thread");
938 
939  auto nodeValueAccess = this->valueAccess(NoLock());
940  Base::setValue(*nodeValueAccess, newValue);
941  synchronize(*nodeValueAccess); // synchronizes this node and its children with the
942  // actual underlying data representation that
943  // might have been changed by the above assignment
944  }
945 
946  // implemented in GetSetMixin
947  //value_type get() const override;
948 
949 public:
954  void synchronize() override
955  {
956  auto lock = this->getLock();
957  return synchronize(*this->valueAccess(NoLock()));
958  }
959 
960 private:
961  void synchronize(value_type& nodeValue);
962 };
963 
965 
970 template <typename T>
972 {
973  typedef TypedPropertyNode<T*> Base;
974 public:
975  typedef typename Base::value_type value_type;
976 public:
977  TypedPropertyNodeImpl(const std::string& id, const std::string& name,
978  const std::string& comment, const value_type& value,
979  bool isReadOnly, bool isVolatile) :
980  Base(id, name, comment, isReadOnly, isVolatile), mPointer(value) {}
981 
982 protected:
983  // all access to mPointer (except update()) goes through LockedAccess,
984  // ensures locking if required
986  using NoLock = typename LockedAccess::NoLock;
987 
988  const LockedAccess pointerAccess() const {
989  return LockedAccess(const_cast<TypedPropertyNodeImpl*>(this), mPointer);
990  }
991 
993  return LockedAccess(this, mPointer);
994  }
995 
997  return LockedAccess(const_cast<TypedPropertyNodeImpl*>(this), mPointer, NoLock());
998  }
999 
1001  return LockedAccess(this, mPointer, NoLock());
1002  }
1003 
1004 public:
1005  void setFromJSON(const json::Value& json, const Duration& timeout) override {
1006  if(this->isReadOnly())
1007  MIRA_THROW(XLogical, "Cannot set value of read-only property.");
1008 
1009  JSONDeserializer ds(json);
1010 
1011  // atomic types do not need to call synchronize()
1012  if constexpr(!Base::template mayHaveChildNodes<T>()) {
1013  ds.deserialize(*pointerAccess());
1014  return;
1015  }
1016 
1017  auto root = this->getRootNode();
1018  auto lock = this->tryGetLock(root, timeout);
1019  if (root && !lock.owns())
1020  MIRA_THROW(XIO, "PropertyNode is locked by another thread");
1021 
1022  auto nodePointerAccess = pointerAccess(NoLock());
1023  ds.deserialize(*nodePointerAccess);
1024  synchronize(*nodePointerAccess); // synchronizes this node and its children with the
1025  // actual underlying data representation that
1026  // might have been changed by the above deserialization
1027  }
1028  json::Value getAsJSON() const override {
1029  JSONSerializer s(true);
1030  return s.serialize(*pointerAccess());
1031  }
1032 public:
1033  void set(const value_type& newPointer, const Duration& timeout) override {
1034  if(this->isReadOnly())
1035  MIRA_THROW(XLogical, "Cannot set value of read-only property.");
1036 
1037  // atomic types do not need to call synchronize()
1038  if constexpr(!Base::template mayHaveChildNodes<T>()) {
1039  *pointerAccess() = newPointer;
1040  return;
1041  }
1042 
1043  auto root = this->getRootNode();
1044  auto lock = this->tryGetLock(root, timeout);
1045  if (root && !lock.owns())
1046  MIRA_THROW(XIO, "PropertyNode is locked by another thread");
1047 
1048  auto nodePointerAccess = pointerAccess(NoLock());
1049  *nodePointerAccess = newPointer;
1050  synchronize(*nodePointerAccess); // synchronizes this node and its children with the
1051  // actual underlying data representation that
1052  // might have been changed by the above assignment
1053  }
1054  value_type get() const override {
1055  return *pointerAccess();
1056  }
1057 protected:
1058  friend class PropertySerializer;
1059 
1064  void update(T* value) {
1065  mPointer = value;
1066  }
1067 public:
1068  void synchronize() override
1069  {
1070  auto lock = this->getLock();
1071  return synchronize(*this->pointerAccess(NoLock()));
1072  }
1073 private:
1074  void synchronize(value_type& nodePointer);
1075 private:
1076  value_type mPointer;
1077 };
1078 
1080 
1085 template <typename Getter, typename Setter>
1087  public TypedPropertyNode<typename Accessor<Getter,Setter>::value_type>
1088 {
1089  typedef typename Accessor<Getter,Setter>::value_type T;
1091  typedef TypedPropertyNode<T> Base;
1092 public:
1093  typedef typename Base::value_type value_type;
1094 public:
1095  TypedPropertyNodeImpl(const std::string& id, const std::string& name,
1096  const std::string& comment, const AccessorType& value,
1097  bool isReadOnly, bool isVolatile) :
1098  Base(id, name, comment, isReadOnly, isVolatile), mAccessor(value) {}
1099 
1100 protected:
1101  // all access to mAccessor (except update()) goes through LockedAccess,
1102  // ensures locking if required
1104  using NoLock = typename LockedAccess::NoLock;
1105 
1107  return LockedAccess(const_cast<TypedPropertyNodeImpl*>(this), mAccessor);
1108  }
1109 
1111  return LockedAccess(this, mAccessor);
1112  }
1113 
1115  return LockedAccess(const_cast<TypedPropertyNodeImpl*>(this), mAccessor, NoLock());
1116  }
1117 
1119  return LockedAccess(this, mAccessor, NoLock());
1120  }
1121 
1122 public:
1123 
1124  void setFromJSON(const json::Value& json, const Duration& timeout) override {
1125  if(this->isReadOnly())
1126  MIRA_THROW(XLogical, "Cannot set value of read-only property.");
1127 
1128  JSONDeserializer ds(json);
1129 
1130  // atomic types do not need to call synchronize()
1131  if constexpr(!Base::template mayHaveChildNodes<T>()) {
1132  ds.deserialize(*accessorAccess());
1133  return;
1134  }
1135 
1136  auto root = this->getRootNode();
1137  auto lock = this->tryGetLock(root, timeout);
1138  if (root && !lock.owns())
1139  MIRA_THROW(XIO, "PropertyNode is locked by another thread");
1140 
1141  auto nodeAccessorAccess = accessorAccess(NoLock());
1142  ds.deserialize(*nodeAccessorAccess);
1143  synchronize(*nodeAccessorAccess); // synchronizes this node and its children with the
1144  // actual underlying data representation that
1145  // might have been changed by the above deserialization
1146  }
1147 
1148  json::Value getAsJSON() const override {
1149  JSONSerializer s(true);
1150  return s.serialize(*accessorAccess());
1151  }
1152 
1153 public:
1154 
1155  void set(const value_type& newValue, const Duration& timeout) override {
1156  if(this->isReadOnly())
1157  MIRA_THROW(XLogical, "Cannot set value of read-only property.");
1158 
1159  // atomic types do not need to call synchronize()
1160  if constexpr(!Base::template mayHaveChildNodes<T>()) {
1161  (*accessorAccess()).set(newValue);
1162  return;
1163  }
1164 
1165  auto root = this->getRootNode();
1166  auto lock = this->tryGetLock(root, timeout);
1167  if (root && !lock.owns())
1168  MIRA_THROW(XIO, "PropertyNode is locked by another thread");
1169 
1170  auto nodeAccessorAccess = accessorAccess(NoLock());
1171  (*nodeAccessorAccess).set(newValue);
1172  synchronize(*nodeAccessorAccess); // synchronizes this node and its children with the
1173  // actual underlying data representation that
1174  // might have been changed by the above assignment
1175  }
1176 
1177  value_type get() const override {
1178  return (*accessorAccess()).get();
1179  }
1180 
1181 protected:
1182  friend class PropertySerializer;
1183 
1188  void update(AccessorType& value) {
1189  mAccessor = value;
1190  }
1191 public:
1192  void synchronize() override
1193  {
1194  auto lock = this->getLock();
1195  return synchronize(*this->accessorAccess(NoLock()));
1196  }
1197 private:
1198  void synchronize(AccessorType& nodeAccessor);
1199 private:
1200  AccessorType mAccessor;
1201 };
1202 
1204 
1205 // Support for remote property management
1206 
1227 {
1228 public:
1230  PropertyNode(info), mTypedNode(NULL) {}
1231 
1233  delete mTypedNode;
1234  }
1235 
1236 public:
1237 
1239  void addChild(PropertyNode* child, int index = -1) {
1240  PropertyNode::addChild(child, index);
1241  }
1242 
1243 public:
1244 
1246  template <typename T>
1248 
1249 private:
1250 
1252  PropertyNode* mTypedNode;
1253 };
1254 
1276 template <typename T>
1278 {
1279 public:
1281  typedef typename Base::value_type value_type;
1282 
1283 public:
1284 
1286  Base(*node), mNode(node) {}
1287 
1288 public:
1289  // implementation of PropertyNode that delegates to the "real"
1290  // RemotePropertyNode
1291  void setFromJSON(const json::Value& node, const Duration& timeout) override { mNode->setFromJSON(node, timeout); }
1292  json::Value getAsJSON() const override { return mNode->getAsJSON(); }
1293 
1294 public:
1295  // the following methods of PropertyNode must be delegated to the "real"
1296  // RemotePropertyNode, that has the parent and the children.
1297  PropertyNode* parent() override { return mNode->parent();}
1298  const PropertyNode* parent() const override { return mNode->parent(); }
1299  PropertyNode::NodeList& children() override { return mNode->children(); }
1300  const PropertyNode::NodeList& children() const override { return mNode->children(); }
1301  void synchronize() override {
1302  MIRA_THROW(XNotImplemented, "TypedRemotePropertyNode::synchronize() not implemented!");
1303  }
1304 
1305 public:
1306  // implementation of TypedPropertyNode
1307 
1308  void set(const value_type& value, const Duration& timeout) override
1309  {
1310  try {
1311  // serialize the value to json and set it remotely via setFromJSON()
1312  JSONSerializer s;
1313  json::Value jsonval = s.serialize(value);
1314  setFromJSON(jsonval, timeout);
1315  } catch(std::exception& ex) {
1316  MIRA_THROW(XIO, "Failed to convert value to json: " << ex.what())
1317  }
1318  }
1319 
1320  value_type get() const override
1321  {
1322  try {
1323  // get the value remotely via getAsJSON
1324  json::Value jsonval = getAsJSON();
1325  // and deserialize it into the value
1326  value_type value;
1327  JSONDeserializer ds(jsonval);
1328  ds.deserialize(value);
1329  return value;
1330  } catch(std::exception& ex) {
1331  MIRA_THROW(XIO, "Failed to obtain remote value: " << ex.what())
1332  }
1333  }
1334 
1335 private:
1337 };
1338 
1341 
1342 // implementations of the PropertyNode toTyped methods
1343 template <typename T>
1345 
1346  // try a direct cast to the desired type
1347  TypedPropertyNode<T>* node = dynamic_cast<TypedPropertyNode<T>*>(this);
1348  if(node!=NULL)
1349  return node; // success
1350 
1351  // if the above cast failed, the property could still be a remote property
1352  AbstractRemotePropertyNode* remoteNode = dynamic_cast<AbstractRemotePropertyNode*>(this);
1353  if(remoteNode!=NULL)
1354  return remoteNode->toTyped<T>();
1355 
1356  // otherwise we cannot cast
1357  MIRA_THROW(XBadCast, "Cannot cast PropertyNode which is of "
1358  "type '" << mType << "' to requested type '"
1359  << typeName<T>() << "'");
1360 }
1361 
1362 template <typename T>
1364  PropertyNode* This = const_cast<PropertyNode*>(this);
1365  return This->toTyped<T>();
1366 }
1367 
1369 
1370 template <typename T>
1372 {
1373  if(mTypedNode) {
1374  TypedPropertyNode<T>* node = dynamic_cast<TypedPropertyNode<T>*>(mTypedNode);
1375  if(node==NULL)
1376  MIRA_THROW(XBadCast, "Cannot cast PropertyNode which is of "
1377  "type '" << mType << "' to requested type '"
1378  << typeName<T>() << "'");
1379  return node;
1380  } else {
1381  if(mType != typeName<T>())
1382  MIRA_THROW(XBadCast, "Cannot cast remote PropertyNode which is of "
1383  "type '" << mType << "' to requested type '"
1384  << typeName<T>() << "'");
1385 
1387  mTypedNode = node;
1388 
1389  return node;
1390  }
1391 }
1392 
1394 
1395 } // namespace
1396 
1397 #endif
virtual void endAddChildren(PropertyNodeListenerList &listeners)
Serializer for serializing objects in JSON format.
Definition: JSONSerializer.h:95
This object can use object tracking internally, but the object tracking system&#39;s state remains unchan...
Definition: ReflectControlFlags.h:82
RootPropertyNode::LockType getLock()
Definition: PropertyNode.h:587
virtual void endRemoveChildren()=0
void deserialize(T &value)
Definition: JSONSerializer.h:436
const LockedAccess valueAccess() const
Definition: PropertyNode.h:775
LockedPropertyNodeAccess(NodeType *parent, const ValueType &ref)
Definition: PropertyNode.h:649
void fromList(const AttributeValueList &list)
Sets the property hints from the specified list of attribute/value pairs.
Definition: PropertyHint.h:115
const ValueType & operator*() const
Definition: PropertyNode.h:698
boost::interprocess::scoped_lock< RootPropertyNode::MutexType > lock
Definition: PropertyNode.h:637
Abstract base class for all derived property node classes.
Definition: PropertyNode.h:212
Base::value_type value_type
Definition: PropertyNode.h:1093
void removeAllChildren()
Removes all child nodes (without deleting them).
virtual ~PropertyNodeListener()
Definition: PropertyNode.h:448
Definition: PropertyNode.h:756
void setFromJSON(const json::Value &node, const Duration &timeout) override
Sets the value of the property, where the value is described as JSON value.
Definition: PropertyNode.h:1291
bool needLock
Definition: PropertyNode.h:636
std::string mID
the unique id of the property
Definition: PropertyNode.h:188
void registerListener(PropertyNodeListener *listener)
typename LockedAccess::NoLock NoLock
Definition: PropertyNode.h:1104
const PropertyNode * parent() const override
Returns the parent property node (or NULL, if this is a root node)
Definition: PropertyNode.h:1298
std::vector< PropertyNode * > NodeList
Definition: PropertyNode.h:217
Base::value_type value_type
Definition: PropertyNode.h:760
virtual void beginMoveChildren(PropertyNodeListenerList &listeners, int index, NodeList::iterator it, int count, int destination)
Caller must ensure to keep listeners locked between beginMoveChildren and endMoveChildren! ...
virtual PropertyNode * parent()
Returns the parent property node (or NULL, if this is a root node)
Definition: PropertyNode.h:234
tick_type milliseconds() const
Returns normalized number of milliseconds (0..999)
Definition: Time.h:285
Type trait that evaluates to true if a type is copy assignable, false otherwise.
Definition: IsCopyAssignable.h:71
Definition: PropertyNode.h:74
virtual void beginRemoveChildren(const PropertyNode *node, int index, int count)=0
LockedPropertyNodeAccess(NodeType *parent, const ValueType &ref, NoLock)
Definition: PropertyNode.h:652
virtual const PropertyNode * parent() const
Returns the parent property node (or NULL, if this is a root node)
Definition: PropertyNode.h:237
const PropertyNode * findChildNode(const std::vector< std::string > &ids, std::size_t level=0) const
Searches for a child property node (which may also be a child of a child of a child, etc).
Special derived class of PropertyNode, that allows to handle "remote properties" transparently.
Definition: PropertyNode.h:1226
virtual void setFromString(const std::string &value, const Duration &timeout=Duration::milliseconds(100))
Sets the value of the property, where the value is given as string.
ValueType * PointerType
Definition: PropertyNode.h:719
typename Base::NoLock NoLock
Definition: PropertyNode.h:688
ValueType & operator*()
Definition: PropertyNode.h:745
const ValueType & operator*() const
Definition: PropertyNode.h:732
PropertyNode * parent() override
Returns the parent property node (or NULL, if this is a root node)
Definition: PropertyNode.h:1297
LockedPropertyNodeAccess(NodeType *parent, const PointerType &ref, NoLock)
Definition: PropertyNode.h:694
TypedPropertyNode(const std::string &id, const std::string &name, const std::string &comment, bool isReadOnly, bool isVolatile)
Definition: PropertyNode.h:562
TypedPropertyNodeImpl(const std::string &id, const std::string &name, const std::string &comment, const value_type &value, bool isReadOnly, bool isVolatile)
Definition: PropertyNode.h:977
LockedPropertyNodeAccess< TypedPropertyNodeImplGetSetMixinBase< T >, value_type, true, IsCopyAssignable< value_type >::value > LockedAccess
Definition: PropertyNode.h:771
json::Value getAsJSON() const override
Returns the value of the property as JSON value.
Definition: PropertyNode.h:1148
void reflectCommon(Reflector &r)
Definition: PropertyNode.h:108
LockedPropertyNodeAccess(NodeType *parent, const PointerType &ref)
Definition: PropertyNode.h:691
specialize cv::DataType for our ImgPixel and inherit from cv::DataType<Vec>
Definition: IOService.h:67
typename LockedAccess::NoLock NoLock
Definition: PropertyNode.h:773
std::string Typename
Definition: Typename.h:60
void setName(const std::string &name)
For internal use by PropertySerializer only: Overrides the name of the property.
Definition: PropertyNode.h:179
typename Base::NoLock NoLock
Definition: PropertyNode.h:722
virtual void beginMoveChildren(const PropertyNode *node, int index, int count, int destination)=0
Base::value_type value_type
Definition: PropertyNode.h:884
typename LockedAccess::NoLock NoLock
Definition: PropertyNode.h:986
virtual ~AbstractRemotePropertyNode()
Definition: PropertyNode.h:1232
#define MIRA_SPLIT_REFLECT_MEMBER
Macro that insert a class member reflect() method just splitting reflection into a reflectRead() and ...
Definition: SplitReflect.h:189
const LockedAccess pointerAccess() const
Definition: PropertyNode.h:988
const LockedAccess pointerAccess(NoLock) const
Definition: PropertyNode.h:996
LockedAccess valueAccess()
Definition: PropertyNode.h:779
boost::recursive_timed_mutex MutexType
Definition: PropertyNode.h:507
Type trait to check if a class is copy assignable.
Provides property hints and attributes.
LockedAccess pointerAccess(NoLock)
Definition: PropertyNode.h:1000
json::Value getAsJSON() const override
Returns the value of the property as JSON value.
Definition: PropertyNode.h:1292
Definition: PropertyNode.h:445
virtual NodeList & children()
Returns a vector with all child property nodes.
Definition: PropertyNode.h:240
virtual void synchronize()=0
Synchronize with the reflected object (update PropertyNode when reflected content changes) ...
Grants thread-safe access to an object (the Protectee) that should be protected from concurrent acces...
Definition: ScopedAccess.h:119
const ValueType & r
Definition: PropertyNode.h:635
Holds a boost::function object to a special setter function that must meet the signature "void method...
Definition: GetterSetter.h:395
Definition: PropertyNode.h:642
std::list< std::pair< std::string, std::string > > AttributeValueList
Definition: PropertyHint.h:86
typename Base::NoLock NoLock
Definition: PropertyNode.h:646
json::Value getAsJSON() const override
Returns the value of the property as JSON value.
Definition: PropertyNode.h:917
virtual void endRemoveChildren(PropertyNodeListenerList &listeners)
Get compiler and platform independent typenames.
Definition: PropertyNode.h:617
Provides MIRA_SPLIT_REFLECT macros.
void removeChild(int index)
Removes child at specific index (without deleting it).
Definition: PropertyNode.h:376
NodeType * p
Definition: PropertyNode.h:634
bool has(const std::string &attribute) const
Returns true if the specified attribute exists.
Definition: PropertyHint.h:158
AttributeValueList toList() const
Returns the attributes/value list containing the property hints.
Definition: PropertyHint.h:110
void serialize(const std::string &name, const T &value, const std::string &comment="")
Serializes the specified object value under the given name.
Definition: Serializer.h:204
PropertyNode(const std::string &id, const std::string &name, const std::string &comment, const Typename &type, bool isReadOnly, bool isVolatile)
Definition: PropertyNode.h:223
void addChild(PropertyNode *child, int index=-1)
Adds the specified property node as child node.
Definition: PropertyNode.h:1239
uint8 VersionType
Definition: ReflectorInterface.h:72
#define MIRA_THROW(ex, msg)
Macro for throwing an exception.
Definition: Exception.h:78
void setVolatile(bool isVolatile)
Definition: PropertyNode.h:183
A property hint gives optional instructions to the property editor, i.e.
Definition: PropertyHint.h:82
void moveChild(int index, int destination)
Moves a child node from index to before element at destination.
Definition: PropertyNode.h:409
PropertyNode::NodeList & children() override
Returns a vector with all child property nodes.
Definition: PropertyNode.h:1299
LockedPropertyNodeAccessCommon(NodeType *parent, const ValueType &ref)
Definition: PropertyNode.h:619
LockedPropertyNodeAccess< TypedPropertyNodeImpl< T * >, value_type > LockedAccess
Definition: PropertyNode.h:985
LockType tryGetLock(const Duration &timeout=Duration::milliseconds(10))
In constrast to getLock(), this will return after a defined time even if the lock cannot be acquired ...
LockedAccess accessorAccess()
Definition: PropertyNode.h:1110
PropertyNodeInfo & operator=(const PropertyNodeInfo &info)
Definition: PropertyNode.h:92
void addChild(PropertyNode *child, int index=-1)
PropertyNodeInfo()
Definition: PropertyNode.h:77
LockedAccess accessorAccess(NoLock)
Definition: PropertyNode.h:1118
const PropertyNode::NodeList & children() const override
Returns a vector with all child property nodes.
Definition: PropertyNode.h:1300
const Typename & type() const
Returns the type of this property as Typename.
Definition: PropertyNode.h:151
Special TypedPropertyNode for remote properties.
Definition: PropertyNode.h:1277
Deserializer for serializing objects from JSON format.
Definition: JSONSerializer.h:406
T getHint(const std::string &attribute, const T &defaultValue=T()) const
Returns the specified value for the given property hint attribute.
Definition: PropertyNode.h:159
LockType getLock()
Create lock on the PropertyNode tree.
Base::value_type value_type
Definition: PropertyNode.h:855
const LockedAccess accessorAccess(NoLock) const
Definition: PropertyNode.h:1114
Base::value_type value_type
Definition: PropertyNode.h:823
json::Value getAsJSON() const override
Returns the value of the property as JSON value.
Definition: PropertyNode.h:1028
Use this class to represent time durations.
Definition: Time.h:106
A special node that acts only as (empty) root node for a property tree.
Definition: PropertyNode.h:463
friend LockedAccess
Definition: PropertyNode.h:772
typename Base::NoLock NoLock
Definition: PropertyNode.h:885
PropertyNodeInfo(const PropertyNodeInfo &info)
Definition: PropertyNode.h:86
LockedPropertyNodeAccess(NodeType *parent, const PointerType &ref)
Definition: PropertyNode.h:725
static constexpr bool mayHaveChildNodes()
Definition: PropertySerializer.h:306
boost::interprocess::scoped_lock< MutexType > LockType
Definition: PropertyNode.h:508
void synchronize() override
Synchronize with the reflected object (update PropertyNode when reflected content changes) ...
Definition: PropertyNode.h:1068
Implementation of TypedPropertyNode.
Definition: PropertyNode.h:880
std::string fullID(PropertyNode *p=NULL) const
Returns the full qualified ID of this property, including the names of the parent properties separate...
Definition: PropertyNode.h:293
LockedAccess valueAccess(NoLock)
Definition: PropertyNode.h:787
void update(T &value)
Is called by PropertySerializer to update the internal representation of the value of the property...
Definition: PropertyNode.h:804
void update(AccessorType &value)
Is called by PropertySerializer to update the internal representation of the value of the property...
Definition: PropertyNode.h:1188
bool isReadOnly() const
Returns true, if this property is read-only and hence, can not be modified.
Definition: PropertyNode.h:169
A special PropertyReflector that creates a PropertyNode for each reflected property.
Definition: PropertySerializer.h:68
void update(T *value)
Is called by PropertySerializer to update the internal representation of the value of the property...
Definition: PropertyNode.h:1064
const LockedAccess accessorAccess() const
Definition: PropertyNode.h:1106
virtual RootPropertyNode * getRootNode()
PropertyNode(const PropertyNodeInfo &info)
Definition: PropertyNode.h:220
void setFromJSON(const json::Value &json, const Duration &timeout) override
Sets the value of the property, where the value is described as JSON value.
Definition: PropertyNode.h:1005
Base::value_type value_type
Definition: PropertyNode.h:1281
TypedPropertyNodeImpl(const std::string &id, const std::string &name, const std::string &comment, const AccessorType &value, bool isReadOnly, bool isVolatile)
Definition: PropertyNode.h:1095
bool mIsVolatile
indicates whether the property is volatile
Definition: PropertyNode.h:194
RootPropertyNode::LockType tryGetLock(RootPropertyNode *root, const Duration &timeout)
Definition: PropertyNode.h:591
virtual void beginRemoveChildren(PropertyNodeListenerList &listeners, int index, NodeList::iterator it, int count)
Caller must ensure to keep listeners locked between beginRemoveChildren and endRemoveChildren! ...
TypedPropertyNodeImplGetSetMixin(const std::string &id, const std::string &name, const std::string &comment, value_type &value, bool isReadOnly, bool isVolatile)
Definition: PropertyNode.h:857
RootPropertyNode::LockType tryGetLock(const Duration &timeout)
Definition: PropertyNode.h:595
LockedPropertyNodeAccessCommon(NodeType *parent, const ValueType &ref, NoLock)
Definition: PropertyNode.h:630
ProtecteeMixin< PropertyNodeListenerList > ProtectedListenerList
Definition: PropertyNode.h:499
json_spirit::mValue Value
A value is an abstract description of data in JSON (underlying data can either be one of the JSON bas...
Definition: JSON.h:174
The Accessor class is used as an adapter to reduce the code bloat within the reflection and serializa...
Definition: Accessor.h:244
Partial Implementations of the get/set of TypedPropertyNode specialized for normal classes / for clas...
Definition: PropertyNode.h:819
const std::string & comment() const
Returns the comment that is associated with this property.
Definition: PropertyNode.h:148
void setFromJSON(const json::Value &json, const Duration &timeout) override
Sets the value of the property, where the value is described as JSON value.
Definition: PropertyNode.h:1124
void synchronize() override
Synchronize with the reflected object (update PropertyNode when reflected content changes) ...
Definition: PropertyNode.h:1301
ScopedAccess< ProtectedListenerList > getListeners(bool alreadyLocked=false)
void setFromJSON(const json::Value &json, const Duration &timeout) override
Sets the value of the property, where the value is described as JSON value.
Definition: PropertyNode.h:893
void setValue(value_type &nodeValue, const value_type &newValue)
Definition: PropertyNode.h:832
virtual ~PropertyNode()
Base::value_type value_type
Definition: PropertyNode.h:975
Holds a boost::function object to a special getter function that must meet the signature "T method()"...
Definition: GetterSetter.h:87
void removeChildren(int index, int count)
Removes contiguous children, starting at index (without deleting them).
Definition: PropertyNode.h:382
void synchronize() override
Synchronize with the reflected object (update PropertyNode when reflected content changes) ...
Definition: PropertyNode.h:1192
void addChild(PropertyNode *child, int index=-1)
Adds the specified property node as child node.
virtual void beginAddChildren(PropertyNodeListenerList &listeners, int index, int count)
Caller must ensure to keep listeners locked between beginAddChildren and endAddChildren! ...
void synchronize() override
Synchronizes this node and its children with the the actual underlying data representation.
Definition: PropertyNode.h:954
T value_type
The type of the property.
Definition: PropertyNode.h:553
std::string mComment
the comment that is associated to the property
Definition: PropertyNode.h:190
virtual void setFromJSON(const json::Value &value, const Duration &timeout=Duration::milliseconds(100))=0
Sets the value of the property, where the value is described as JSON value.
bool mIsReadOnly
indicates whether the property is read-only
Definition: PropertyNode.h:193
void setValue(value_type &nodeValue, const value_type &newValue)
Definition: PropertyNode.h:793
ValueType & operator*()
Definition: PropertyNode.h:663
ValueType & operator*()
Definition: PropertyNode.h:705
LockedAccess pointerAccess()
Definition: PropertyNode.h:992
std::string mName
the name of the property (mostly equal to mID)
Definition: PropertyNode.h:189
TypedPropertyNodeImplGetSetMixinBase(const std::string &id, const std::string &name, const std::string &comment, value_type &value, bool isReadOnly, bool isVolatile)
Definition: PropertyNode.h:762
PropertyHint mHint
the specified property hints
Definition: PropertyNode.h:191
Typename mType
the type of the property
Definition: PropertyNode.h:192
AbstractRemotePropertyNode(const PropertyNodeInfo &info)
Definition: PropertyNode.h:1229
Grants thread-safe access to an object that should be protected from concurrent access.
TypedPropertyNode(const PropertyNodeInfo &info)
Definition: PropertyNode.h:557
virtual const NodeList & children() const
Returns a vector with all child property nodes.
Definition: PropertyNode.h:243
void removeChild(int index, NodeList::iterator it)
bool isVolatile() const
Returns true, if this property is volatile and hence, must be locked for access.
Definition: PropertyNode.h:172
RootPropertyNode::LockType getLock(RootPropertyNode *root)
Definition: PropertyNode.h:583
LockedPropertyNodeAccess< TypedPropertyNodeImpl< Accessor< Getter, Setter > >, AccessorType > LockedAccess
Definition: PropertyNode.h:1103
virtual void endMoveChildren(PropertyNodeListenerList &listeners)
virtual void endAddChildren()=0
void reflectWrite(Reflector &r)
Definition: PropertyNode.h:129
TypedPropertyNode< T > Base
Definition: PropertyNode.h:1280
PropertyNodeInfo(const std::string &id, const std::string &name, const std::string &comment, const Typename &type, bool isReadOnly, bool isVolatile)
Definition: PropertyNode.h:78
const std::string & name() const
Returns the name of this property as specified in the reflect() method.
Definition: PropertyNode.h:145
virtual std::string getAsString() const
Returns the value of the property as string.
TypedPropertyNode< T > * toTyped()
Casts this property node to a typed property node, or returns NULL if the types do not match...
Definition: PropertyNode.h:1344
TypedRemotePropertyNode(AbstractRemotePropertyNode *node)
Definition: PropertyNode.h:1285
bool hasHint(const std::string &attribute) const
Returns true if a hint with the specified attribute exists.
Definition: PropertyNode.h:164
void setValue(value_type &nodeValue, const value_type &newValue)
Definition: PropertyNode.h:864
Proxy class that is returned/set by the getter and setter methods of ChannelProperty.
Definition: ChannelProperty.h:154
RootPropertyNode * getRootNode() override
PropertyHint clone() const
Creates an explicit copy as replacement for the copy constructor.
Definition: PropertyHint.h:145
TypedPropertyNodeImpl(const std::string &id, const std::string &name, const std::string &comment, value_type &value, bool isReadOnly, bool isVolatile)
Definition: PropertyNode.h:887
TypedPropertyNode< T > * toTyped()
Specialized method that creates a TypedRemotePropertyNode.
Definition: PropertyNode.h:1371
T get(const std::string &attribute, const T &defaultValue=T()) const
Returns the specified value for the given attribute.
Definition: PropertyHint.h:175
virtual void beginAddChildren(const PropertyNode *node, int index, int count)=0
std::set< PropertyNodeListener * > PropertyNodeListenerList
Definition: PropertyNode.h:68
Typename typeName(bool cvqualify=true)
Returns a compiler and platform independent typename of T.
Definition: Typename.h:103
void unregisterListener(PropertyNodeListener *listener)
ValueType * PointerType
Definition: PropertyNode.h:684
Abstract base class for all typed property nodes.
Definition: PropertyNode.h:72
Serializer and Deserializer for JSON format.
const LockedAccess valueAccess(NoLock) const
Definition: PropertyNode.h:783
const ValueType & operator*() const
Definition: PropertyNode.h:656
virtual void endMoveChildren()=0
void reflectRead(Reflector &r)
Definition: PropertyNode.h:121
LockedPropertyNodeAccess(NodeType *parent, const PointerType &ref, NoLock)
Definition: PropertyNode.h:728
virtual json::Value getAsJSON() const =0
Returns the value of the property as JSON value.
const std::string & id() const
Returns the unique id of this property.
Definition: PropertyNode.h:142
Definition: PropertyNode.h:614
TypedPropertyNodeImplGetSetMixin(const std::string &id, const std::string &name, const std::string &comment, value_type &value, bool isReadOnly, bool isVolatile)
Definition: PropertyNode.h:825