CallbackHelper.hh
00001 #ifndef CALLBACKHELPER_HH
00002 #define CALLBACKHELPER_HH
00003 
00004 #include <vector>
00005 
00006 #include <boost/function.hpp>
00007 #include <boost/shared_ptr.hpp>
00008 #include <google/protobuf/message.h>
00009 
00010 #include "common/Console.hh"
00011 #include "msgs/msgs.h"
00012 #include "common/Exception.hh"
00013 
00014 namespace gazebo
00015 {
00018   namespace transport
00019   {
00020 
00024 
00026     class CallbackHelper
00027     {
00028       public: CallbackHelper() : latching(false) {}
00029 
00031       public: virtual std::string GetMsgType() const = 0;
00032 
00033       public: virtual bool HandleMessage(const google::protobuf::Message *msg) = 0;
00034       public: virtual bool HandleData(const std::string &newdata) = 0;
00035 
00038       public: virtual bool IsLocal() const = 0;
00039 
00040       public: bool GetLatching() const
00041               {return this->latching;}
00042 
00043       protected: bool latching;
00044     };
00045     typedef boost::shared_ptr<CallbackHelper> CallbackHelperPtr;
00046 
00047 
00049     template<class M>
00050     class CallbackHelperT : public CallbackHelper
00051     {
00052       public: CallbackHelperT( const boost::function<void (const boost::shared_ptr<M const> &)> &cb) : callback(cb) 
00053               {
00054                 // Just some code to make sure we have a google protobuf.
00055                 /*M test;
00056                 google::protobuf::Message *m;
00057                 if ( (m=dynamic_cast<google::protobuf::Message*>(&test)) ==NULL)
00058                   gzthrow( "Message type must be a google::protobuf type\n" );
00059                   */
00060               }
00061 
00063       public: std::string GetMsgType() const
00064               {
00065                 M test;
00066                 google::protobuf::Message *m;
00067                 if ((m=dynamic_cast<google::protobuf::Message*>(&test)) ==NULL)
00068                   gzthrow( "Message type must be a google::protobuf type\n" );
00069                 return m->GetTypeName();
00070               }
00071 
00072       public: virtual bool HandleMessage(const google::protobuf::Message *msg)
00073               {
00074                 /*boost::shared_ptr<M> m( new M );
00075                 m->ParseFromString( ((msgs::Packet*)msg)->serialized_data() );
00076                 */
00077                 boost::shared_ptr<M> m( new M );
00078                 m->CopyFrom(*msg);
00079 
00080                 this->callback( m );
00081                 return true;
00082               }
00083 
00084       public: virtual bool HandleData(const std::string &newdata)
00085               {
00086                 /*msgs::Packet packet;
00087                 packet.ParseFromString(newdata);
00088 
00089                 // TODO: Handle this error properly
00090                 if (packet.type() != "data")
00091                   gzerr << "CallbackHelperT::HandleMessage Invalid message!!!\n";
00092                 boost::shared_ptr<M> m( new M );
00093                 m->ParseFromString( packet.serialized_data() );
00094                 */
00095 
00096                 boost::shared_ptr<M> m( new M );
00097                 m->ParseFromString( newdata );
00098                 this->callback( m );
00099                 return true;
00100               }
00101 
00102       public: virtual bool IsLocal() const
00103               {
00104                 return true;
00105               }
00106 
00107       private: boost::function<void (const boost::shared_ptr<M const> &)> callback;
00108     };
00109 
00110     class DebugCallbackHelper : public CallbackHelper
00111     {
00112       public: DebugCallbackHelper( 
00113                   const boost::function<void (ConstStringPtr &)> &cb) : callback(cb) 
00114               {
00115               }
00116 
00118       public: std::string GetMsgType() const
00119               {
00120                 msgs::String m;
00121                 return m.GetTypeName();
00122               }
00123 
00124       public: virtual bool HandleMessage(const google::protobuf::Message *msg)
00125               {
00126                 //std::string data;
00127                 //msg->SerializeToString(data);
00128 
00129                 return this->HandleData( msg->DebugString()  );
00130               }
00131 
00132       public: virtual bool HandleData(const std::string &newdata)
00133               {
00134                 /*msgs::Packet packet;
00135                 packet.ParseFromString(newdata);
00136 
00137                 // TODO: Handle this error properly
00138                 if (packet.type() != "data")
00139                   gzerr << "CallbackHelperT::HandleData Invalid message!!!\n";
00140                   */
00141 
00142                 msgs::Packet packet;
00143                 packet.ParseFromString(newdata);
00144 
00145                 //ConstStringPtr m(new msgs::String);
00146                 boost::shared_ptr<msgs::String> m( new msgs::String );
00147                 m->ParseFromString( newdata );
00148                 this->callback( m );
00149                 return true;
00150               }
00151 
00152       public: virtual bool IsLocal() const
00153               {
00154                 return true;
00155               }
00156 
00157       private: boost::function<void (boost::shared_ptr<msgs::String> &)> callback;
00158     };
00160   }
00161 }
00162 
00163 #endif