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 <string>
51 #include <list>
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 <utils/Time.h>
70 #include <utils/Stamped.h>
71 #include <platform/Typename.h>
72 
73 #include <math/Eigen.h>
74 
75 #include <fw/FrameworkExports.h>
76 
77 namespace mira {
78 
80 
82 template <typename TargetType>
84 
86 template <typename TargetType>
88 
90 
96 {
99 
102 
105 };
106 
112 {
117 };
118 
120 
134 class MIRA_FRAMEWORK_EXPORT ChannelBufferBase : boost::noncopyable
135 {
136  template <typename TargetType>
138 
139  template <typename TargetType>
140  friend struct ChannelBufferPromoter;
141 
142 public:
143 
145  struct Slot;
146 
150  struct ListItem : boost::noncopyable
151  {
153  // creates empty list
154  next = (Slot*)this;
155  prev = (Slot*)this;
156  }
157 
158  // both will be locked by mutex in ChannelBuffer
161  };
162 
166  struct Slot : public ListItem
167  {
168  boost::shared_mutex lock; // locks the following data
169 
175  boost::mutex serializedValueLock;
176 
181 
187 
194  uint32 flags;
195 
196  const Time& timestamp() const {
197  assert(timestampPtr!=NULL); // pointer is set in ChannelBuffers allocateSlot
198  return *timestampPtr;
199  }
200 
201  virtual ~Slot() = default;
202  virtual std::unique_ptr<Slot> clone() = 0;
203  };
204 
205 public:
206 
213  mStorageDuration(Duration::seconds(0)),
214  mAutoIncreaseStorageDuration(true),
215  mMinSlots(0),
216  mMaxSlots(100),
217  mSize(0)
218  {
219  }
220 
221  virtual ~ChannelBufferBase();
222 
223 public:
224 
229  {
230  mMinSlots = other.mMinSlots;
231  mMaxSlots = other.mMaxSlots;
232  mStorageDuration = other.mStorageDuration;
233  mAutoIncreaseStorageDuration = other.mAutoIncreaseStorageDuration;
234  }
235 
236 public:
237 
246  void setStorageDuration(const Duration& storageDuration);
247 
248 
256  void setAutoIncreaseStorageDuration(bool increase);
257 
267  void setMinSlots(std::size_t minSlots);
268 
269 
279  void setMaxSlots(std::size_t maxSlots);
280 
281 public:
282 
284  std::size_t getSize() const;
285 
287  std::size_t getMaxSlots() const;
288 
290  std::size_t getMinSlots() const;
291 
293  Duration getStorageDuration() const;
294 
296  bool isAutoIncreasingStorageDuration() const;
297 
298 
299 public:
300 
302  virtual int getTypeId() const = 0;
303 
305  virtual bool isTyped() const = 0;
306 
308  virtual bool isPolymorphic() const = 0;
309 
315  virtual Typename getTypename() const = 0;
316 
320  virtual void setTypename(const Typename& name) = 0;
321 
326  virtual TypeMetaPtr createTypeMeta(Slot* s, MetaTypeDatabase& ioDB) = 0;
327 
331  TypeMetaPtr getTypeMeta() const { return mTypeMeta; }
332 
336  void setTypeMeta(TypeMetaPtr meta) { mTypeMeta = meta; }
337 
345  virtual void fixateType() = 0;
346 
348  virtual Slot* allocateSlot() = 0;
349 
351  virtual void freeSlot(Slot* s) = 0;
352 
356  virtual StampedHeader& getStampedHeader(Slot* s) = 0;
357 
362  virtual const Buffer<uint8>& readSerializedValue(Slot* s) = 0;
363 
370  virtual const Buffer<uint8>& readSerializedValue(Slot* s,
371  uint8 formatVersion, bool orLower) = 0;
372 
378  virtual Buffer<uint8> readSerializedValue(Slot* s,
379  std::list<BinarySerializerCodecPtr>& codecs) = 0;
380 
388  virtual Buffer<uint8> readSerializedValue(Slot* s,
389  std::list<BinarySerializerCodecPtr>& codecs,
390  uint8 formatVersion, bool orLower) = 0;
391 
396  virtual void writeSerializedValue(Slot* s, Buffer<uint8> data) = 0;
397 
405  virtual void readJSON(Slot* s, JSONValue& oValue) = 0;
406 
413  virtual void readJSON(Slot* s, JSONValue& oValue, JSONSerializer& serializer) = 0;
414 
422  virtual void writeJSON(Slot* s, const JSONValue& value) = 0;
423 
430  virtual void writeJSON(Slot* s, JSONDeserializer& value) = 0;
431 
438  virtual void writeXML(Slot* s, const XMLDom::const_iterator& node) = 0;
439 
440 public:
441 
443  // write access
444 
467  Slot* requestWriteSlot();
468 
477  bool finishWriteSlot(Slot* n, bool* dropped=NULL);
478 
483  void discardWriteSlot(Slot* n);
484 
485 
487  // read access
488 
494  Slot* readNewestSlot();
495 
502  Slot* readSlotAtTime(const Time& timestamp, SlotQueryMode mode);
503 
509  void readInterval(const Time& timestamp, std::size_t nrSlots,
510  std::size_t olderSlots, std::size_t newerSlots,
511  IntervalFillMode fillMode, std::list<Slot*>& oSlots);
512 
518  void readInterval(const Time& from, const Time& to, std::list<Slot*>& oSlots);
519 
520 public:
521 
530  template<typename TargetType>
531  ChannelBufferBase* promote();
532 
533 private:
534 
540  Slot* findFirstOlderSlot(const Time& timestamp, Slot* start=NULL);
541 
542 private:
543 
548  void splice(Slot* first, Slot* last, Slot* position) const;
549 
554  void splice(Slot* item, Slot* position) const {
555  splice(item,item,position);
556  }
557 
558  static bool isEmpty(const ListItem& list) { return list.next == &list; }
559  static Slot* begin(ListItem& list) { return list.next; }
560  static Slot* last(ListItem& list) { return list.prev; }
561  static Slot* end(ListItem& list) { return (Slot*)&list; }
562 
564  void deleteSlots(ListItem& list);
565 
566 protected:
567 
569  void clear();
570 
571 private:
572 
577  void resetSlot(Slot* s);
578 
579  // parameters:
580  Duration mStorageDuration;
581  bool mAutoIncreaseStorageDuration;
582  std::size_t mMinSlots;
583  std::size_t mMaxSlots;
584 
585 
586  // mutex that locks all actions when we change our lists
587  mutable boost::mutex mMutex;
588 
589  std::size_t mSize; // current number of slots we are using
590 
591  ListItem mBuffer;
592 
605  ListItem mWaitingOrFree;
606 
610  ListItem mWriting;
611 
612  TypeMetaPtr mTypeMeta;
613 
614 private:
615 
616  std::string dbgDumpList(ListItem& list, bool brief);
617 
618 public:
619 
620  void dbgDump(const std::string& prefix, bool brief=true);
621 
622  static void dbgCheckListIntegrity(const ListItem& list);
623  void dbgCheckIntegrity();
624 };
625 
627 
631 template <typename T>
633 {
634 public:
635 
637 
638 public:
639 
640  virtual ~TypedChannelBufferBase() { this->clear(); }
641 
642 public:
643 
645  struct Slot : public ChannelBufferBase::Slot {
648  EIGEN_MAKE_ALIGNED_OPERATOR_NEW
649 
650  std::unique_ptr<ChannelBufferBase::Slot> clone() override {
651  auto slot = std::make_unique<Slot>();
652  slot->serializedValue = this->serializedValue;
653  slot->timestampPtr = &(static_cast<StampedHeader&>(slot->data).timestamp);
654  slot->flags = this->flags;
655  slot->data = this->data;
656  return slot;
657  }
658  };
659 
660 protected:
661 
666  {
667  // cast abstract ChannelBufferBase::Slot to TypedChannelBufferBase<T>::Slot.
668  // this is safe since all slots were created by us in allocateSlot()
669  // as TypedChannelBufferBase<T>::Slots
670  return static_cast<Slot*>(s);
671  }
672 
673 public:
678  virtual int getTypeId() const { return typeId<T>(); }
679  virtual bool isTyped() const { return true; }
680  virtual bool isPolymorphic() const {return false; }
681  virtual Typename getTypename() const { return typeName<T>(); }
682  virtual void setTypename(const Typename& name) {
683  MIRA_THROW(XRuntime, "Cannot set Typename for typed channels");
684  }
686  MetaSerializer ms(ioDB);
687  Slot* slot = castSlot(s);
688  TypeMetaPtr meta = ms.addMeta(slot->data.internalValueRep());
689  return meta;
690  }
691 
692  virtual void fixateType() {} // doesn't do anything
694  Slot* slot = new Slot;
695  slot->timestampPtr = &(static_cast<StampedHeader&>(slot->data).timestamp); // "connect" the timestamp ptr
696  return slot;
697  }
699  // casting s to our slot type ensures that the correct destructor is called
700  Slot* slot = castSlot(s);
701  delete slot;
702  }
703 
704 public:
705 
707  // we can safely cast here, since s is an object of our Slot type
708  Slot* slot = static_cast<Slot*>(s);
709  return stampedHeader(slot->data);
710  }
711 
713  {
714  // lock the serialization mutex to protect serializedValueLock
715  // (we or someone else may write it here)
716  boost::mutex::scoped_lock lock(s->serializedValueLock);
717 
718  // no serialized data yet, so serialize it now (lazy evaluation)
719  if(s->serializedValue.empty()) {
720  // we can safely cast here, since s is an object of our Slot type
721  Slot* slot = static_cast<Slot*>(s);
722 
723  // serialize the data
725  bs.serialize(slot->data.internalValueRep(), false);
726  }
727 
728  return s->serializedValue;
729  }
730 
731 
733  uint8 formatVersion, bool orLower)
734  {
735  uint8 serializerVersion = BinaryBufferSerializer::getSerializerFormatVersion();
736 
737  if (formatVersion == serializerVersion)
738  return readSerializedValue(s);
739 
740  if (formatVersion == 0) {
741  // lock the serialization mutex to protect serializedValueLock
742  // (we or someone else may write it here)
743  boost::mutex::scoped_lock lock(s->serializedValueLock);
744 
745  // no serialized data yet, so serialize it now (lazy evaluation)
746  if(s->serializedValue.empty()) {
747  // we can safely cast here, since s is an object of our Slot type
748  Slot* slot = static_cast<Slot*>(s);
749 
750  // serialize the data
752  bs.serialize(slot->data.internalValueRep(), false);
753  }
754 
755  return s->serializedValue;
756  }
757 
758  MIRA_THROW(XIO, "Requested serialized data of binary format version " << (int)formatVersion
759  << ". Only implemented for versions 0, " << (int)serializerVersion << ".");
760  }
761 
763  std::list<BinarySerializerCodecPtr>& codecs)
764  {
765  Buffer<uint8> serializedValue;
766 
767  // we can safely cast here, since s is an object of our Slot type
768  Slot* slot = static_cast<Slot*>(s);
769 
770  BinaryBufferSerializer bs(&serializedValue);
771 
772  // register codecs
773  foreach(BinarySerializerCodecPtr codec, codecs)
774  bs.registerCodec(codec);
775 
776  // serialize the data
777  bs.serialize(slot->data.internalValueRep(),false);
778 
779  return std::move(serializedValue);
780  }
781 
783  std::list<BinarySerializerCodecPtr>& codecs,
784  uint8 formatVersion, bool orLower)
785  {
786  uint8 serializerVersion = BinaryBufferSerializer::getSerializerFormatVersion();
787 
788  if (formatVersion == serializerVersion)
789  return readSerializedValue(s, codecs);
790 
791  if (formatVersion == 0) {
792  Buffer<uint8> serializedValue;
793 
794  // we can safely cast here, since s is an object of our Slot type
795  Slot* slot = static_cast<Slot*>(s);
796 
797  BinaryBufferSerializerLegacy bs(&serializedValue);
798 
799  // register codecs
800  foreach(BinarySerializerCodecPtr codec, codecs)
801  bs.registerCodec(codec);
802 
803  // serialize the data
804  bs.serialize(slot->data.internalValueRep(),false);
805 
806  return std::move(serializedValue);
807  }
808 
809  MIRA_THROW(XIO, "Requested serialized data of binary format version " << (int)formatVersion
810  << ". Only implemented for versions 0, " << (int)serializerVersion << ".");
811  }
812 
814  {
815  s->serializedValue = std::move(data);
816 
817  // we can safely cast here, since s is an object of our Slot type
818  Slot* slot = static_cast<Slot*>(s);
819 
820  // deserialize into our data
822 
823  {
824  boost::mutex::scoped_lock lock(mCodecsMutex);
825  bs.setCodecs(mCodecs);
826  }
827  bs.deserialize(slot->data.internalValueRep(), false);
828  {
829  boost::mutex::scoped_lock lock(mCodecsMutex);
830  mCodecs = bs.getCodecs();
831  }
832  }
833 
834  virtual void readJSON(ChannelBufferBase::Slot* s, JSONValue& oValue)
835  {
836  // we can safely cast here, since s is an object of our Slot type
837  Slot* slot = static_cast<Slot*>(s);
838 
839  JSONSerializer json;
840  oValue = json.serialize(slot->data.internalValueRep());
841  }
842 
843  virtual void readJSON(ChannelBufferBase::Slot* s, JSONValue& oValue,
844  JSONSerializer& serializer)
845  {
846  // we can safely cast here, since s is an object of our Slot type
847  Slot* slot = static_cast<Slot*>(s);
848 
849  oValue = serializer.serialize(slot->data.internalValueRep());
850  }
851 
852  virtual void writeJSON(ChannelBufferBase::Slot* s, const JSONValue& value)
853  {
854  // we can safely cast here, since s is an object of our Slot type
855  Slot* slot = static_cast<Slot*>(s);
856 
857  JSONDeserializer json(value);
858  json.deserialize(slot->data.internalValueRep());
859  }
860 
861  virtual void writeJSON(ChannelBufferBase::Slot* s, JSONDeserializer& deserializer)
862  {
863  // we can safely cast here, since s is an object of our Slot type
864  Slot* slot = static_cast<Slot*>(s);
865 
866  deserializer.deserialize(slot->data.internalValueRep());
867  }
868 
870  {
871  // we can safely cast here, since s is an object of our Slot type
872  Slot* slot = static_cast<Slot*>(s);
873  XMLDeserializer xml(node);
874  const std::string rootTag = *node;
875  xml.deserializeFromNode(rootTag.c_str(), slot->data.internalValueRep());
876  }
878 
879 private:
880 
882  boost::mutex mCodecsMutex;
883 };
884 
885 
887 
891 template <typename T>
893 {};
894 
896 
901 template <>
903 {
904 public:
905 
907 
908 public:
909 
911  struct Slot : public ChannelBufferBase::Slot {
913  EIGEN_MAKE_ALIGNED_OPERATOR_NEW
914 
915  std::unique_ptr<ChannelBufferBase::Slot> clone() override {
916  auto slot = std::make_unique<Slot>();
917  slot->serializedValue = this->serializedValue;
918  slot->timestampPtr = &slot->header.timestamp;
919  slot->flags = this->flags;
920  slot->header = this->header;
921  return slot;
922  }
923  };
924 
925 protected:
926 
931  {
932  return static_cast<Slot*>(s);
933  }
934 
935 public:
936 
937  ChannelBuffer() : mTypename("") {}
938 
939  virtual ~ChannelBuffer() { this->clear(); }
940 
941 
942 public:
947  virtual int getTypeId() const { return -1; }
948  virtual bool isTyped() const { return false; }
949  virtual bool isPolymorphic() const {return false; }
950  virtual Typename getTypename() const { return mTypename; }
951  virtual void setTypename(const Typename& name);
953  MIRA_THROW(XRuntime, "Cannot create type meta for untyped channels");
954  // keep compiler happy
955  return TypeMetaPtr();
956  }
957  virtual void fixateType() {} // doesn't do anything
958 
960  Slot* slot = new Slot;
961  slot->timestampPtr = &slot->header.timestamp; // "connect" the timestamp ptr
962  return slot;
963  }
964 
966  // casting s to our slot type ensures that the correct destructor is called
967  Slot* slot = castSlot(s);
968  delete slot;
969  }
970 
971 public:
972 
974  // casting here is not safe, if we actually are a typed buffer,
975  // however, if we are, then the TypedChannelBuffer::getStampedHeader()
976  // of that class would have been called instead of us.
977  Slot* slot = static_cast<Slot*>(s);
978  return slot->header;
979  }
980 
982  {
983  return s->serializedValue;
984  }
985 
987  uint8 formatVersion, bool orLower)
988  {
989  BinaryBufferIstream stream(&(s->serializedValue));
990  uint8 dataVersion = BinaryBufferDeserializer::getDataFormatVersion(stream);
991  if ((!orLower && (dataVersion != formatVersion)) || (dataVersion > formatVersion)) {
992  MIRA_THROW(XIO, "Untyped channel contains serialized data of version " << (int)dataVersion
993  << ", cannot return data of version " << (int)formatVersion << ".");
994  }
995 
996  return readSerializedValue(s);
997  }
998 
999 
1001  std::list<BinarySerializerCodecPtr>& codecs)
1002  {
1003  // we must ignore the codecs
1004  return s->serializedValue;
1005  }
1006 
1008  std::list<BinarySerializerCodecPtr>& codecs,
1009  uint8 formatVersion, bool orLower)
1010  {
1011  // we must ignore the codecs
1012  return readSerializedValue(s, formatVersion, orLower);
1013  }
1014 
1016  {
1017  s->serializedValue = std::move(data);
1018  }
1019 
1020  virtual void readJSON(ChannelBufferBase::Slot* s, JSONValue& oValue);
1021  virtual void readJSON(ChannelBufferBase::Slot* s, JSONValue& oValue, JSONSerializer& serializer);
1022 
1023  virtual void writeJSON(ChannelBufferBase::Slot* s, const JSONValue& value);
1024  virtual void writeJSON(ChannelBufferBase::Slot* s, JSONDeserializer& deserializer);
1025  void writeXML(ChannelBufferBase::Slot* s, const XMLDom::const_iterator& node) override;
1026 
1028 
1029 private:
1030 
1031  Typename mTypename;
1032 };
1033 
1035 
1040 {
1042 
1043 public:
1044 
1047  mMostDerivedClass(NULL),
1048  mFixatedClass(NULL) {}
1049 
1050 public:
1055  virtual bool isPolymorphic() const {return true; }
1056 
1057  virtual int getTypeId() const;
1058 
1059  virtual Typename getTypename() const;
1060 
1061  virtual ChannelBufferBase::Slot* allocateSlot();
1062 
1063  virtual void freeSlot(ChannelBufferBase::Slot* s);
1064 
1065  virtual void fixateType();
1066 
1067  virtual void writeSerializedValue(ChannelBufferBase::Slot* s, Buffer<uint8> data);
1069 
1071  void promote(const Class* promotionClass);
1072 
1073 protected:
1074 
1077 };
1078 
1079 #ifndef MIRA_WINDOWS
1080 // declare template extern to speed up compilation time by several seconds
1081 extern template class TypedChannelBufferBase<Object*>;
1082 #endif
1083 
1085 
1090 template <typename T>
1092 {
1093  static_assert(std::is_base_of<mira::Object,T>::value,
1094  "In channels you can only use pointers of polymorphic "
1095  "classes that are derived from mira::Object. Pointers to "
1096  "other classes cannot be stored in a channel.");
1097 public:
1098  typedef Stamped<T*> ValueType;
1099 
1100 public:
1102  mMostDerivedClass = &T::CLASS();
1103  }
1104 };
1105 
1107 // Channel buffer promotion code
1108 
1115 template <typename U>
1116 struct ChannelBufferPromoterCommon
1117 {
1119  {
1120  assert(!buffer->isTyped() &&
1121  "Can promote untyped channels to typed channels only");
1122 
1123  if(!buffer->getTypename().empty() && buffer->getTypename()!=typeName<U>())
1124  MIRA_THROW(XBadCast, "Invalid promotion from untyped to typed "
1125  "ChannelBuffer. Typename does not match. ('" <<
1126  buffer->getTypename() << "' != '" << typeName<U>() << "'");
1127 
1128  typedef ChannelBufferBase::Slot Slot;
1129 
1130  // create a new typed buffer
1131  ChannelBuffer<U>* typedBuffer = new ChannelBuffer<U>;
1132 
1133  // copy all parameters
1134  typedBuffer->cloneParameters(*buffer);
1135 
1136  // copy all the serialized data from the untyped buffer into the
1137  // typed buffer and deserialize it into the value
1138 
1139  // now lock the whole buffer for reading ...
1140  for(Slot* s=ChannelBufferBase::begin(buffer->mBuffer);
1141  s!=ChannelBufferBase::end(buffer->mBuffer); s=s->next)
1142  s->lock.lock_shared();
1143 
1144  // ... and deserialize the content of each slot into the new buffer
1145  for(Slot* s=ChannelBufferBase::begin(buffer->mBuffer);
1146  s!=ChannelBufferBase::end(buffer->mBuffer); s=s->next)
1147  {
1148  Slot* n = typedBuffer->requestWriteSlot(); // obtain a new slot
1149 
1150  // ... copy the headers
1151  typedBuffer->getStampedHeader(n) = buffer->getStampedHeader(s);
1152 
1153  // ... and write the value into the new slot (this will deserialize the data there)
1154  typedBuffer->writeSerializedValue(n, s->serializedValue);
1155 
1156  typedBuffer->finishWriteSlot(n);
1157  }
1158 
1159  // free the read lock from above ...
1160  for(Slot* s=ChannelBufferBase::begin(buffer->mBuffer);
1161  s!=ChannelBufferBase::end(buffer->mBuffer); s=s->next)
1162  s->lock.unlock_shared();
1163 
1164  return typedBuffer;
1165  }
1166 };
1167 
1169 
1180 template <typename U>
1181 struct ChannelBufferPromoter : public ChannelBufferPromoterCommon<U>
1182 {
1185  {
1186  if(buffer->isTyped())
1187  return buffer; // we are promoted already, do nothing
1188  return Base::promoteUntyped(buffer);
1189  }
1190 };
1191 
1193 
1198 template <typename U>
1200 {
1203  {
1204  // if untyped, promote to typed first
1205  if(!buffer->isTyped())
1206  buffer = Base::promoteUntyped(buffer);
1207 
1208  PolymorphicChannelBuffer* polymorphicBuffer = dynamic_cast<PolymorphicChannelBuffer*>(buffer);
1209 
1210  assert(polymorphicBuffer!=NULL &&
1211  "We should never reach here if the buffer to promote is not "
1212  "polymorphic");
1213 
1214  // get class of U
1215  const Class* classU = &U::CLASS();
1216 
1217  // promote us (this will do error checking and might throw XBadCast)
1218  polymorphicBuffer->promote(classU);
1219 
1220  return polymorphicBuffer;
1221  }
1222 };
1223 
1225 
1226 template<typename U>
1228 {
1229  return ChannelBufferPromoter<U>::promote(this);
1230 }
1231 
1233 
1234 }
1235 
1236 #endif
Serializer for serializing objects in JSON format.
Definition: JSONSerializer.h:93
virtual void writeJSON(ChannelBufferBase::Slot *s, const JSONValue &value)
Writes data in json representation into the slot, using a default-instantiated JSONDeserializer.
Definition: ChannelBuffer.h:852
virtual void freeSlot(ChannelBufferBase::Slot *s)
Called to destroy the slot and free the used memory.
Definition: ChannelBuffer.h:698
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:427
boost::shared_mutex lock
Definition: ChannelBuffer.h:168
static ChannelBufferBase * promote(ChannelBufferBase *buffer)
Definition: ChannelBuffer.h:1202
EIGEN_MAKE_ALIGNED_OPERATOR_NEW std::unique_ptr< ChannelBufferBase::Slot > clone() override
Definition: ChannelBuffer.h:650
Definition: BinarySerializer.h:324
const Time * timestampPtr
Pointer to the actual timestamp in the slot data for easy access.
Definition: ChannelBuffer.h:180
const Class * mFixatedClass
Definition: ChannelBuffer.h:1076
virtual TypeMetaPtr createTypeMeta(ChannelBufferBase::Slot *s, MetaTypeDatabase &ioDB)
Creates meta information for data in slot and stores all meta information in the given database...
Definition: ChannelBuffer.h:952
boost::mutex serializedValueLock
Lock for writing serializedValue in readSerializedData.
Definition: ChannelBuffer.h:175
const Class * mMostDerivedClass
Definition: ChannelBuffer.h:1075
Include file for all eigen related things.
virtual ~ChannelBuffer()
Definition: ChannelBuffer.h:939
Typed slot derived from ChannelBufferBase::Slot.
Definition: ChannelBuffer.h:645
void promote(const Class *promotionClass)
Promotes the polymorphic type of the channel to the given class type.
The first slot with timestamp < requested will be chosen.
Definition: ChannelBuffer.h:98
virtual void writeSerializedValue(ChannelBufferBase::Slot *s, Buffer< uint8 > data)
Write the given buffer (that contains binary serialized data WITHOUT the StampedHeader) to the slot...
Definition: ChannelBuffer.h:1015
virtual Buffer< uint8 > readSerializedValue(ChannelBufferBase::Slot *s, std::list< BinarySerializerCodecPtr > &codecs, uint8 formatVersion, bool orLower)
Returns a buffer containing the binary serialized data of the slot.
Definition: ChannelBuffer.h:782
Slot * castSlot(ChannelBufferBase::Slot *s)
Cast an abstract slot to a typed slot.
Definition: ChannelBuffer.h:930
specialize cv::DataType for our ImgPixel and inherit from cv::DataType<Vec>
Definition: IOService.h:67
std::string Typename
Definition: Typename.h:60
virtual ChannelBufferBase::Slot * allocateSlot()
Creates and returns a new slot.
Definition: ChannelBuffer.h:693
Specialization for polymorphic types (only classes derived from mira::Object are supported!) ...
Definition: ChannelBuffer.h:1091
ValueType header
Definition: ChannelBuffer.h:912
virtual bool isTyped() const
Returns true, if the channel is typed and false, if it is untyped.
Definition: ChannelBuffer.h:948
Time and Duration wrapper class.
Class object which supports some kind of class reflection.
Definition: Class.h:97
virtual Typename getTypename() const
Returns the Typename of the slot values, in contrast to getTypeId() the Typename is portable and uniq...
Definition: ChannelBuffer.h:950
ListItem()
Definition: ChannelBuffer.h:152
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:1227
TypeMetaPtr getTypeMeta() const
Returns the meta information for the slots type.
Definition: ChannelBuffer.h:331
Base class for typed channel buffers.
Definition: ChannelBuffer.h:632
virtual void fixateType()
Calling this method will fix the type of the ChannelBuffer.
Definition: ChannelBuffer.h:692
static ChannelBufferBase * promoteUntyped(ChannelBufferBase *buffer)
Definition: ChannelBuffer.h:1118
Get compiler and platform independent typenames.
Framework export macro declaration.
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:82
void serialize(const T &value, bool enableTypeCheck=true)
Provides a special serialize interface for the BinarySerializer.
Definition: BinarySerializer.h:598
Implements double-linked list item.
Definition: ChannelBuffer.h:150
Const sibling_iterator for iterating over xml nodes that have the same parent (siblings) ...
Definition: XMLDom.h:671
virtual StampedHeader & getStampedHeader(ChannelBufferBase::Slot *s)
Returns a reference to the stamped header information.
Definition: ChannelBuffer.h:973
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.
ChannelBufferPromoterCommon< U > Base
Definition: ChannelBuffer.h:1201
virtual const Buffer< uint8 > & readSerializedValue(ChannelBufferBase::Slot *s, uint8 formatVersion, bool orLower)
Returns a buffer containing the binary serialized data of the slot.
Definition: ChannelBuffer.h:732
ChannelBuffer()
Definition: ChannelBuffer.h:1101
A channel buffer for polymorphic types (classes derived from mira::Object)
Definition: ChannelBuffer.h:1039
Deserializer for serializing objects from JSON format.
Definition: JSONSerializer.h:400
virtual int getTypeId() const
Returns typeid of the slot values, the allocator creates.
Definition: ChannelBuffer.h:947
virtual ~TypedChannelBufferBase()
Definition: ChannelBuffer.h:640
void setTypeMeta(TypeMetaPtr meta)
Sets the meta information of the slot&#39;s type.
Definition: ChannelBuffer.h:336
Binary serializer and deserializer.
PolymorphicChannelBuffer()
Constructor.
Definition: ChannelBuffer.h:1046
forward decl.
Definition: ChannelBuffer.h:83
void registerCodec(BinarySerializerCodecPtr codec)
Registers the specified codec instance in this binary serializer.
Definition: BinarySerializer.h:764
virtual Buffer< uint8 > readSerializedValue(ChannelBufferBase::Slot *s, std::list< BinarySerializerCodecPtr > &codecs)
Returns a buffer containing the binary serialized data of the slot.
Definition: ChannelBuffer.h:1000
virtual void writeSerializedValue(ChannelBufferBase::Slot *s, Buffer< uint8 > data)
Write the given buffer (that contains binary serialized data WITHOUT the StampedHeader) to the slot...
Definition: ChannelBuffer.h:813
virtual bool isPolymorphic() const
Returns true if the channel has a polymorphic type.
Definition: ChannelBuffer.h:949
Definition: MetaSerializer.h:586
virtual TypeMetaPtr createTypeMeta(ChannelBufferBase::Slot *s, MetaTypeDatabase &ioDB)
Creates meta information for data in slot and stores all meta information in the given database...
Definition: ChannelBuffer.h:685
Slot * castSlot(ChannelBufferBase::Slot *s)
Cast an abstract slot to a typed slot.
Definition: ChannelBuffer.h:665
virtual StampedHeader & getStampedHeader(ChannelBufferBase::Slot *s)
Returns a reference to the stamped header information.
Definition: ChannelBuffer.h:706
#define MIRA_FRAMEWORK_EXPORT
Definition: FrameworkExports.h:61
Stamped< T * > ValueType
Definition: ChannelBuffer.h:1096
Core class of the logging library.
Use this class to represent time durations.
Definition: Time.h:106
virtual bool isPolymorphic() const
Returns true if the channel has a polymorphic type.
Definition: ChannelBuffer.h:680
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:1581
bool empty() const
Checks if the buffer is empty (used size == 0).
Definition: Buffer.h:303
Typed ChannelBuffer.
Definition: ChannelBuffer.h:892
The slot with smallest time difference to the requested will be chosen.
Definition: ChannelBuffer.h:104
virtual StampedHeader & getStampedHeader(Slot *s)=0
Returns a reference to the stamped header information.
ChannelBuffer()
Definition: ChannelBuffer.h:937
virtual const Buffer< uint8 > & readSerializedValue(ChannelBufferBase::Slot *s, uint8 formatVersion, bool orLower)
Returns a buffer containing the binary serialized data of the slot.
Definition: ChannelBuffer.h:986
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
virtual int getTypeId() const
Returns typeid of the slot values, the allocator creates.
Definition: ChannelBuffer.h:678
virtual void freeSlot(ChannelBufferBase::Slot *s)
Called to destroy the slot and free the used memory.
Definition: ChannelBuffer.h:965
Mix in for adding a timestamp to data types.
virtual Buffer< uint8 > readSerializedValue(ChannelBufferBase::Slot *s, std::list< BinarySerializerCodecPtr > &codecs, uint8 formatVersion, bool orLower)
Returns a buffer containing the binary serialized data of the slot.
Definition: ChannelBuffer.h:1007
virtual void readJSON(ChannelBufferBase::Slot *s, JSONValue &oValue, JSONSerializer &serializer)
Reads data of that slot as json representation using the provided JSONSerializer. ...
Definition: ChannelBuffer.h:843
Stamped< T > ValueType
Definition: ChannelBuffer.h:636
Serializer for creating meta information out of types using serialization.
void cloneParameters(const ChannelBufferBase &other)
Copies the parameters of other to this.
Definition: ChannelBuffer.h:228
forward decl.
Definition: ChannelBuffer.h:87
virtual bool isPolymorphic() const
Returns true if the channel has a polymorphic type.
Definition: ChannelBuffer.h:1055
ValueType data
the actual data value, that is stored in this channel&#39;s slots
Definition: ChannelBuffer.h:647
Base class that manages the slots of channels by providing read and write access to them...
Definition: ChannelBuffer.h:134
const Time & timestamp() const
Definition: ChannelBuffer.h:196
Container for storing a single data element in the linked list.
Definition: ChannelBuffer.h:166
bool finishWriteSlot(Slot *n, bool *dropped=NULL)
Adds written slot into buffer at the right time position.
void setCodecs(const CodecsMap &codecs)
Set the map of known codecs.
Definition: BinarySerializer.h:1586
virtual void setTypename(const Typename &name)
Sets the Typename of the slot values.
Definition: ChannelBuffer.h:682
virtual void fixateType()
Calling this method will fix the type of the ChannelBuffer.
Definition: ChannelBuffer.h:957
Input stream adapter that can be assigned to any input stream and allows binary input using the >> st...
Definition: BinaryStream.h:523
Slot * next
Definition: ChannelBuffer.h:159
Buffer< uint8 > serializedValue
The data of this slot as serialized data.
Definition: ChannelBuffer.h:186
virtual void readJSON(ChannelBufferBase::Slot *s, JSONValue &oValue)
Reads data of that slot as json representation using a default-instantiated JSONSerializer.
Definition: ChannelBuffer.h:834
virtual const Buffer< uint8 > & readSerializedValue(ChannelBufferBase::Slot *s)
Returns a buffer containing the binary serialized data of the slot.
Definition: ChannelBuffer.h:981
void deserialize(T &value, bool enableTypeCheck=true, bool recursive=false)
Provides a special deserialize interface for the BinaryDeserializer.
Definition: BinarySerializer.h:1340
StampedHeader ValueType
Definition: ChannelBuffer.h:906
virtual bool isTyped() const
Returns true, if the channel is typed and false, if it is untyped.
Definition: ChannelBuffer.h:679
ChannelBufferPromoterCommon< U > Base
Definition: ChannelBuffer.h:1183
TypeMetaPtr addMeta(const T &v)
Definition: MetaSerializer.h:605
virtual ChannelBufferBase::Slot * allocateSlot()
Creates and returns a new slot.
Definition: ChannelBuffer.h:959
XMLSerializer and XMLDeserializer.
Prefer filling the interval with slots with timestamp > requested.
Definition: ChannelBuffer.h:116
Prefer filling the interval with slots with timestamp < requested.
Definition: ChannelBuffer.h:114
EIGEN_MAKE_ALIGNED_OPERATOR_NEW std::unique_ptr< ChannelBufferBase::Slot > clone() override
Definition: ChannelBuffer.h:915
uint32 flags
Used to store internal flags that are especially used by the remote capability of the framework...
Definition: ChannelBuffer.h:194
static ChannelBufferBase * promote(ChannelBufferBase *buffer)
Definition: ChannelBuffer.h:1184
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:358
IntervalFillMode
Mode that is used to determine what slots should be added to the interval when not enough slots are a...
Definition: ChannelBuffer.h:111
virtual const Buffer< uint8 > & readSerializedValue(ChannelBufferBase::Slot *s)
Returns a buffer containing the binary serialized data of the slot.
Definition: ChannelBuffer.h:712
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:869
virtual Buffer< uint8 > readSerializedValue(ChannelBufferBase::Slot *s, std::list< BinarySerializerCodecPtr > &codecs)
Returns a buffer containing the binary serialized data of the slot.
Definition: ChannelBuffer.h:762
Specialization of ChannelBufferPromoter for polymorphic pointer channel buffers.
Definition: ChannelBuffer.h:1199
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:95
json::Value JSONValue
Imports the json::Value type into mira namespace.
Definition: JSON.h:363
void clear()
Deletes all slots in all lists and therefore clears the whole buffer.
Provides method for generating a unique id for any type.
Slot * prev
Definition: ChannelBuffer.h:160
virtual Typename getTypename() const
Returns the Typename of the slot values, in contrast to getTypeId() the Typename is portable and uniq...
Definition: ChannelBuffer.h:681
ChannelBufferBase()
Constructor.
Definition: ChannelBuffer.h:212
Serializer and Deserializer for JSON format.
virtual void writeJSON(ChannelBufferBase::Slot *s, JSONDeserializer &deserializer)
Writes data from an initialized json deserializer into the slot.
Definition: ChannelBuffer.h:861
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:101
std::map< TypeId, BinarySerializerCodecPtr > CodecsMap
A map of binary serialization codecs.
Definition: BinarySerializer.h:1270
boost::shared_ptr< BinarySerializerCodec > BinarySerializerCodecPtr
Shared pointer of BinarySerializerCodec.
Definition: BinarySerializerCodec.h:64
Deserializer for serializing objects from XML format.
Definition: XMLSerializer.h:313