MIRA
ChannelBuffer.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_CHANNELBUFFER_H_
48 #define _MIRA_CHANNELBUFFER_H_
49 
50 #include <list>
51 #include <string>
52 #include <type_traits>
53 
54 #ifndef Q_MOC_RUN
55 #include <boost/noncopyable.hpp>
56 #include <boost/thread/mutex.hpp>
57 #include <boost/thread/shared_mutex.hpp>
58 #endif
59 
60 #include <error/LoggingCore.h>
61 
62 #include <factory/TypeId.h>
63 
68 
69 #include <platform/Typename.h>
70 #include <utils/Stamped.h>
71 #include <utils/Time.h>
72 
73 #include <math/Eigen.h>
74 
75 namespace mira {
76 
78 
80 template<typename TargetType>
82 
84 template<typename TargetType>
86 
88 
94 {
97 
100 
103 };
104 
110 {
115 };
116 
118 
132 class ChannelBufferBase : boost::noncopyable
133 {
134  template<typename TargetType>
136 
137  template<typename TargetType>
138  friend struct ChannelBufferPromoter;
139 
140 public:
142  struct Slot;
143 
147  struct ListItem : boost::noncopyable
148  {
150  {
151  // creates empty list
152  next = (Slot*)this;
153  prev = (Slot*)this;
154  }
155 
156  // both will be locked by mutex in ChannelBuffer
159  };
160 
164  struct Slot : public ListItem
165  {
166  boost::shared_mutex lock; // locks the following data
167 
173  boost::mutex serializedValueLock;
174 
179 
185 
193 
194  const Time& timestamp() const
195  {
196  assert(timestampPtr != nullptr); // pointer is set in ChannelBuffers allocateSlot
197  return *timestampPtr;
198  }
199 
200  // required to allow dynamic_cast for subclasses
201  virtual ~Slot() = default;
202  };
203 
204 public:
210  ChannelBufferBase() = default;
211 
212  virtual ~ChannelBufferBase();
213 
214 public:
219  {
220  mMinSlots = other.mMinSlots;
221  mMaxSlots = other.mMaxSlots;
222  mStorageDuration = other.mStorageDuration;
223  mAutoIncreaseStorageDuration = other.mAutoIncreaseStorageDuration;
224  }
225 
226 public:
238  void setStorageDuration(const Duration& storageDuration);
239 
247  void setAutoIncreaseStorageDuration(bool increase);
248 
258  void setMinSlots(std::size_t minSlots);
259 
269  void setMaxSlots(std::size_t maxSlots);
270 
271 public:
273  std::size_t getSize() const;
274 
276  std::size_t getMaxSlots() const;
277 
279  std::size_t getMinSlots() const;
280 
283 
285  bool isAutoIncreasingStorageDuration() const;
286 
287 public:
289  virtual int getTypeId() const = 0;
290 
292  virtual bool isTyped() const = 0;
293 
295  virtual bool isPolymorphic() const = 0;
296 
302  virtual Typename getTypename() const = 0;
303 
307  virtual void setTypename(const Typename& name) = 0;
308 
313  virtual TypeMetaPtr createTypeMeta(Slot* s, MetaTypeDatabase& ioDB) = 0;
314 
319  {
320  return mTypeMeta;
321  }
322 
327  {
328  mTypeMeta = meta;
329  }
330 
338  virtual void fixateType() = 0;
339 
341  virtual Slot* allocateSlot() = 0;
342 
344  virtual void freeSlot(Slot* s) = 0;
345 
349  virtual StampedHeader& getStampedHeader(Slot* s) = 0;
350 
355  virtual const Buffer<uint8>& readSerializedValue(Slot* s) = 0;
356 
363  virtual const Buffer<uint8>& readSerializedValue(Slot* s, uint8 formatVersion, bool orLower) = 0;
364 
370  virtual Buffer<uint8> readSerializedValue(Slot* s, std::list<BinarySerializerCodecPtr>& codecs) = 0;
371 
379  virtual Buffer<uint8> readSerializedValue(Slot* s, std::list<BinarySerializerCodecPtr>& codecs,
380  uint8 formatVersion, bool orLower) = 0;
381 
386  virtual void writeSerializedValue(Slot* s, Buffer<uint8> data) = 0;
387 
395  virtual void readJSON(Slot* s, JSONValue& oValue) = 0;
396 
403  virtual void readJSON(Slot* s, JSONValue& oValue, JSONSerializer& serializer) = 0;
404 
412  virtual void writeJSON(Slot* s, const JSONValue& value) = 0;
413 
420  virtual void writeJSON(Slot* s, JSONDeserializer& value) = 0;
421 
428  virtual void writeXML(Slot* s, const XMLDom::const_iterator& node) = 0;
429 
430 public:
432  // write access
433 
456  Slot* requestWriteSlot();
457 
466  bool finishWriteSlot(Slot* n, bool* dropped = nullptr);
467 
472  void discardWriteSlot(Slot* n);
473 
475  // read access
476 
482  Slot* readNewestSlot();
483 
491  Slot* readSlotAtTime(const Time& timestamp, SlotQueryMode mode, bool keepStorageDuration);
492 
499  void readInterval(const Time& timestamp, std::size_t nrSlots, std::size_t olderSlots,
500  std::size_t newerSlots, IntervalFillMode fillMode, std::list<Slot*>& oSlots,
501  bool keepStorageDuration);
502 
509  void readInterval(const Time& from, const Time& to, std::list<Slot*>& oSlots, bool keepStorageDuration);
510 
511 public:
520  template<typename TargetType>
522 
523 private:
529  Slot* findFirstOlderSlot(const Time& timestamp, Slot* start = nullptr);
530 
531 private:
536  void splice(Slot* first, Slot* last, Slot* position) const;
537 
542  void splice(Slot* item, Slot* position) const
543  {
544  splice(item, item, position);
545  }
546 
547  static bool isEmpty(const ListItem& list)
548  {
549  return list.next == &list;
550  }
551  static Slot* begin(ListItem& list)
552  {
553  return list.next;
554  }
555  static Slot* last(ListItem& list)
556  {
557  return list.prev;
558  }
559  static Slot* end(ListItem& list)
560  {
561  return (Slot*)&list;
562  }
563 
565  void deleteSlots(ListItem& list);
566 
567 protected:
569  void clear();
570 
571 private:
577  void increaseStorageDuration(const Time& requested);
578 
583  void resetSlot(Slot* s);
584 
585  // parameters:
586  Duration mStorageDuration = Duration::seconds(0);
587  bool mAutoIncreaseStorageDuration = true;
588  std::size_t mMinSlots = 0;
589  std::size_t mMaxSlots = 100;
590 
591  // mutex that locks all actions when we change our lists
592  mutable boost::mutex mMutex;
593 
594  std::size_t mSize = 0; // current number of slots we are using
595 
596  ListItem mBuffer;
597 
610  ListItem mWaitingOrFree;
611 
615  ListItem mWriting;
616 
617  TypeMetaPtr mTypeMeta;
618 
619 private:
620  std::string dbgDumpList(ListItem& list, bool brief);
621 
622 public:
623  void dbgDump(const std::string& prefix, bool brief = true);
624 
625  static void dbgCheckListIntegrity(const ListItem& list);
626  void dbgCheckIntegrity();
627 };
628 
630 
634 template<typename T>
636 {
637 public:
639 
640 public:
642  {
643  this->clear();
644  }
645 
646 public:
649  {
652  EIGEN_MAKE_ALIGNED_OPERATOR_NEW
653 
654  template<bool IsCheap = IsCheapToCopy<T>::value>
655  std::unique_ptr<Slot> clone()
656  {
657  static_assert(IsCheap,
658  "TypedChannelBufferBase<T>::Slot::clone() must not be called "
659  "with IsCheapToCopy<T>=false");
660  auto slot = std::make_unique<Slot>();
661  {
662  boost::mutex::scoped_lock lock(this->serializedValueLock);
663  slot->serializedValue = this->serializedValue;
664  }
665  slot->timestampPtr = &(static_cast<StampedHeader&>(slot->data).timestamp);
666  slot->flags = this->flags;
667  slot->data = this->data;
668  return slot;
669  }
670  };
671 
672 protected:
677  {
678  // cast abstract ChannelBufferBase::Slot to TypedChannelBufferBase<T>::Slot.
679  // this is safe since all slots were created by us in allocateSlot()
680  // as TypedChannelBufferBase<T>::Slots
681  return static_cast<Slot*>(s);
682  }
683 
684 public:
689  int getTypeId() const override
690  {
691  return typeId<T>();
692  }
693  bool isTyped() const override
694  {
695  return true;
696  }
697  bool isPolymorphic() const override
698  {
699  return false;
700  }
701  Typename getTypename() const override
702  {
703  return typeName<T>();
704  }
705  void setTypename(const Typename& name) override
706  {
707  MIRA_THROW(XRuntime, "Cannot set Typename for typed channels");
708  }
710  {
711  MetaSerializer ms(ioDB);
712  Slot* slot = castSlot(s);
713  TypeMetaPtr meta = ms.addMeta(slot->data.internalValueRep());
714  return meta;
715  }
716 
717  void fixateType() override {} // doesn't do anything
719  {
720  Slot* slot = new Slot;
721  slot->timestampPtr =
722  &(static_cast<StampedHeader&>(slot->data).timestamp); // "connect" the timestamp ptr
723  return slot;
724  }
726  {
727  // casting s to our slot type ensures that the correct destructor is called
728  Slot* slot = castSlot(s);
729  delete slot;
730  }
731 
732 public:
734  {
735  // we can safely cast here, since s is an object of our Slot type
736  Slot* slot = static_cast<Slot*>(s);
737  return stampedHeader(slot->data);
738  }
739 
741  {
742  // lock the serialization mutex to protect serializedValueLock
743  // (we or someone else may write it here)
744  boost::mutex::scoped_lock lock(s->serializedValueLock);
745 
746  // no serialized data yet, so serialize it now (lazy evaluation)
747  if (s->serializedValue.empty()) {
748  // we can safely cast here, since s is an object of our Slot type
749  Slot* slot = static_cast<Slot*>(s);
750 
751  // serialize the data
753  bs.serialize(slot->data.internalValueRep(), false);
754  }
755 
756  return s->serializedValue;
757  }
758 
760  bool orLower) override
761  {
762  uint8 serializerVersion = BinaryBufferSerializer::getSerializerFormatVersion();
763 
764  if (formatVersion == serializerVersion)
765  return readSerializedValue(s);
766 
767  if (formatVersion == 0) {
768  // lock the serialization mutex to protect serializedValueLock
769  // (we or someone else may write it here)
770  boost::mutex::scoped_lock lock(s->serializedValueLock);
771 
772  // no serialized data yet, so serialize it now (lazy evaluation)
773  if (s->serializedValue.empty()) {
774  // we can safely cast here, since s is an object of our Slot type
775  Slot* slot = static_cast<Slot*>(s);
776 
777  // serialize the data
779  bs.serialize(slot->data.internalValueRep(), false);
780  }
781 
782  return s->serializedValue;
783  }
784 
785  MIRA_THROW(XIO,
786  "Requested serialized data of binary format version "
787  << (int)formatVersion << ". Only implemented for versions 0, "
788  << (int)serializerVersion << ".");
789  }
790 
792  std::list<BinarySerializerCodecPtr>& codecs) override
793  {
794  Buffer<uint8> serializedValue;
795 
796  // we can safely cast here, since s is an object of our Slot type
797  Slot* slot = static_cast<Slot*>(s);
798 
799  BinaryBufferSerializer bs(&serializedValue);
800 
801  // register codecs
802  foreach (BinarySerializerCodecPtr codec, codecs)
803  bs.registerCodec(codec);
804 
805  // serialize the data
806  bs.serialize(slot->data.internalValueRep(), false);
807 
808  return std::move(serializedValue);
809  }
810 
811  Buffer<uint8> readSerializedValue(ChannelBufferBase::Slot* s, std::list<BinarySerializerCodecPtr>& codecs,
812  uint8 formatVersion, bool orLower) override
813  {
814  uint8 serializerVersion = BinaryBufferSerializer::getSerializerFormatVersion();
815 
816  if (formatVersion == serializerVersion)
817  return readSerializedValue(s, codecs);
818 
819  if (formatVersion == 0) {
820  Buffer<uint8> serializedValue;
821 
822  // we can safely cast here, since s is an object of our Slot type
823  Slot* slot = static_cast<Slot*>(s);
824 
825  BinaryBufferSerializerLegacy bs(&serializedValue);
826 
827  // register codecs
828  foreach (BinarySerializerCodecPtr codec, codecs)
829  bs.registerCodec(codec);
830 
831  // serialize the data
832  bs.serialize(slot->data.internalValueRep(), false);
833 
834  return std::move(serializedValue);
835  }
836 
837  MIRA_THROW(XIO,
838  "Requested serialized data of binary format version "
839  << (int)formatVersion << ". Only implemented for versions 0, "
840  << (int)serializerVersion << ".");
841  }
842 
844  {
845  s->serializedValue = std::move(data);
846 
847  // we can safely cast here, since s is an object of our Slot type
848  Slot* slot = static_cast<Slot*>(s);
849 
850  // deserialize into our data
852 
853  {
854  boost::mutex::scoped_lock lock(mCodecsMutex);
855  bs.setCodecs(mCodecs);
856  }
857  bs.deserialize(slot->data.internalValueRep(), false);
858  {
859  boost::mutex::scoped_lock lock(mCodecsMutex);
860  mCodecs = bs.getCodecs();
861  }
862  }
863 
864  void readJSON(ChannelBufferBase::Slot* s, JSONValue& oValue) override
865  {
866  // we can safely cast here, since s is an object of our Slot type
867  Slot* slot = static_cast<Slot*>(s);
868 
869  JSONSerializer json;
870  oValue = json.serialize(slot->data.internalValueRep());
871  }
872 
873  void readJSON(ChannelBufferBase::Slot* s, JSONValue& oValue, JSONSerializer& serializer) override
874  {
875  // we can safely cast here, since s is an object of our Slot type
876  Slot* slot = static_cast<Slot*>(s);
877 
878  oValue = serializer.serialize(slot->data.internalValueRep());
879  }
880 
881  void writeJSON(ChannelBufferBase::Slot* s, const JSONValue& value) override
882  {
883  // we can safely cast here, since s is an object of our Slot type
884  Slot* slot = static_cast<Slot*>(s);
885 
886  JSONDeserializer json(value);
887  json.deserialize(slot->data.internalValueRep());
888  }
889 
890  void writeJSON(ChannelBufferBase::Slot* s, JSONDeserializer& deserializer) override
891  {
892  // we can safely cast here, since s is an object of our Slot type
893  Slot* slot = static_cast<Slot*>(s);
894 
895  deserializer.deserialize(slot->data.internalValueRep());
896  }
897 
899  {
900  // we can safely cast here, since s is an object of our Slot type
901  Slot* slot = static_cast<Slot*>(s);
902  XMLDeserializer xml(node);
903  const std::string rootTag = *node;
904  xml.deserializeFromNode(rootTag.c_str(), slot->data.internalValueRep());
905  }
907 
908 private:
910  boost::mutex mCodecsMutex;
911 };
912 
914 
918 template<typename T>
920 {};
921 
923 
928 template<>
929 class ChannelBuffer<void> : public ChannelBufferBase
930 {
931 public:
933 
934 public:
937  {
939  EIGEN_MAKE_ALIGNED_OPERATOR_NEW
940  };
941 
942 protected:
947  {
948  return static_cast<Slot*>(s);
949  }
950 
951 public:
952  ChannelBuffer() : mTypename("") {}
953 
954  virtual ~ChannelBuffer()
955  {
956  this->clear();
957  }
958 
959 public:
964  int getTypeId() const override
965  {
966  return -1;
967  }
968  bool isTyped() const override
969  {
970  return false;
971  }
972  bool isPolymorphic() const override
973  {
974  return false;
975  }
976  Typename getTypename() const override
977  {
978  return mTypename;
979  }
980  void setTypename(const Typename& name) override;
982  {
983  MIRA_THROW(XRuntime, "Cannot create type meta for untyped channels");
984  // keep compiler happy
985  return TypeMetaPtr();
986  }
987  void fixateType() override {} // doesn't do anything
988 
990  {
991  Slot* slot = new Slot;
992  slot->timestampPtr = &slot->header.timestamp; // "connect" the timestamp ptr
993  return slot;
994  }
995 
997  {
998  // casting s to our slot type ensures that the correct destructor is called
999  Slot* slot = castSlot(s);
1000  delete slot;
1001  }
1002 
1003 public:
1005  {
1006  // casting here is not safe, if we actually are a typed buffer,
1007  // however, if we are, then the TypedChannelBuffer::getStampedHeader()
1008  // of that class would have been called instead of us.
1009  Slot* slot = static_cast<Slot*>(s);
1010  return slot->header;
1011  }
1012 
1014  {
1015  return s->serializedValue;
1016  }
1017 
1019  bool orLower) override
1020  {
1021  BinaryBufferIstream stream(&(s->serializedValue));
1022  uint8 dataVersion = BinaryBufferDeserializer::getDataFormatVersion(stream);
1023  if ((!orLower && (dataVersion != formatVersion)) || (dataVersion > formatVersion)) {
1024  MIRA_THROW(XIO,
1025  "Untyped channel contains serialized data of version "
1026  << (int)dataVersion << ", cannot return data of version " << (int)formatVersion
1027  << ".");
1028  }
1029 
1030  return readSerializedValue(s);
1031  }
1032 
1034  std::list<BinarySerializerCodecPtr>& codecs) override
1035  {
1036  // we must ignore the codecs
1037  return s->serializedValue;
1038  }
1039 
1040  Buffer<uint8> readSerializedValue(ChannelBufferBase::Slot* s, std::list<BinarySerializerCodecPtr>& codecs,
1041  uint8 formatVersion, bool orLower) override
1042  {
1043  // we must ignore the codecs
1044  return readSerializedValue(s, formatVersion, orLower);
1045  }
1046 
1048  {
1049  s->serializedValue = std::move(data);
1050  }
1051 
1052  void readJSON(ChannelBufferBase::Slot* s, JSONValue& oValue) override;
1053  void readJSON(ChannelBufferBase::Slot* s, JSONValue& oValue, JSONSerializer& serializer) override;
1054 
1055  void writeJSON(ChannelBufferBase::Slot* s, const JSONValue& value) override;
1056  void writeJSON(ChannelBufferBase::Slot* s, JSONDeserializer& deserializer) override;
1057  void writeXML(ChannelBufferBase::Slot* s, const XMLDom::const_iterator& node) override;
1058 
1060 
1061 private:
1062  Typename mTypename;
1063 };
1064 
1066 
1071 {
1073 
1074 public:
1077 
1078 public:
1083  bool isPolymorphic() const override
1084  {
1085  return true;
1086  }
1087 
1088  int getTypeId() const override;
1089 
1090  Typename getTypename() const override;
1091 
1093 
1094  void freeSlot(ChannelBufferBase::Slot* s) override;
1095 
1096  void fixateType() override;
1097 
1100 
1102  void promote(const Class* promotionClass);
1103 
1104 protected:
1107 };
1108 
1109 // declare template extern to speed up compilation time by several seconds
1110 extern template class TypedChannelBufferBase<Object*>;
1111 
1113 
1118 template<typename T>
1120 {
1121  static_assert(std::is_base_of<mira::Object, T>::value,
1122  "In channels you can only use pointers of polymorphic "
1123  "classes that are derived from mira::Object. Pointers to "
1124  "other classes cannot be stored in a channel.");
1125 
1126 public:
1127  typedef Stamped<T*> ValueType;
1128 
1129 public:
1131  {
1132  mMostDerivedClass = &T::CLASS();
1133  }
1134 };
1135 
1137 // Channel buffer promotion code
1138 
1145 template<typename U>
1146 struct ChannelBufferPromoterCommon
1147 {
1149  {
1150  assert(!buffer->isTyped() && "Can promote untyped channels to typed channels only");
1151 
1152  if (!buffer->getTypename().empty() && buffer->getTypename() != typeName<U>())
1153  MIRA_THROW(XBadCast,
1154  "Invalid promotion from untyped to typed "
1155  "ChannelBuffer. Typename does not match. ('"
1156  << buffer->getTypename() << "' != '" << typeName<U>() << "'");
1157 
1158  typedef ChannelBufferBase::Slot Slot;
1159 
1160  // create a new typed buffer
1161  ChannelBuffer<U>* typedBuffer = new ChannelBuffer<U>;
1162 
1163  // copy all parameters
1164  typedBuffer->cloneParameters(*buffer);
1165 
1166  // copy all the serialized data from the untyped buffer into the
1167  // typed buffer and deserialize it into the value
1168 
1169  // now lock the whole buffer for reading ...
1170  for (Slot* s = ChannelBufferBase::begin(buffer->mBuffer);
1171  s != ChannelBufferBase::end(buffer->mBuffer); s = s->next)
1172  s->lock.lock_shared();
1173 
1174  // ... and deserialize the content of each slot into the new buffer
1175  for (Slot* s = ChannelBufferBase::begin(buffer->mBuffer);
1176  s != ChannelBufferBase::end(buffer->mBuffer); s = s->next) {
1177  Slot* n = typedBuffer->requestWriteSlot(); // obtain a new slot
1178 
1179  // ... copy the headers
1180  typedBuffer->getStampedHeader(n) = buffer->getStampedHeader(s);
1181 
1182  // ... and write the value into the new slot (this will deserialize the data there)
1183  typedBuffer->writeSerializedValue(n, s->serializedValue);
1184 
1185  typedBuffer->finishWriteSlot(n);
1186  }
1187 
1188  // free the read lock from above ...
1189  for (Slot* s = ChannelBufferBase::begin(buffer->mBuffer);
1190  s != ChannelBufferBase::end(buffer->mBuffer); s = s->next)
1191  s->lock.unlock_shared();
1192 
1193  return typedBuffer;
1194  }
1195 };
1196 
1198 
1209 template<typename U>
1210 struct ChannelBufferPromoter : public ChannelBufferPromoterCommon<U>
1211 {
1214  {
1215  if (buffer->isTyped())
1216  return buffer; // we are promoted already, do nothing
1217  return Base::promoteUntyped(buffer);
1218  }
1219 };
1220 
1222 
1227 template<typename U>
1229 {
1232  {
1233  // if untyped, promote to typed first
1234  if (!buffer->isTyped())
1235  buffer = Base::promoteUntyped(buffer);
1236 
1237  PolymorphicChannelBuffer* polymorphicBuffer = dynamic_cast<PolymorphicChannelBuffer*>(buffer);
1238 
1239  assert(polymorphicBuffer != nullptr
1240  && "We should never reach here if the buffer to promote is not "
1241  "polymorphic");
1242 
1243  // get class of U
1244  const Class* classU = &U::CLASS();
1245 
1246  // promote us (this will do error checking and might throw XBadCast)
1247  polymorphicBuffer->promote(classU);
1248 
1249  return polymorphicBuffer;
1250  }
1251 };
1252 
1254 
1255 template<typename U>
1257 {
1258  return ChannelBufferPromoter<U>::promote(this);
1259 }
1260 
1262 
1263 } // namespace mira
1264 
1265 #endif
Serializer for serializing objects in JSON format.
Definition: JSONSerializer.h:95
void fixateType() override
Calling this method will fix the type of the ChannelBuffer.
Typename getTypename() const override
Returns the Typename of the slot values, in contrast to getTypeId() the Typename is portable and uniq...
Definition: ChannelBuffer.h:701
void fixateType() override
Calling this method will fix the type of the ChannelBuffer.
Definition: ChannelBuffer.h:717
Database that stores all meta type information and provides additional functions for accessing the da...
Definition: MetaSerializer.h:509
void deserialize(T &value)
Definition: JSONSerializer.h:436
void setStorageDuration(const Duration &storageDuration)
Sets the desired storage duration (the history).
boost::shared_mutex lock
Definition: ChannelBuffer.h:166
static ChannelBufferBase * promote(ChannelBufferBase *buffer)
Definition: ChannelBuffer.h:1231
const Buffer< uint8 > & readSerializedValue(ChannelBufferBase::Slot *s, uint8 formatVersion, bool orLower) override
Returns a buffer containing the binary serialized data of the slot.
Definition: ChannelBuffer.h:1018
Definition: BinarySerializer.h:316
const Time * timestampPtr
Pointer to the actual timestamp in the slot data for easy access.
Definition: ChannelBuffer.h:178
const Class * mFixatedClass
Definition: ChannelBuffer.h:1106
Buffer< uint8 > readSerializedValue(ChannelBufferBase::Slot *s, std::list< BinarySerializerCodecPtr > &codecs) override
Returns a buffer containing the binary serialized data of the slot.
Definition: ChannelBuffer.h:791
bool isPolymorphic() const override
Returns true if the channel has a polymorphic type.
Definition: ChannelBuffer.h:1083
virtual void readJSON(Slot *s, JSONValue &oValue)=0
Reads data of that slot as json representation using a default-instantiated JSONSerializer.
boost::mutex serializedValueLock
Lock for writing serializedValue in readSerializedData.
Definition: ChannelBuffer.h:173
const Class * mMostDerivedClass
Definition: ChannelBuffer.h:1105
bool isAutoIncreasingStorageDuration() const
Returns whether the storage duration is automatically increased.
Include file for all eigen related things.
ChannelBufferBase::Slot * allocateSlot() override
Creates and returns a new slot.
Definition: ChannelBuffer.h:718
virtual ~ChannelBuffer()
Definition: ChannelBuffer.h:954
Typed slot derived from ChannelBufferBase::Slot.
Definition: ChannelBuffer.h:648
void promote(const Class *promotionClass)
Promotes the polymorphic type of the channel to the given class type.
virtual void freeSlot(Slot *s)=0
Called to destroy the slot and free the used memory.
The first slot with timestamp < requested will be chosen.
Definition: ChannelBuffer.h:96
ChannelBufferBase::Slot * allocateSlot() override
Creates and returns a new slot.
ChannelBufferBase::Slot * allocateSlot() override
Creates and returns a new slot.
Definition: ChannelBuffer.h:989
Slot * castSlot(ChannelBufferBase::Slot *s)
Cast an abstract slot to a typed slot.
Definition: ChannelBuffer.h:946
void writeSerializedValue(ChannelBufferBase::Slot *s, Buffer< uint8 > data) override
Write the given buffer (that contains binary serialized data WITHOUT the StampedHeader) to the slot...
Definition: ChannelBuffer.h:1047
specialize cv::DataType for our ImgPixel and inherit from cv::DataType<Vec>
Definition: IOService.h:67
virtual TypeMetaPtr createTypeMeta(Slot *s, MetaTypeDatabase &ioDB)=0
Creates meta information for data in slot and stores all meta information in the given database...
int getTypeId() const override
Returns typeid of the slot values, the allocator creates.
Definition: ChannelBuffer.h:689
std::string Typename
Definition: Typename.h:60
void writeJSON(ChannelBufferBase::Slot *s, const JSONValue &value) override
Writes data in json representation into the slot, using a default-instantiated JSONDeserializer.
Definition: ChannelBuffer.h:881
Specialization for polymorphic types (only classes derived from mira::Object are supported!) ...
Definition: ChannelBuffer.h:1119
ValueType header
Definition: ChannelBuffer.h:938
Time and Duration wrapper class.
Class object which supports some kind of class reflection.
Definition: Class.h:97
uint32_t uint32
Definition: Types.h:64
void freeSlot(ChannelBufferBase::Slot *s) override
Called to destroy the slot and free the used memory.
Definition: ChannelBuffer.h:725
virtual void setTypename(const Typename &name)=0
Sets the Typename of the slot values.
ListItem()
Definition: ChannelBuffer.h:149
Stamped class specialization for polymorphic pointers.
Definition: Stamped.h:238
StampedHeader & stampedHeader(Stamped< T > &data)
Helper to extract the header from stamped data.
Definition: Stamped.h:482
ChannelBufferBase * promote()
Promotes this buffer to the specified target type (if required).
Definition: ChannelBuffer.h:1256
TypeMetaPtr getTypeMeta() const
Returns the meta information for the slots type.
Definition: ChannelBuffer.h:318
Base class for typed channel buffers.
Definition: ChannelBuffer.h:635
void setMinSlots(std::size_t minSlots)
Sets the desired min.
static ChannelBufferBase * promoteUntyped(ChannelBufferBase *buffer)
Definition: ChannelBuffer.h:1148
static void dbgCheckListIntegrity(const ListItem &list)
Get compiler and platform independent typenames.
bool isPolymorphic() const override
Returns true if the channel has a polymorphic type.
Definition: ChannelBuffer.h:972
void readJSON(ChannelBufferBase::Slot *s, JSONValue &oValue, JSONSerializer &serializer) override
Reads data of that slot as json representation using the provided JSONSerializer. ...
Definition: ChannelBuffer.h:873
virtual Slot * allocateSlot()=0
Creates and returns a new slot.
const Buffer< uint8 > & readSerializedValue(ChannelBufferBase::Slot *s) override
Returns a buffer containing the binary serialized data of the slot.
Definition: ChannelBuffer.h:1013
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
#define MIRA_THROW(ex, msg)
Macro for throwing an exception.
Definition: Exception.h:78
void serialize(const T &value, bool enableTypeCheck=true)
Provides a special serialize interface for the BinarySerializer.
Definition: BinarySerializer.h:590
Slot * readSlotAtTime(const Time &timestamp, SlotQueryMode mode, bool keepStorageDuration)
Returns a slot at the given time according to mode.
Implements double-linked list item.
Definition: ChannelBuffer.h:147
Const sibling_iterator for iterating over xml nodes that have the same parent (siblings) ...
Definition: XMLDom.h:763
Wrapper class for boost::posix_time::ptime for adding more functionality to it.
Definition: Time.h:418
Slot * requestWriteSlot()
Returns a slot for writing, where the shared_mutex is already write locked.
bool isPolymorphic() const override
Returns true if the channel has a polymorphic type.
Definition: ChannelBuffer.h:697
ChannelBufferPromoterCommon< U > Base
Definition: ChannelBuffer.h:1230
ChannelBuffer()
Definition: ChannelBuffer.h:1130
A channel buffer for polymorphic types (classes derived from mira::Object)
Definition: ChannelBuffer.h:1070
Deserializer for serializing objects from JSON format.
Definition: JSONSerializer.h:406
virtual void writeXML(Slot *s, const XMLDom::const_iterator &node)=0
Writes data in xml representation into the slot, using a default-instantiated XMLDeserializer and the...
virtual ~TypedChannelBufferBase()
Definition: ChannelBuffer.h:641
void setTypeMeta(TypeMetaPtr meta)
Sets the meta information of the slot&#39;s type.
Definition: ChannelBuffer.h:326
Binary serializer and deserializer.
PolymorphicChannelBuffer()
Constructor.
Definition: ChannelBuffer.h:1076
forward decl.
Definition: ChannelBuffer.h:81
void registerCodec(BinarySerializerCodecPtr codec)
Registers the specified codec instance in this binary serializer.
Definition: BinarySerializer.h:756
int getTypeId() const override
Returns typeid of the slot values, the allocator creates.
virtual const Buffer< uint8 > & readSerializedValue(Slot *s)=0
Returns a buffer containing the binary serialized data of the slot.
Definition: MetaSerializer.h:586
Buffer< uint8 > readSerializedValue(ChannelBufferBase::Slot *s, std::list< BinarySerializerCodecPtr > &codecs, uint8 formatVersion, bool orLower) override
Returns a buffer containing the binary serialized data of the slot.
Definition: ChannelBuffer.h:1040
Slot * castSlot(ChannelBufferBase::Slot *s)
Cast an abstract slot to a typed slot.
Definition: ChannelBuffer.h:676
EIGEN_MAKE_ALIGNED_OPERATOR_NEW std::unique_ptr< Slot > clone()
Definition: ChannelBuffer.h:655
Stamped< T * > ValueType
Definition: ChannelBuffer.h:1124
sec_type seconds() const
Returns normalized number of seconds (0..59)
Definition: Time.h:280
Typename getTypename() const override
Returns the Typename of the slot values, in contrast to getTypeId() the Typename is portable and uniq...
Definition: ChannelBuffer.h:976
Core class of the logging library.
Use this class to represent time durations.
Definition: Time.h:106
The common header for all stamped data.
Definition: Stamped.h:62
const CodecsMap & getCodecs() const
Return the map of currently known codecs.
Definition: BinarySerializer.h:1570
void setTypename(const Typename &name) override
Sets the Typename of the slot values.
Definition: ChannelBuffer.h:705
uint8_t uint8
Definition: Types.h:62
void writeSerializedValue(ChannelBufferBase::Slot *s, Buffer< uint8 > data) override
Write the given buffer (that contains binary serialized data WITHOUT the StampedHeader) to the slot...
Definition: ChannelBuffer.h:843
bool empty() const
Checks if the buffer is empty (used size == 0).
Definition: Buffer.h:299
StampedHeader & getStampedHeader(ChannelBufferBase::Slot *s) override
Returns a reference to the stamped header information.
Definition: ChannelBuffer.h:1004
void freeSlot(ChannelBufferBase::Slot *s) override
Called to destroy the slot and free the used memory.
Typed ChannelBuffer.
Definition: ChannelBuffer.h:919
The slot with smallest time difference to the requested will be chosen.
Definition: ChannelBuffer.h:102
virtual void fixateType()=0
Calling this method will fix the type of the ChannelBuffer.
void freeSlot(ChannelBufferBase::Slot *s) override
Called to destroy the slot and free the used memory.
Definition: ChannelBuffer.h:996
int getTypeId() const override
Returns typeid of the slot values, the allocator creates.
Definition: ChannelBuffer.h:964
virtual StampedHeader & getStampedHeader(Slot *s)=0
Returns a reference to the stamped header information.
ChannelBuffer()
Definition: ChannelBuffer.h:952
Mix in for adding a time stamp, an optional frame id and an optional sequence id to data types like P...
Definition: Stamped.h:149
boost::shared_ptr< TypeMeta > TypeMetaPtr
Definition: MetaSerializer.h:309
Mix in for adding a timestamp to data types.
Stamped< T > ValueType
Definition: ChannelBuffer.h:638
Serializer for creating meta information out of types using serialization.
ChannelBufferBase()=default
Constructor.
void cloneParameters(const ChannelBufferBase &other)
Copies the parameters of other to this.
Definition: ChannelBuffer.h:218
forward decl.
Definition: ChannelBuffer.h:85
virtual bool isPolymorphic() const =0
Returns true if the channel has a polymorphic type.
void dbgDump(const std::string &prefix, bool brief=true)
void writeSerializedValue(ChannelBufferBase::Slot *s, Buffer< uint8 > data) override
Write the given buffer (that contains binary serialized data WITHOUT the StampedHeader) to the slot...
void setMaxSlots(std::size_t maxSlots)
Sets the max.
Buffer< uint8 > readSerializedValue(ChannelBufferBase::Slot *s, std::list< BinarySerializerCodecPtr > &codecs) override
Returns a buffer containing the binary serialized data of the slot.
Definition: ChannelBuffer.h:1033
ValueType data
the actual data value, that is stored in this channel&#39;s slots
Definition: ChannelBuffer.h:651
Buffer< uint8 > readSerializedValue(ChannelBufferBase::Slot *s, std::list< BinarySerializerCodecPtr > &codecs, uint8 formatVersion, bool orLower) override
Returns a buffer containing the binary serialized data of the slot.
Definition: ChannelBuffer.h:811
Base class that manages the slots of channels by providing read and write access to them...
Definition: ChannelBuffer.h:132
const Time & timestamp() const
Definition: ChannelBuffer.h:194
Container for storing a single data element in the linked list.
Definition: ChannelBuffer.h:164
std::size_t getMaxSlots() const
Returns the size of the max number of slots.
void setCodecs(const CodecsMap &codecs)
Set the map of known codecs.
Definition: BinarySerializer.h:1575
Slot * readNewestSlot()
Returns the newest(latest) slot for reading, where the shared_mutex is already read locked...
bool isTyped() const override
Returns true, if the channel is typed and false, if it is untyped.
Definition: ChannelBuffer.h:693
Input stream adapter that can be assigned to any input stream and allows binary input using the >> st...
Definition: BinaryStream.h:525
Slot * next
Definition: ChannelBuffer.h:157
std::size_t getSize() const
Returns the size of the buffer.
Buffer< uint8 > serializedValue
The data of this slot as serialized data.
Definition: ChannelBuffer.h:184
const Buffer< uint8 > & readSerializedValue(ChannelBufferBase::Slot *s) override
Returns a buffer containing the binary serialized data of the slot.
Definition: ChannelBuffer.h:740
const Buffer< uint8 > & readSerializedValue(ChannelBufferBase::Slot *s, uint8 formatVersion, bool orLower) override
Returns a buffer containing the binary serialized data of the slot.
Definition: ChannelBuffer.h:759
bool finishWriteSlot(Slot *n, bool *dropped=nullptr)
Adds written slot into buffer at the right time position.
StampedHeader & getStampedHeader(ChannelBufferBase::Slot *s) override
Returns a reference to the stamped header information.
Definition: ChannelBuffer.h:733
void deserialize(T &value, bool enableTypeCheck=true, bool recursive=false)
Provides a special deserialize interface for the BinaryDeserializer.
Definition: BinarySerializer.h:1329
StampedHeader ValueType
Definition: ChannelBuffer.h:932
void writeJSON(ChannelBufferBase::Slot *s, JSONDeserializer &deserializer) override
Writes data from an initialized json deserializer into the slot.
Definition: ChannelBuffer.h:890
ChannelBufferPromoterCommon< U > Base
Definition: ChannelBuffer.h:1212
TypeMetaPtr addMeta(const T &v)
Definition: MetaSerializer.h:605
Typename getTypename() const override
Returns the Typename of the slot values, in contrast to getTypeId() the Typename is portable and uniq...
XMLSerializer and XMLDeserializer.
std::size_t getMinSlots() const
Returns the size of the min number of slots.
virtual void writeSerializedValue(Slot *s, Buffer< uint8 > data)=0
Write the given buffer (that contains binary serialized data WITHOUT the StampedHeader) to the slot...
Prefer filling the interval with slots with timestamp > requested.
Definition: ChannelBuffer.h:114
void discardWriteSlot(Slot *n)
Discards written slot.
Prefer filling the interval with slots with timestamp < requested.
Definition: ChannelBuffer.h:112
void fixateType() override
Calling this method will fix the type of the ChannelBuffer.
Definition: ChannelBuffer.h:987
void setAutoIncreaseStorageDuration(bool increase)
Sets whether the storage duration is automatically increased on read accesses.
void readJSON(ChannelBufferBase::Slot *s, JSONValue &oValue) override
Reads data of that slot as json representation using a default-instantiated JSONSerializer.
Definition: ChannelBuffer.h:864
uint32 flags
Used to store internal flags that are especially used by the remote capability of the framework...
Definition: ChannelBuffer.h:192
static ChannelBufferBase * promote(ChannelBufferBase *buffer)
Definition: ChannelBuffer.h:1213
void deserializeFromNode(const char *name, T &value)
In contrast to the deserialize() method this method will use the node that was specified in the const...
Definition: XMLSerializer.h:362
IntervalFillMode
Mode that is used to determine what slots should be added to the interval when not enough slots are a...
Definition: ChannelBuffer.h:109
void writeXML(ChannelBufferBase::Slot *s, const XMLDom::const_iterator &node) override
Writes data in xml representation into the slot, using a default-instantiated XMLDeserializer and the...
Definition: ChannelBuffer.h:898
Specialization of ChannelBufferPromoter for polymorphic pointer channel buffers.
Definition: ChannelBuffer.h:1228
virtual Typename getTypename() const =0
Returns the Typename of the slot values, in contrast to getTypeId() the Typename is portable and uniq...
SlotQueryMode
Mode that is used to determine the slot obtained from a channel when no slot exists at the exact time...
Definition: ChannelBuffer.h:93
json::Value JSONValue
Imports the json::Value type into mira namespace.
Definition: JSON.h:361
TypeMetaPtr createTypeMeta(ChannelBufferBase::Slot *s, MetaTypeDatabase &ioDB) override
Creates meta information for data in slot and stores all meta information in the given database...
Definition: ChannelBuffer.h:981
void clear()
Deletes all slots in all lists and therefore clears the whole buffer.
Provides method for generating a unique id for any type.
Duration getStorageDuration() const
Returns the storage duration.
Slot * prev
Definition: ChannelBuffer.h:158
TypeMetaPtr createTypeMeta(ChannelBufferBase::Slot *s, MetaTypeDatabase &ioDB) override
Creates meta information for data in slot and stores all meta information in the given database...
Definition: ChannelBuffer.h:709
void readInterval(const Time &timestamp, std::size_t nrSlots, std::size_t olderSlots, std::size_t newerSlots, IntervalFillMode fillMode, std::list< Slot *> &oSlots, bool keepStorageDuration)
Reads an interval of slots.
bool isTyped() const override
Returns true, if the channel is typed and false, if it is untyped.
Definition: ChannelBuffer.h:968
virtual void writeJSON(Slot *s, const JSONValue &value)=0
Writes data in json representation into the slot, using a default-instantiated JSONDeserializer.
Serializer and Deserializer for JSON format.
virtual int getTypeId() const =0
Returns typeid of the slot values, the allocator creates.
virtual bool isTyped() const =0
Returns true, if the channel is typed and false, if it is untyped.
The first slot with timestamp > requested will be chosen.
Definition: ChannelBuffer.h:99
std::map< TypeId, BinarySerializerCodecPtr > CodecsMap
A map of binary serialization codecs.
Definition: BinarySerializer.h:1259
boost::shared_ptr< BinarySerializerCodec > BinarySerializerCodecPtr
Shared pointer of BinarySerializerCodec.
Definition: BinarySerializerCodec.h:64
Deserializer for serializing objects from XML format.
Definition: XMLSerializer.h:314