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 
51 #include <serialization/adapters/std/pair>
54 #include <platform/Typename.h>
55 #include <thread/ScopedAccess.h>
56 #include <utils/IsCopyAssignable.h>
57 
58 namespace mira {
59 
61 
62 // forward declarations
63 class PropertySerializer;
64 class RootPropertyNode;
65 
67 typedef std::set<PropertyNodeListener*> PropertyNodeListenerList;
68 
69 template <typename T>
71 
73 {
74 public:
76  PropertyNodeInfo(const std::string& id, const std::string& name,
77  const std::string& comment, const Typename& type,
78  bool isReadOnly, bool isVolatile) :
82 
83  // special copy constructor, that clones the property hint
85  mID(info.mID), mName(info.mName), mComment(info.mComment),
86  mHint(info.mHint.clone()), mType(info.mType),
88 
89 public:
91  {
92  mID = info.mID;
93  mName = info.mName;
94  mComment = info.mComment;
95  mHint = info.mHint.clone();
96  mType = info.mType;
97  mIsReadOnly = info.mIsReadOnly;
98  mIsVolatile = info.mIsVolatile;
99 
100  return *this;
101  }
102 
103 public:
104 
105  template<typename Reflector>
106  void reflectCommon(Reflector& r)
107  {
108  serialization::VersionType v = r.version(2, this);
109  r.member("ID", mID, "");
110  r.member("Name", mName, "");
111  r.member("Comment", mComment, "");
112  r.member("Type", mType, "The typename");
113  r.member("IsReadOnly", mIsReadOnly, "");
114  if (v > 1)
115  r.member("IsVolatile", mIsVolatile, "");
116  }
117 
118  template<typename Reflector>
119  void reflectRead(Reflector& r)
120  {
121  reflectCommon(r);
123  r.member("Hint", hints, "The property hints", REFLECT_CTRLFLAG_TEMP_TRACKING);
124  }
125 
126  template<typename Reflector>
127  void reflectWrite(Reflector& r)
128  {
129  reflectCommon(r);
131  r.member("Hint", hints, "The property hints", REFLECT_CTRLFLAG_TEMP_TRACKING);
132  mHint.fromList(hints);
133  }
134 
136 
137 public:
138 
140  const std::string& id() const { return mID; }
141 
143  const std::string& name() const { return mName; }
144 
146  const std::string& comment() const { return mComment; }
147 
149  const Typename& type() const { return mType; }
150 
156  template <typename T>
157  T getHint(const std::string& attribute, const T& defaultValue = T()) const {
158  return mHint.get(attribute, defaultValue);
159  }
160 
162  bool hasHint(const std::string& attribute) const {
163  return mHint.has(attribute);
164  }
165 
167  bool isReadOnly() const {return mIsReadOnly;}
168 
170  bool isVolatile() const {return mIsVolatile;}
171 
173  void setName(const std::string& name) {
174  mName = name;
175  }
176 
177 protected:
178  std::string mID;
179  std::string mName;
180  std::string mComment;
183  bool mIsReadOnly;
184  bool mIsVolatile;
185 };
186 
203 {
204  friend class PropertySerializer; // needs to call addChild, etc
205 
206 public:
207  typedef std::vector<PropertyNode*> NodeList;
208 
209 public:
211  PropertyNodeInfo(info), mParent(NULL), mUpdated(true) {}
212 
213  PropertyNode(const std::string& id, const std::string& name,
214  const std::string& comment, const Typename& type,
215  bool isReadOnly, bool isVolatile) :
216  PropertyNodeInfo(id, name, comment, type, isReadOnly, isVolatile),
217  mParent(NULL), mUpdated(true) {}
218 
219  virtual ~PropertyNode();
220 
221 public:
222 
224  virtual PropertyNode* parent() { return mParent; }
225 
227  virtual const PropertyNode* parent() const { return mParent; }
228 
230  virtual NodeList& children() { return mChildren; }
231 
233  virtual const NodeList& children() const { return mChildren; }
234 
245  const PropertyNode* findChildNode(const std::vector<std::string>& ids,
246  std::size_t level = 0) const;
247 
252  PropertyNode* findChildNode(const std::vector<std::string>& ids,
253  std::size_t level = 0);
254 
266  const PropertyNode* findChildNode(const std::string& id) const;
267 
271  PropertyNode* findChildNode(const std::string& id);
272 
273 public:
274 
283  std::string fullID(PropertyNode* p = NULL) const
284  {
285  std::string s = id();
286  boost::algorithm::replace_all(s, ".", "\\");
287  for(const PropertyNode* n = parent(); n!=NULL && n!=p; n=n->parent())
288  s = boost::algorithm::replace_all_copy(n->id(), ".", "\\") + "." + s;
289  return s;
290  }
291 
292 public:
293 
298  virtual void setFromJSON(const json::Value& value) = 0;
299 
303  virtual json::Value getAsJSON() const = 0;
304 
305 public:
306 
310  virtual void setFromString(const std::string& value);
311 
315  virtual std::string getAsString() const;
316 
317 public:
318 
323  template <typename T>
324  TypedPropertyNode<T>* toTyped();
325 
330  template <typename T>
331  const TypedPropertyNode<T>* toTyped() const;
332 
333 public:
334 
338  virtual void synchronize() = 0;
339 
340 public:
341 
342  virtual RootPropertyNode* getRootNode();
343  virtual const RootPropertyNode* getRootNode() const;
344 
345 protected:
346 
352  void addChild(PropertyNode* child, int index = -1);
353 
358  void removeChild(int index) { removeChild(index, std::next(mChildren.begin(), index)); }
359 
364  void removeChildren(int index, int count) { removeChildren(index, std::next(mChildren.begin(), index), count); }
365 
371  void removeChild(int index, NodeList::iterator it);
372 
379  void removeChildren(int index, NodeList::iterator it, int count);
380 
385  void removeAllChildren();
386 
391  void moveChild(int index, int destination) {
392  moveChild(index, std::next(mChildren.begin(), index),
393  destination, std::next(mChildren.begin(), destination)); }
394 
400  void moveChild(int index, NodeList::iterator it, int destination, NodeList::iterator destIt);
401 
402 protected:
403 
405  virtual void beginAddChildren(PropertyNodeListenerList& listeners, int index, int count);
406  virtual void endAddChildren(PropertyNodeListenerList& listeners);
407 
409  virtual void beginRemoveChildren(PropertyNodeListenerList& listeners, int index, NodeList::iterator it, int count);
410  virtual void endRemoveChildren(PropertyNodeListenerList& listeners);
411 
413  virtual void beginMoveChildren(PropertyNodeListenerList& listeners, int index, NodeList::iterator it, int count, int destination);
414  virtual void endMoveChildren(PropertyNodeListenerList& listeners);
415 
416 private:
417 
419  PropertyNode* mParent;
420 
422  NodeList mChildren;
423 
425  bool mUpdated;
426 };
427 
429 
431 {
432 public:
434 
435  virtual void beginAddChildren(const PropertyNode* node, int index, int count) = 0;
436  virtual void endAddChildren() = 0;
437 
438  virtual void beginRemoveChildren(const PropertyNode* node, int index, int count) = 0;
439  virtual void endRemoveChildren() = 0;
440 
441  virtual void beginMoveChildren(const PropertyNode* node, int index, int count, int destination) = 0;
442  virtual void endMoveChildren() = 0;
443 };
444 
446 
449 // Deriving from PropertyNode allows to use PropertyNode's mParent to refer
450 // to an instance of RootPropertyNode, instead of adding another pointer in
451 // PropertyNode (in each instance, even though it is only required in the root).
452 {
453 public:
454 
456 
457 public:
458 
459  void addChild(PropertyNode* child, int index = -1);
460 
461  void removeChild(int index, NodeList::iterator it);
462  void removeChild(int index);
463  void removeAllChildren();
464 
465 private:
466 
467  // These are not meant to ever be called
468  virtual void setFromJSON(const json::Value& value);
469  virtual json::Value getAsJSON() const;
470  virtual void synchronize();
471 
472 protected:
473 
474  virtual RootPropertyNode* getRootNode();
475  virtual const RootPropertyNode* getRootNode() const;
476 
477 public:
478 
479  void registerListener(PropertyNodeListener* listener);
481 
482 public:
483 
484  void lock();
485  bool tryLock();
486  void unlock();
487 
488 protected:
489  friend class PropertyNode;
491 
492  ScopedAccess<ProtectedListenerList> getListeners(bool alreadyLocked = false);
493 
494 private:
495 
496  ProtectedListenerList mListeners;
497 
498  boost::timed_mutex mMutex;
499 };
500 
502 
515 template <typename T>
516 class TypedPropertyNode : public PropertyNode
517 {
518 public:
519 
521  typedef T value_type; // STL conform typedef
522 
523 public:
524 
526  PropertyNode(info) {
527  assert(info.type()==typeName<value_type>());
528  }
529 
530  TypedPropertyNode(const std::string& id, const std::string& name,
531  const std::string& comment, bool isReadOnly, bool isVolatile) :
533 
534 public:
535 
539  virtual void set(const value_type& value) = 0;
540 
544  virtual value_type get() const = 0;
545 
546 };
547 
549 
550 // LockedPropertyNodeAccess encapsulates locking all access to a TypedPropertyNode's
551 // internal reference/pointer/accessor.
552 // Optionally, when (const!) access is attempted but not possible (because the node is locked
553 // by another thread), it can return a backup of the previous value. The backup value is
554 // automatically updated with each successful read (const access).
555 
556 template <typename NodeType, typename ValueType>
557 class LockedPropertyNodeAccessCommon : boost::noncopyable {
558 protected:
559  LockedPropertyNodeAccessCommon(NodeType* parent, const ValueType& ref)
560  : p(parent), r(ref),
561  root(p->isVolatile() ? parent->getRootNode() : NULL),
562  lockFailed(false) {
563  if (root && !root->tryLock()) {
564  root = NULL;
565  lockFailed = true;
566  }
567  }
568 
570  std::swap(p, other.p);
571  std::swap(root, other.root);
572  std::swap(lockFailed, other.lockFailed);
573  }
574 
576  if (root)
577  root->unlock();
578  }
579 
580 public:
582  std::swap(p, other.p);
583  r = other.r;
584  std::swap(root, other.root);
585  std::swap(lockFailed, other.lockFailed);
586  return *this;
587  }
588 
589 protected:
590  NodeType* p;
591  const ValueType& r;
594 };
595 
596 template <typename NodeType, typename ValueType,
597  bool ValueTypePointer = false, bool UseBackup = false>
598 class LockedPropertyNodeAccess : public LockedPropertyNodeAccessCommon<NodeType, ValueType> {
599 
600 public:
601  LockedPropertyNodeAccess(NodeType* parent, const ValueType& ref)
602  : LockedPropertyNodeAccessCommon<NodeType, ValueType>(parent, ref) {}
603 
604 public:
605  const ValueType& operator*() const {
606  if (this->lockFailed) {
607  MIRA_THROW(XIO, "Property is not available (yet?)")
608  }
609 
610  return this->r;
611  }
612 
613  ValueType& operator*() {
614  if (this->lockFailed)
615  MIRA_THROW(XIO, "PropertyNode is locked");
616 
617  return const_cast<ValueType&>(this->r);
618  }
619 };
620 
621 // specialize for ValueTypePointer=false, UseBackup=true --> invalid
622 template <typename NodeType, typename ValueType>
623 class LockedPropertyNodeAccess<NodeType, ValueType, false, true> {
624  static_assert(sizeof(ValueType)==0, // assertion must depend on template parameter!
625  "LockedPropertyNodeAccess: combination ValueTypePointer=false, UseBackup=true not implemented");
626 };
627 
628 // specialize for ValueTypePointer=true, UseBackup=false
629 template <typename NodeType, typename ValueType>
630 class LockedPropertyNodeAccess<NodeType, ValueType, true, false>
631  : public LockedPropertyNodeAccessCommon<NodeType, ValueType*> {
632 
633 protected:
634  typedef ValueType* PointerType;
635 
636 public:
637  LockedPropertyNodeAccess(NodeType* parent, const PointerType& ref)
638  : LockedPropertyNodeAccessCommon<NodeType, PointerType>(parent, ref) {}
639 
640 public:
641  const ValueType& operator*() const {
642  if (this->lockFailed) {
643  MIRA_THROW(XIO, "Property is not available (yet?)")
644  }
645 
646  return *this->r;
647  }
648 
649  ValueType& operator*() {
650  if (this->lockFailed)
651  MIRA_THROW(XIO, "PropertyNode is locked");
652 
653  return const_cast<ValueType&>(*this->r);
654  }
655 };
656 
657 // specialize for ValueTypePointer=true, UseBackup=true
658 template <typename NodeType, typename ValueType>
659 class LockedPropertyNodeAccess<NodeType, ValueType, true, true>
660  : public LockedPropertyNodeAccessCommon<NodeType, ValueType*> {
661 
662 protected:
663  typedef ValueType* PointerType;
664 
665 public:
666  LockedPropertyNodeAccess(NodeType* parent, const PointerType& ref)
667  : LockedPropertyNodeAccessCommon<NodeType, PointerType>(parent, ref) {
668  if (this->root)
669  this->p->mBackupValue.reset(new ValueType(*this->r));
670  }
671 
672 public:
673  const ValueType& operator*() const {
674  if (this->lockFailed) {
675 
676  if (this->p->mBackupValue)
677  return *this->p->mBackupValue;
678 
679  MIRA_THROW(XIO, "Property is not available (yet?)")
680  }
681 
682  return *this->r;
683  }
684 
685  ValueType& operator*() {
686  if (this->lockFailed)
687  MIRA_THROW(XIO, "PropertyNode is locked");
688 
689  return const_cast<ValueType&>(*this->r);
690  }
691 };
692 
694 
695 template <typename T>
697 {
698  typedef TypedPropertyNode<T> Base;
699 public:
700  typedef typename Base::value_type value_type;
701 public:
702  TypedPropertyNodeImplGetSetMixinBase(const std::string& id, const std::string& name,
703  const std::string& comment, value_type& value,
704  bool isReadOnly, bool isVolatile) :
705  Base(id, name, comment, isReadOnly, isVolatile), mValue(&value) {}
706 
707 protected:
708  // all access to mValue (except update()) goes through LockedAccess,
709  // ensures locking the PropertyNode if required
712  friend LockedAccess;
713 
714  const LockedAccess value() const {
715  return LockedAccess(const_cast<TypedPropertyNodeImplGetSetMixinBase*>(this), mValue);
716  }
717 
719  return LockedAccess(this, mValue);
720  }
721 
722 protected:
723 
724  void setValue(const value_type& value) {
725  *this->value() = value;
726  }
727 
728 protected:
729  friend class PropertySerializer;
730 
735  void update(T& value) {
736  mValue = &value;
737  }
738 
739 private:
740  value_type* mValue;
741  std::unique_ptr<value_type> mBackupValue; // value_type may not be default constructible
742 };
743 
749 template <typename T, bool /* = true */>
751 {
753 public:
754  typedef typename Base::value_type value_type;
755 public:
756  TypedPropertyNodeImplGetSetMixin(const std::string& id, const std::string& name,
757  const std::string& comment, value_type& value,
758  bool isReadOnly, bool isVolatile) :
760 
761 protected:
762 
763  void setValue(const value_type& value) {
772  }
773 
774 public:
775 
776  virtual value_type get() const {
777  return *Base::value();
778  }
779 };
780 
781 template <typename T>
783 {
785 public:
786  typedef typename Base::value_type value_type;
787 public:
788  TypedPropertyNodeImplGetSetMixin(const std::string& id, const std::string& name,
789  const std::string& comment, value_type& value,
790  bool isReadOnly, bool isVolatile) :
792 
793 protected:
794 
795  void setValue(const value_type& value) {
796  MIRA_THROW(XLogical, "Cannot set value of property, since the underlying class does not provide an assignment operator");
797  }
798 
799 public:
800 
801  virtual value_type get() const {
802  MIRA_THROW(XLogical, "Cannot get value of property, since the underlying class does not provide an assignment operator");
803  }
804 };
805 
810 template <typename T>
811 class TypedPropertyNodeImpl : public TypedPropertyNodeImplGetSetMixin<T,IsCopyAssignable<T>::value>
812 {
814 public:
815  typedef typename Base::value_type value_type;
816 public:
817  TypedPropertyNodeImpl(const std::string& id, const std::string& name,
818  const std::string& comment, value_type& value,
819  bool isReadOnly, bool isVolatile) :
821 public:
822 
823  virtual void setFromJSON(const json::Value& node) {
824  if(this->isReadOnly())
825  MIRA_THROW(XLogical, "Cannot set value of read-only property.");
826 
827  JSONDeserializer ds(node);
828  ds.deserialize(*this->value());
829  synchronize(); // synchronizes this node and its children with the
830  // actual underlying data representation that
831  // might have been changed by the above deserialization
832  }
833 
834  virtual json::Value getAsJSON() const {
835  JSONSerializer s(true);
836  return s.serialize(*this->value());
837  }
838 
839 public:
840 
841  virtual void set(const value_type& value) {
842  if(this->isReadOnly())
843  MIRA_THROW(XLogical, "Cannot set value of read-only property.");
844 
846  synchronize(); // synchronizes this node and its children with the
847  // actual underlying data representation that
848  // might have been changed by the above assignment
849  }
850 
851  // implemented in GetSetMixin
852  //virtual value_type get() const;
853 
854 private:
855 
860  virtual void synchronize();
861 };
862 
864 
869 template <typename T>
871 {
872  typedef TypedPropertyNode<T*> Base;
873 public:
874  typedef typename Base::value_type value_type;
875 public:
876  TypedPropertyNodeImpl(const std::string& id, const std::string& name,
877  const std::string& comment, const value_type& value,
878  bool isReadOnly, bool isVolatile) :
879  Base(id, name, comment, isReadOnly, isVolatile), mPointer(value) {}
880 
881 protected:
882  // all access to mPointer (except update()) goes through LockedAccess,
883  // ensures locking if required
885 
886  const LockedAccess pointer() const {
887  return LockedAccess(const_cast<TypedPropertyNodeImpl*>(this), mPointer);
888  }
889 
891  return LockedAccess(this, mPointer);
892  }
893 
894 public:
895  virtual void setFromJSON(const json::Value& node) {
896  if(this->isReadOnly())
897  MIRA_THROW(XLogical, "Cannot set value of read-only property.");
898 
899  JSONDeserializer ds(node);
900  ds.deserialize(*pointer());
901  synchronize(); // synchronizes this node and its children with the
902  // actual underlying data representation that
903  // might have been changed by the above deserialization
904  }
905  virtual json::Value getAsJSON() const {
906  JSONSerializer s(true);
907  return s.serialize(*pointer());
908  }
909 public:
910  virtual void set(const value_type& value) {
911  if(this->isReadOnly())
912  MIRA_THROW(XLogical, "Cannot set value of read-only property.");
913 
914  *pointer() = value;
915  synchronize(); // synchronizes this node and its children with the
916  // actual underlying data representation that
917  // might have been changed by the above assignment
918  }
919  virtual value_type get() const {
920  return *pointer();
921  }
922 protected:
923  friend class PropertySerializer;
924 
929  void update(T* value) {
930  mPointer = value;
931  }
932 private:
933  virtual void synchronize();
934 private:
935  value_type mPointer;
936 };
937 
939 
944 template <typename Getter, typename Setter>
946  public TypedPropertyNode<typename Accessor<Getter,Setter>::value_type>
947 {
948  typedef typename Accessor<Getter,Setter>::value_type T;
950  typedef TypedPropertyNode<T> Base;
951 public:
952  typedef typename Base::value_type value_type;
953 public:
954  TypedPropertyNodeImpl(const std::string& id, const std::string& name,
955  const std::string& comment, const AccessorType& value,
956  bool isReadOnly, bool isVolatile) :
957  Base(id, name, comment, isReadOnly, isVolatile), mAccessor(value) {}
958 
959 protected:
960  // all access to mAccessor (except update()) goes through LockedAccess,
961  // ensures locking if required
963 
964  const LockedAccess accessor() const {
965  return LockedAccess(const_cast<TypedPropertyNodeImpl*>(this), mAccessor);
966  }
967 
969  return LockedAccess(this, mAccessor);
970  }
971 
972 public:
973 
974  virtual void setFromJSON(const json::Value& node) {
975  if(this->isReadOnly())
976  MIRA_THROW(XLogical, "Cannot set value of read-only property.");
977 
978  JSONDeserializer ds(node);
979  ds.deserialize(*accessor());
980  synchronize(); // synchronizes this node and its children with the
981  // actual underlying data representation that
982  // might have been changed by the above deserialization
983  }
984 
985  virtual json::Value getAsJSON() const {
986  JSONSerializer s(true);
987  return s.serialize(*accessor());
988  }
989 
990 public:
991 
992  virtual void set(const value_type& value) {
993  if(this->isReadOnly())
994  MIRA_THROW(XLogical, "Cannot set value of read-only property.");
995 
996  (*accessor()).set(value);
997  synchronize(); // synchronizes this node and its children with the
998  // actual underlying data representation that
999  // might have been changed by the above assignment
1000  }
1001 
1002  virtual value_type get() const {
1003  return (*accessor()).get();
1004  }
1005 
1006 protected:
1007  friend class PropertySerializer;
1008 
1014  mAccessor = value;
1015  }
1016 
1017 private:
1018  virtual void synchronize();
1019 private:
1020  AccessorType mAccessor;
1021 };
1022 
1024 
1025 // Support for remote property management
1026 
1047 {
1048 public:
1050  PropertyNode(info), mTypedNode(NULL) {}
1051 
1053  delete mTypedNode;
1054  }
1055 
1056 public:
1057 
1059  void addChild(PropertyNode* child, int index = -1) {
1060  PropertyNode::addChild(child, index);
1061  }
1062 
1063 public:
1064 
1066  template <typename T>
1068 
1069 private:
1070 
1072  PropertyNode* mTypedNode;
1073 };
1074 
1096 template <typename T>
1098 {
1099 public:
1101  typedef typename Base::value_type value_type;
1102 
1103 public:
1104 
1106  Base(*node), mNode(node) {}
1107 
1108 public:
1109  // implementation of PropertyNode that delegates to the "real"
1110  // RemotePropertyNode
1111  virtual void setFromJSON(const json::Value& node) { mNode->setFromJSON(node); }
1112  virtual json::Value getAsJSON() const { return mNode->getAsJSON(); }
1113 
1114 public:
1115  // the following methods of PropertyNode must be delegated to the "real"
1116  // RemotePropertyNode, that has the parent and the children.
1117  virtual PropertyNode* parent() { return mNode->parent();}
1118  virtual const PropertyNode* parent() const { return mNode->parent(); }
1119  virtual PropertyNode::NodeList& children() { return mNode->children(); }
1120  virtual const PropertyNode::NodeList& children() const { return mNode->children(); }
1121  virtual void synchronize() {
1122  MIRA_THROW(XNotImplemented, "TypedRemotePropertyNode::synchronize() not implemented!");
1123  }
1124 
1125 public:
1126  // implementation of TypedPropertyNode
1127 
1128  virtual void set(const value_type& value)
1129  {
1130  try {
1131  // serialize the value to json and set it remotely via setFromJSON()
1132  JSONSerializer s;
1133  json::Value jsonval = s.serialize(value);
1134  setFromJSON(jsonval);
1135  } catch(std::exception& ex) {
1136  MIRA_THROW(XIO, "Failed to convert value to json: " << ex.what())
1137  }
1138  }
1139 
1140  virtual value_type get() const
1141  {
1142  try {
1143  // get the value remotely via getAsJSON
1144  json::Value jsonval = getAsJSON();
1145  // and deserialize it into the value
1146  value_type value;
1147  JSONDeserializer ds(jsonval);
1148  ds.deserialize(value);
1149  return value;
1150  } catch(std::exception& ex) {
1151  MIRA_THROW(XIO, "Failed to obtain remote value: " << ex.what())
1152  }
1153  }
1154 
1155 private:
1157 };
1158 
1161 
1162 // implementations of the PropertyNode toTyped methods
1163 template <typename T>
1165 
1166  // try a direct cast to the desired type
1167  TypedPropertyNode<T>* node = dynamic_cast<TypedPropertyNode<T>*>(this);
1168  if(node!=NULL)
1169  return node; // success
1170 
1171  // if the above cast failed, the property could still be a remote property
1172  AbstractRemotePropertyNode* remoteNode = dynamic_cast<AbstractRemotePropertyNode*>(this);
1173  if(remoteNode!=NULL)
1174  return remoteNode->toTyped<T>();
1175 
1176  // otherwise we cannot cast
1177  MIRA_THROW(XBadCast, "Cannot cast PropertyNode which is of "
1178  "type '" << mType << "' to requested type '"
1179  << typeName<T>() << "'");
1180 }
1181 
1182 template <typename T>
1184  PropertyNode* This = const_cast<PropertyNode*>(this);
1185  return This->toTyped<T>();
1186 }
1187 
1189 
1190 template <typename T>
1192 {
1193  if(mTypedNode) {
1194  TypedPropertyNode<T>* node = dynamic_cast<TypedPropertyNode<T>*>(mTypedNode);
1195  if(node==NULL)
1196  MIRA_THROW(XBadCast, "Cannot cast PropertyNode which is of "
1197  "type '" << mType << "' to requested type '"
1198  << typeName<T>() << "'");
1199  return node;
1200  } else {
1201  if(mType != typeName<T>())
1202  MIRA_THROW(XBadCast, "Cannot cast remote PropertyNode which is of "
1203  "type '" << mType << "' to requested type '"
1204  << typeName<T>() << "'");
1205 
1207  mTypedNode = node;
1208 
1209  return node;
1210  }
1211 }
1212 
1214 
1215 } // namespace
1216 
1217 #endif
Serializer for serializing objects in JSON format.
Definition: JSONSerializer.h:93
This object can use object tracking internally, but the object tracking system&#39;s state remains unchan...
Definition: ReflectControlFlags.h:82
virtual void setFromJSON(const json::Value &node)
Sets the value of the property, where the value is described as JSON value.
Definition: PropertyNode.h:895
virtual void endRemoveChildren()=0
void deserialize(T &value)
Definition: JSONSerializer.h:427
LockedPropertyNodeAccess(NodeType *parent, const ValueType &ref)
Definition: PropertyNode.h:601
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:641
Abstract base class for all derived property node classes.
Definition: PropertyNode.h:202
Base::value_type value_type
Definition: PropertyNode.h:952
virtual ~PropertyNodeListener()
Definition: PropertyNode.h:433
Definition: PropertyNode.h:696
std::string mID
the unique id of the property
Definition: PropertyNode.h:178
void registerListener(PropertyNodeListener *listener)
void setValue(const value_type &value)
Definition: PropertyNode.h:763
LockedAccess pointer()
Definition: PropertyNode.h:890
std::vector< PropertyNode * > NodeList
Definition: PropertyNode.h:207
Base::value_type value_type
Definition: PropertyNode.h:700
virtual PropertyNode * parent()
Returns the parent property node (or NULL, if this is a root node)
Definition: PropertyNode.h:224
Type trait that evaluates to true if a type is copy assignable, false otherwise.
Definition: IsCopyAssignable.h:71
Definition: PropertyNode.h:72
virtual void beginRemoveChildren(const PropertyNode *node, int index, int count)=0
virtual const PropertyNode * parent() const
Returns the parent property node (or NULL, if this is a root node)
Definition: PropertyNode.h:227
Special derived class of PropertyNode, that allows to handle "remote properties" transparently.
Definition: PropertyNode.h:1046
virtual void setFromJSON(const json::Value &node)
Sets the value of the property, where the value is described as JSON value.
Definition: PropertyNode.h:1111
ValueType * PointerType
Definition: PropertyNode.h:663
ValueType & operator*()
Definition: PropertyNode.h:685
virtual PropertyNode::NodeList & children()
Returns a vector with all child property nodes.
Definition: PropertyNode.h:1119
const ValueType & operator*() const
Definition: PropertyNode.h:673
virtual void setFromJSON(const json::Value &value)=0
Sets the value of the property, where the value is described as JSON value.
TypedPropertyNode(const std::string &id, const std::string &name, const std::string &comment, bool isReadOnly, bool isVolatile)
Definition: PropertyNode.h:530
TypedPropertyNodeImpl(const std::string &id, const std::string &name, const std::string &comment, const value_type &value, bool isReadOnly, bool isVolatile)
Definition: PropertyNode.h:876
LockedPropertyNodeAccess< TypedPropertyNodeImplGetSetMixinBase< T >, value_type, true, IsCopyAssignable< value_type >::value > LockedAccess
Definition: PropertyNode.h:711
void reflectCommon(Reflector &r)
Definition: PropertyNode.h:106
LockedPropertyNodeAccess(NodeType *parent, const PointerType &ref)
Definition: PropertyNode.h:637
specialize cv::DataType for our ImgPixel and inherit from cv::DataType<Vec>
Definition: IOService.h:67
void setValue(const value_type &value)
Definition: PropertyNode.h:795
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:173
virtual void beginMoveChildren(const PropertyNode *node, int index, int count, int destination)=0
Base::value_type value_type
Definition: PropertyNode.h:815
LockedPropertyNodeAccessCommon & operator=(LockedPropertyNodeAccessCommon &&other) noexcept
Definition: PropertyNode.h:581
void setValue(const value_type &value)
Definition: PropertyNode.h:724
virtual ~AbstractRemotePropertyNode()
Definition: PropertyNode.h:1052
#define MIRA_SPLIT_REFLECT_MEMBER
Macro that insert a class member reflect() method just splitting reflection into a reflectRead() and ...
Definition: SplitReflect.h:238
Type trait to check if a class is copy assignable.
Provides property hints and attributes.
Definition: PropertyNode.h:430
virtual NodeList & children()
Returns a vector with all child property nodes.
Definition: PropertyNode.h:230
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:591
Holds a boost::function object to a special setter function that must meet the signature "void method...
Definition: GetterSetter.h:395
Definition: PropertyNode.h:598
virtual json::Value getAsJSON() const
Returns the value of the property as JSON value.
Definition: PropertyNode.h:985
std::list< std::pair< std::string, std::string > > AttributeValueList
Definition: PropertyHint.h:86
Get compiler and platform independent typenames.
Provides MIRA_SPLIT_REFLECT macros.
void removeChild(int index)
Removes child at specific index (without deleting it).
Definition: PropertyNode.h:358
NodeType * p
Definition: PropertyNode.h:590
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:213
void addChild(PropertyNode *child, int index=-1)
Adds the specified property node as child node.
Definition: PropertyNode.h:1059
uint8 VersionType
Definition: ReflectorInterface.h:72
#define MIRA_THROW(ex, msg)
Macro for throwing an exception.
Definition: Exception.h:81
A property hint gives optional instructions to the property editor, i.e.
Definition: PropertyHint.h:82
virtual const PropertyNode::NodeList & children() const
Returns a vector with all child property nodes.
Definition: PropertyNode.h:1120
void moveChild(int index, int destination)
Moves a child node from index to before element at destination.
Definition: PropertyNode.h:391
virtual void synchronize()
Synchronize with the reflected object (update PropertyNode when reflected content changes) ...
Definition: PropertyNode.h:1121
LockedPropertyNodeAccessCommon(NodeType *parent, const ValueType &ref)
Definition: PropertyNode.h:559
LockedPropertyNodeAccess< TypedPropertyNodeImpl< T * >, value_type > LockedAccess
Definition: PropertyNode.h:884
virtual void setFromJSON(const json::Value &node)
Sets the value of the property, where the value is described as JSON value.
Definition: PropertyNode.h:974
PropertyNodeInfo & operator=(const PropertyNodeInfo &info)
Definition: PropertyNode.h:90
void addChild(PropertyNode *child, int index=-1)
PropertyNodeInfo()
Definition: PropertyNode.h:75
const Typename & type() const
Returns the type of this property as Typename.
Definition: PropertyNode.h:149
Special TypedPropertyNode for remote properties.
Definition: PropertyNode.h:1097
Deserializer for serializing objects from JSON format.
Definition: JSONSerializer.h:400
T getHint(const std::string &attribute, const T &defaultValue=T()) const
Returns the specified value for the given property hint attribute.
Definition: PropertyNode.h:157
Base::value_type value_type
Definition: PropertyNode.h:786
Base::value_type value_type
Definition: PropertyNode.h:754
PropertyHint type(const std::string &t)
Sets the attribute "type" to the specified value.
Definition: PropertyHint.h:295
bool lockFailed
Definition: PropertyNode.h:593
A special node that acts only as (empty) root node for a property tree.
Definition: PropertyNode.h:448
friend LockedAccess
Definition: PropertyNode.h:712
LockedAccess accessor()
Definition: PropertyNode.h:968
virtual void setFromJSON(const json::Value &node)
Sets the value of the property, where the value is described as JSON value.
Definition: PropertyNode.h:823
LockedAccess value()
Definition: PropertyNode.h:718
PropertyNodeInfo(const PropertyNodeInfo &info)
Definition: PropertyNode.h:84
virtual const PropertyNode * parent() const
Returns the parent property node (or NULL, if this is a root node)
Definition: PropertyNode.h:1118
LockedPropertyNodeAccess(NodeType *parent, const PointerType &ref)
Definition: PropertyNode.h:666
Implementation of TypedPropertyNode.
Definition: PropertyNode.h:811
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:283
void update(T &value)
Is called by PropertySerializer to update the internal representation of the value of the property...
Definition: PropertyNode.h:735
void update(AccessorType &value)
Is called by PropertySerializer to update the internal representation of the value of the property...
Definition: PropertyNode.h:1013
bool isReadOnly() const
Returns true, if this property is read-only and hence, can not be modified.
Definition: PropertyNode.h:167
A special PropertyReflector that creates a PropertyNode for each reflected property.
Definition: PropertySerializer.h:67
void update(T *value)
Is called by PropertySerializer to update the internal representation of the value of the property...
Definition: PropertyNode.h:929
PropertyNode(const PropertyNodeInfo &info)
Definition: PropertyNode.h:210
virtual json::Value getAsJSON() const
Returns the value of the property as JSON value.
Definition: PropertyNode.h:1112
Base::value_type value_type
Definition: PropertyNode.h:1101
TypedPropertyNodeImpl(const std::string &id, const std::string &name, const std::string &comment, const AccessorType &value, bool isReadOnly, bool isVolatile)
Definition: PropertyNode.h:954
bool mIsVolatile
indicates whether the property is volatile
Definition: PropertyNode.h:184
RootPropertyNode * root
Definition: PropertyNode.h:592
TypedPropertyNodeImplGetSetMixin(const std::string &id, const std::string &name, const std::string &comment, value_type &value, bool isReadOnly, bool isVolatile)
Definition: PropertyNode.h:788
ProtecteeMixin< PropertyNodeListenerList > ProtectedListenerList
Definition: PropertyNode.h:490
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:176
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:750
const std::string & comment() const
Returns the comment that is associated with this property.
Definition: PropertyNode.h:146
ScopedAccess< ProtectedListenerList > getListeners(bool alreadyLocked=false)
const LockedAccess value() const
Definition: PropertyNode.h:714
virtual json::Value getAsJSON() const
Returns the value of the property as JSON value.
Definition: PropertyNode.h:834
Base::value_type value_type
Definition: PropertyNode.h:874
virtual RootPropertyNode * getRootNode()
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:364
void addChild(PropertyNode *child, int index=-1)
Adds the specified property node as child node.
virtual PropertyNode * parent()
Returns the parent property node (or NULL, if this is a root node)
Definition: PropertyNode.h:1117
T value_type
The type of the property.
Definition: PropertyNode.h:521
std::string mComment
the comment that is associated to the property
Definition: PropertyNode.h:180
bool mIsReadOnly
indicates whether the property is read-only
Definition: PropertyNode.h:183
~LockedPropertyNodeAccessCommon()
Definition: PropertyNode.h:575
ValueType & operator*()
Definition: PropertyNode.h:613
ValueType & operator*()
Definition: PropertyNode.h:649
std::string mName
the name of the property (mostly equal to mID)
Definition: PropertyNode.h:179
TypedPropertyNodeImplGetSetMixinBase(const std::string &id, const std::string &name, const std::string &comment, value_type &value, bool isReadOnly, bool isVolatile)
Definition: PropertyNode.h:702
PropertyHint mHint
the specified property hints
Definition: PropertyNode.h:181
Typename mType
the type of the property
Definition: PropertyNode.h:182
AbstractRemotePropertyNode(const PropertyNodeInfo &info)
Definition: PropertyNode.h:1049
Grants thread-safe access to an object that should be protected from concurrent access.
virtual json::Value getAsJSON() const
Returns the value of the property as JSON value.
Definition: PropertyNode.h:905
TypedPropertyNode(const PropertyNodeInfo &info)
Definition: PropertyNode.h:525
const LockedAccess pointer() const
Definition: PropertyNode.h:886
virtual const NodeList & children() const
Returns a vector with all child property nodes.
Definition: PropertyNode.h:233
void removeChild(int index, NodeList::iterator it)
#define MIRA_BASE_EXPORT
This is required because on windows there is a macro defined called ERROR.
Definition: Platform.h:153
bool isVolatile() const
Returns true, if this property is volatile and hence, must be locked for access.
Definition: PropertyNode.h:170
LockedPropertyNodeAccess< TypedPropertyNodeImpl< Accessor< Getter, Setter > >, AccessorType > LockedAccess
Definition: PropertyNode.h:962
virtual void endAddChildren()=0
void reflectWrite(Reflector &r)
Definition: PropertyNode.h:127
TypedPropertyNode< T > Base
Definition: PropertyNode.h:1100
PropertyNodeInfo(const std::string &id, const std::string &name, const std::string &comment, const Typename &type, bool isReadOnly, bool isVolatile)
Definition: PropertyNode.h:76
const std::string & name() const
Returns the name of this property as specified in the reflect() method.
Definition: PropertyNode.h:143
TypedPropertyNode< T > * toTyped()
Casts this property node to a typed property node, or returns NULL if the types do not match...
Definition: PropertyNode.h:1164
TypedRemotePropertyNode(AbstractRemotePropertyNode *node)
Definition: PropertyNode.h:1105
bool hasHint(const std::string &attribute) const
Returns true if a hint with the specified attribute exists.
Definition: PropertyNode.h:162
Proxy class that is returned/set by the getter and setter methods of ChannelProperty.
Definition: ChannelProperty.h:154
LockedPropertyNodeAccessCommon(LockedPropertyNodeAccessCommon &&other) noexcept
Definition: PropertyNode.h:569
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:817
TypedPropertyNode< T > * toTyped()
Specialized method that creates a TypedRemotePropertyNode.
Definition: PropertyNode.h:1191
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:66
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:634
Abstract base class for all typed property nodes.
Definition: PropertyNode.h:70
Serializer and Deserializer for JSON format.
const ValueType & operator*() const
Definition: PropertyNode.h:605
const LockedAccess accessor() const
Definition: PropertyNode.h:964
virtual void endMoveChildren()=0
void reflectRead(Reflector &r)
Definition: PropertyNode.h:119
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:140
Definition: PropertyNode.h:557
TypedPropertyNodeImplGetSetMixin(const std::string &id, const std::string &name, const std::string &comment, value_type &value, bool isReadOnly, bool isVolatile)
Definition: PropertyNode.h:756