00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #ifndef ROSCPP_MESSAGE_EVENT_H
00030 #define ROSCPP_MESSAGE_EVENT_H
00031
00032 #include "ros/time.h"
00033 #include <ros/datatypes.h>
00034 #include <ros/message_traits.h>
00035
00036 #include <boost/type_traits/is_void.hpp>
00037 #include <boost/type_traits/is_base_of.hpp>
00038 #include <boost/type_traits/is_const.hpp>
00039 #include <boost/type_traits/add_const.hpp>
00040 #include <boost/type_traits/remove_const.hpp>
00041 #include <boost/utility/enable_if.hpp>
00042 #include <boost/function.hpp>
00043 #include <boost/make_shared.hpp>
00044
00045 namespace ros
00046 {
00047
00048 template<typename M>
00049 struct DefaultMessageCreator
00050 {
00051 boost::shared_ptr<M> operator()()
00052 {
00053 return boost::make_shared<M>();
00054 }
00055 };
00056
00057 template<typename M>
00058 ROS_DEPRECATED inline boost::shared_ptr<M> defaultMessageCreateFunction()
00059 {
00060 return DefaultMessageCreator<M>()();
00061 }
00062
00068 template<typename M>
00069 class MessageEvent
00070 {
00071 public:
00072 typedef typename boost::add_const<M>::type ConstMessage;
00073 typedef typename boost::remove_const<M>::type Message;
00074 typedef boost::shared_ptr<Message> MessagePtr;
00075 typedef boost::shared_ptr<ConstMessage> ConstMessagePtr;
00076 typedef boost::function<MessagePtr()> CreateFunction;
00077
00078 MessageEvent()
00079 : nonconst_need_copy_(true)
00080 {}
00081
00082 MessageEvent(const MessageEvent<Message>& rhs)
00083 {
00084 *this = rhs;
00085 }
00086
00087 MessageEvent(const MessageEvent<ConstMessage>& rhs)
00088 {
00089 *this = rhs;
00090 }
00091
00092 MessageEvent(const MessageEvent<Message>& rhs, bool nonconst_need_copy)
00093 {
00094 *this = rhs;
00095 nonconst_need_copy_ = nonconst_need_copy;
00096 }
00097
00098 MessageEvent(const MessageEvent<ConstMessage>& rhs, bool nonconst_need_copy)
00099 {
00100 *this = rhs;
00101 nonconst_need_copy_ = nonconst_need_copy;
00102 }
00103
00104 MessageEvent(const MessageEvent<void const>& rhs, const CreateFunction& create)
00105 {
00106 init(boost::const_pointer_cast<Message>(boost::static_pointer_cast<ConstMessage>(rhs.getMessage())), rhs.getConnectionHeaderPtr(), rhs.getReceiptTime(), rhs.nonConstWillCopy(), create);
00107 }
00108
00112 MessageEvent(const ConstMessagePtr& message)
00113 {
00114 init(message, getConnectionHeader(message.get()), ros::Time::now(), true, ros::DefaultMessageCreator<Message>());
00115 }
00116
00117 MessageEvent(const ConstMessagePtr& message, const boost::shared_ptr<M_string>& connection_header, ros::Time receipt_time)
00118 {
00119 init(message, connection_header, receipt_time, true, ros::DefaultMessageCreator<Message>());
00120 }
00121
00122 MessageEvent(const ConstMessagePtr& message, ros::Time receipt_time)
00123 {
00124 init(message, getConnectionHeader(message.get()), receipt_time, true, ros::DefaultMessageCreator<Message>());
00125 }
00126
00127 MessageEvent(const ConstMessagePtr& message, const boost::shared_ptr<M_string>& connection_header, ros::Time receipt_time, bool nonconst_need_copy, const CreateFunction& create)
00128 {
00129 init(message, connection_header, receipt_time, nonconst_need_copy, create);
00130 }
00131
00132 void init(const ConstMessagePtr& message, const boost::shared_ptr<M_string>& connection_header, ros::Time receipt_time, bool nonconst_need_copy, const CreateFunction& create)
00133 {
00134 message_ = message;
00135 connection_header_ = connection_header;
00136 receipt_time_ = receipt_time;
00137 nonconst_need_copy_ = nonconst_need_copy;
00138 create_ = create;
00139 }
00140
00141 void operator=(const MessageEvent<Message>& rhs)
00142 {
00143 init(boost::static_pointer_cast<Message>(rhs.getMessage()), rhs.getConnectionHeaderPtr(), rhs.getReceiptTime(), rhs.nonConstWillCopy(), rhs.getMessageFactory());
00144 message_copy_.reset();
00145 }
00146
00147 void operator=(const MessageEvent<ConstMessage>& rhs)
00148 {
00149 init(boost::const_pointer_cast<Message>(boost::static_pointer_cast<ConstMessage>(rhs.getMessage())), rhs.getConnectionHeaderPtr(), rhs.getReceiptTime(), rhs.nonConstWillCopy(), rhs.getMessageFactory());
00150 message_copy_.reset();
00151 }
00152
00158 boost::shared_ptr<M> getMessage() const
00159 {
00160 return copyMessageIfNecessary<M>();
00161 }
00162
00166 const boost::shared_ptr<ConstMessage>& getConstMessage() const { return message_; }
00170 M_string& getConnectionHeader() const { return *connection_header_; }
00171 const boost::shared_ptr<M_string>& getConnectionHeaderPtr() const { return connection_header_; }
00172
00176 const std::string& getPublisherName() const { return connection_header_ ? (*connection_header_)["callerid"] : s_unknown_publisher_string_; }
00177
00181 ros::Time getReceiptTime() const { return receipt_time_; }
00182
00183 bool nonConstWillCopy() const { return nonconst_need_copy_; }
00184 bool getMessageWillCopy() const { return !boost::is_const<M>::value && nonconst_need_copy_; }
00185
00186 bool operator<(const MessageEvent<M>& rhs)
00187 {
00188 if (message_ != rhs.message_)
00189 {
00190 return message_ < rhs.message_;
00191 }
00192
00193 if (receipt_time_ != rhs.receipt_time_)
00194 {
00195 return receipt_time_ < rhs.receipt_time_;
00196 }
00197
00198 return nonconst_need_copy_ < rhs.nonconst_need_copy_;
00199 }
00200
00201 bool operator==(const MessageEvent<M>& rhs)
00202 {
00203 return message_ = rhs.message_ && receipt_time_ == rhs.receipt_time_ && nonconst_need_copy_ == rhs.nonconst_need_copy_;
00204 }
00205
00206 bool operator!=(const MessageEvent<M>& rhs)
00207 {
00208 return !(*this == rhs);
00209 }
00210
00211 const CreateFunction& getMessageFactory() const { return create_; }
00212
00213 private:
00214 template<typename M2>
00215 typename boost::disable_if<boost::is_void<M2>, boost::shared_ptr<M> >::type copyMessageIfNecessary() const
00216 {
00217 if (boost::is_const<M>::value || !nonconst_need_copy_)
00218 {
00219 return boost::const_pointer_cast<Message>(message_);
00220 }
00221
00222 if (message_copy_)
00223 {
00224 return message_copy_;
00225 }
00226
00227 assert(create_);
00228 message_copy_ = create_();
00229 *message_copy_ = *message_;
00230
00231 return message_copy_;
00232 }
00233
00234 template<typename M2>
00235 typename boost::enable_if<boost::is_void<M2>, boost::shared_ptr<M> >::type copyMessageIfNecessary() const
00236 {
00237 return boost::const_pointer_cast<Message>(message_);
00238 }
00239
00240 template<typename T>
00241 boost::shared_ptr<ros::M_string>
00242 getConnectionHeader(T* t, typename boost::enable_if<ros::message_traits::IsMessage<T> >::type*_ = 0) const
00243 {
00244 return t->__connection_header;
00245 }
00246
00247 template<typename T>
00248 boost::shared_ptr<ros::M_string>
00249 getConnectionHeader(T* t, typename boost::disable_if<ros::message_traits::IsMessage<T> >::type*_ = 0) const
00250 {
00251 return boost::shared_ptr<ros::M_string>();
00252 }
00253
00254
00255 ConstMessagePtr message_;
00256
00257 mutable MessagePtr message_copy_;
00258 boost::shared_ptr<M_string> connection_header_;
00259 ros::Time receipt_time_;
00260 bool nonconst_need_copy_;
00261 CreateFunction create_;
00262
00263 static const std::string s_unknown_publisher_string_;
00264 };
00265
00266 template<typename M> const std::string MessageEvent<M>::s_unknown_publisher_string_("unknown_publisher");
00267
00268
00269 }
00270
00271 #endif // ROSCPP_MESSAGE_EVENT_H