00001 /* 00002 * Copyright (C) 2009, Willow Garage, Inc. 00003 * 00004 * Redistribution and use in source and binary forms, with or without 00005 * modification, are permitted provided that the following conditions are met: 00006 * * Redistributions of source code must retain the above copyright notice, 00007 * this list of conditions and the following disclaimer. 00008 * * Redistributions in binary form must reproduce the above copyright 00009 * notice, this list of conditions and the following disclaimer in the 00010 * documentation and/or other materials provided with the distribution. 00011 * * Neither the names of Stanford University or Willow Garage, Inc. nor the names of its 00012 * contributors may be used to endorse or promote products derived from 00013 * this software without specific prior written permission. 00014 * 00015 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 00016 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00017 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 00018 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 00019 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 00020 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 00021 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 00022 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 00023 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 00024 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 00025 * POSSIBILITY OF SUCH DAMAGE. 00026 */ 00027 00028 #ifndef ROSCPP_SUBSCRIPTION_CALLBACK_HELPER_H 00029 #define ROSCPP_SUBSCRIPTION_CALLBACK_HELPER_H 00030 00031 #include <typeinfo> 00032 00033 #include "common.h" 00034 #include "ros/forwards.h" 00035 #include "ros/parameter_adapter.h" 00036 #include "ros/message_traits.h" 00037 #include "ros/builtin_message_traits.h" 00038 #include "ros/serialization.h" 00039 #include "ros/message_event.h" 00040 #include <ros/static_assert.h> 00041 00042 #include <boost/type_traits/add_const.hpp> 00043 #include <boost/type_traits/remove_const.hpp> 00044 #include <boost/type_traits/remove_reference.hpp> 00045 #include <boost/type_traits/is_base_of.hpp> 00046 #include <boost/utility/enable_if.hpp> 00047 #include <boost/make_shared.hpp> 00048 00049 namespace ros 00050 { 00051 00052 struct SubscriptionCallbackHelperDeserializeParams 00053 { 00054 uint8_t* buffer; 00055 uint32_t length; 00056 boost::shared_ptr<M_string> connection_header; 00057 }; 00058 00059 struct ROSCPP_DECL SubscriptionCallbackHelperCallParams 00060 { 00061 MessageEvent<void const> event; 00062 }; 00063 00069 class ROSCPP_DECL SubscriptionCallbackHelper 00070 { 00071 public: 00072 virtual ~SubscriptionCallbackHelper() {} 00073 virtual VoidConstPtr deserialize(const SubscriptionCallbackHelperDeserializeParams&) = 0; 00074 virtual void call(SubscriptionCallbackHelperCallParams& params) = 0; 00075 virtual const std::type_info& getTypeInfo() = 0; 00076 virtual bool isConst() = 0; 00077 }; 00078 typedef boost::shared_ptr<SubscriptionCallbackHelper> SubscriptionCallbackHelperPtr; 00079 00085 template<typename P, typename Enabled = void> 00086 class SubscriptionCallbackHelperT : public SubscriptionCallbackHelper 00087 { 00088 public: 00089 typedef ParameterAdapter<P> Adapter; 00090 typedef typename ParameterAdapter<P>::Message NonConstType; 00091 typedef typename ParameterAdapter<P>::Event Event; 00092 typedef typename boost::add_const<NonConstType>::type ConstType; 00093 typedef boost::shared_ptr<NonConstType> NonConstTypePtr; 00094 typedef boost::shared_ptr<ConstType> ConstTypePtr; 00095 00096 static const bool is_const = ParameterAdapter<P>::is_const; 00097 00098 typedef boost::function<void(typename Adapter::Parameter)> Callback; 00099 typedef boost::function<NonConstTypePtr()> CreateFunction; 00100 00101 SubscriptionCallbackHelperT(const Callback& callback, 00102 const CreateFunction& create = DefaultMessageCreator<NonConstType>()) 00103 : callback_(callback) 00104 , create_(create) 00105 { } 00106 00107 void setCreateFunction(const CreateFunction& create) 00108 { 00109 create_ = create; 00110 } 00111 00112 virtual VoidConstPtr deserialize(const SubscriptionCallbackHelperDeserializeParams& params) 00113 { 00114 namespace ser = serialization; 00115 00116 NonConstTypePtr msg = create_(); 00117 00118 if (!msg) 00119 { 00120 ROS_DEBUG("Allocation failed for message of type [%s]", getTypeInfo().name()); 00121 return VoidConstPtr(); 00122 } 00123 00124 assignSubscriptionConnectionHeader(msg.get(), params.connection_header); 00125 00126 ser::PreDeserializeParams<NonConstType> predes_params; 00127 predes_params.message = msg; 00128 predes_params.connection_header = params.connection_header; 00129 ser::PreDeserialize<NonConstType>::notify(predes_params); 00130 00131 ser::IStream stream(params.buffer, params.length); 00132 ser::deserialize(stream, *msg); 00133 00134 return VoidConstPtr(msg); 00135 } 00136 00137 virtual void call(SubscriptionCallbackHelperCallParams& params) 00138 { 00139 Event event(params.event, create_); 00140 callback_(ParameterAdapter<P>::getParameter(event)); 00141 } 00142 00143 virtual const std::type_info& getTypeInfo() 00144 { 00145 return typeid(NonConstType); 00146 } 00147 00148 virtual bool isConst() 00149 { 00150 return ParameterAdapter<P>::is_const; 00151 } 00152 00153 private: 00154 Callback callback_; 00155 CreateFunction create_; 00156 }; 00157 00158 } 00159 00160 #endif // ROSCPP_SUBSCRIPTION_CALLBACK_HELPER_H