Ignition Transport

API Reference

4.0.0
SubscriptionHandler.hh
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2014 Open Source Robotics Foundation
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16 */
17 
18 #ifndef IGN_TRANSPORT_SUBSCRIPTIONHANDLER_HH_
19 #define IGN_TRANSPORT_SUBSCRIPTIONHANDLER_HH_
20 
21 #ifdef _MSC_VER
22 #pragma warning(push, 0)
23 #endif
24 #include <google/protobuf/message.h>
25 #ifdef _MSC_VER
26 #pragma warning(pop)
27 #endif
28 
29 #include <google/protobuf/stubs/common.h>
30 
31 #if GOOGLE_PROTOBUF_VERSION >= 3000000
32 #include <google/protobuf/stubs/casts.h>
33 #endif
34 
35 #include <chrono>
36 #include <iostream>
37 #include <memory>
38 #include <string>
39 #include <utility>
40 
41 #include <ignition/msgs/Factory.hh>
42 
43 #include "ignition/transport/Export.hh"
48 
49 namespace ignition
50 {
51  namespace transport
52  {
55  class IGNITION_TRANSPORT_VISIBLE SubscriptionHandlerBase
56  {
60  public: explicit SubscriptionHandlerBase(
61  const std::string &_nUuid,
62  const SubscribeOptions &_opts = SubscribeOptions());
63 
65  public: virtual ~SubscriptionHandlerBase() = default;
66 
70  public: virtual std::string TypeName() = 0;
71 
74  public: std::string NodeUuid() const;
75 
78  public: std::string HandlerUuid() const;
79 
83  protected: bool UpdateThrottling();
84 
86  protected: std::string hUuid;
87 
89  protected: SubscribeOptions opts;
90 
93 
96  protected: double periodNs;
97 
99  private: std::string nUuid;
100  };
101 
110  class IGNITION_TRANSPORT_VISIBLE ISubscriptionHandler
111  : public SubscriptionHandlerBase
112  {
116  public: explicit ISubscriptionHandler(
117  const std::string &_nUuid,
118  const SubscribeOptions &_opts = SubscribeOptions());
119 
121  public: virtual ~ISubscriptionHandler() = default;
122 
127  public: virtual bool RunLocalCallback(
128  const ProtoMsg &_msg,
129  const MessageInfo &_info) = 0;
130 
135  public: virtual const std::shared_ptr<ProtoMsg> CreateMsg(
136  const std::string &_data,
137  const std::string &_type) const = 0;
138  };
139 
144  template <typename T> class SubscriptionHandler
145  : public ISubscriptionHandler
146  {
147  // Documentation inherited.
148  public: explicit SubscriptionHandler(const std::string &_nUuid,
149  const SubscribeOptions &_opts = SubscribeOptions())
150  : ISubscriptionHandler(_nUuid, _opts)
151  {
152  }
153 
154  // Documentation inherited.
156  const std::string &_data,
157  const std::string &/*_type*/) const
158  {
159  // Instantiate a specific protobuf message
160  auto msgPtr = std::make_shared<T>();
161 
162  // Create the message using some serialized data
163  if (!msgPtr->ParseFromString(_data))
164  {
165  std::cerr << "SubscriptionHandler::CreateMsg() error: ParseFromString"
166  << " failed" << std::endl;
167  }
168 
169  return msgPtr;
170  }
171 
172  // Documentation inherited.
174  {
175  return T().GetTypeName();
176  }
177 
180  public: void SetCallback(const MsgCallback<T> &_cb)
181  {
182  this->cb = _cb;
183  }
184 
185  // Documentation inherited.
186  public: bool RunLocalCallback(const ProtoMsg &_msg,
187  const MessageInfo &_info)
188  {
189  // No callback stored.
190  if (!this->cb)
191  {
192  std::cerr << "SubscriptionHandler::RunLocalCallback() error: "
193  << "Callback is NULL" << std::endl;
194  return false;
195  }
196 
197  // Check the subscription throttling option.
198  if (!this->UpdateThrottling())
199  return true;
200 
201 #if GOOGLE_PROTOBUF_VERSION >= 3000000
202  auto msgPtr = google::protobuf::down_cast<const T*>(&_msg);
203 #else
204  auto msgPtr = google::protobuf::internal::down_cast<const T*>(&_msg);
205 #endif
206 
207  this->cb(*msgPtr, _info);
208  return true;
209  }
210 
212  private: MsgCallback<T> cb;
213  };
214 
217  template <> class SubscriptionHandler<ProtoMsg>
218  : public ISubscriptionHandler
219  {
220  // Documentation inherited.
221  public: explicit SubscriptionHandler(const std::string &_nUuid,
222  const SubscribeOptions &_opts = SubscribeOptions())
223  : ISubscriptionHandler(_nUuid, _opts)
224  {
225  }
226 
227  // Documentation inherited.
229  const std::string &_data,
230  const std::string &_type) const
231  {
233 
234  const google::protobuf::Descriptor *desc =
235  google::protobuf::DescriptorPool::generated_pool()
236  ->FindMessageTypeByName(_type);
237 
238  // First, check if we have the descriptor from the generated proto
239  // classes.
240  if (desc)
241  {
242  msgPtr.reset(google::protobuf::MessageFactory::generated_factory()
243  ->GetPrototype(desc)->New());
244  }
245  else
246  {
247  // Fallback on Ignition Msgs if the message type is not found.
248  msgPtr = ignition::msgs::Factory::New(_type);
249  }
250 
251  if (!msgPtr)
252  return nullptr;
253 
254  // Create the message using some serialized data
255  if (!msgPtr->ParseFromString(_data))
256  {
257  std::cerr << "CreateMsg() error: ParseFromString failed" << std::endl;
258  return nullptr;
259  }
260 
261  return msgPtr;
262  }
263 
264  // Documentation inherited.
266  {
267  return kGenericMessageType;
268  }
269 
272  public: void SetCallback(const MsgCallback<ProtoMsg> &_cb)
273  {
274  this->cb = _cb;
275  }
276 
277  // Documentation inherited.
278  public: bool RunLocalCallback(const ProtoMsg &_msg,
279  const MessageInfo &_info)
280  {
281  // No callback stored.
282  if (!this->cb)
283  {
284  std::cerr << "SubscriptionHandler::RunLocalCallback() "
285  << "error: Callback is NULL" << std::endl;
286  return false;
287  }
288 
289  // Check the subscription throttling option.
290  if (!this->UpdateThrottling())
291  return true;
292 
293  this->cb(_msg, _info);
294  return true;
295  }
296 
298  private: MsgCallback<ProtoMsg> cb;
299  };
300 
305  {
312  public: explicit RawSubscriptionHandler(
313  const std::string &_nUuid,
314  const std::string &_msgType = kGenericMessageType,
315  const SubscribeOptions &_opts = SubscribeOptions());
316 
317  // Documentation inherited
318  public: std::string TypeName() override;
319 
323  public: void SetCallback(const RawCallback &_callback);
324 
331  public: bool RunRawCallback(const char *_msgData, const size_t _size,
332  const MessageInfo &_info);
333 
335  public: ~RawSubscriptionHandler();
336 
337  private: class Implementation;
340  private: std::unique_ptr<Implementation> pimpl;
341  };
342  }
343 }
344 
345 #endif
bool RunRawCallback(const char *_msgData, const size_t _size, const MessageInfo &_info)
Executes the raw callback registered for this handler.
SubscriptionHandler(const std::string &_nUuid, const SubscribeOptions &_opts=SubscribeOptions())
Definition: SubscriptionHandler.hh:221
Definition: AdvertiseOptions.hh:27
STL class.
STL class.
double periodNs
If throttling is enabled, the minimum period for receiving a message in nanoseconds.
Definition: SubscriptionHandler.hh:96
google::protobuf::Message ProtoMsg
Definition: TransportTypes.hh:66
RawSubscriptionHandler(const std::string &_nUuid, const std::string &_msgType=kGenericMessageType, const SubscribeOptions &_opts=SubscribeOptions())
Constructor.
SubscriptionHandlerBase contains functions and data which are common to all SubscriptionHandler types...
Definition: SubscriptionHandler.hh:55
std::string TypeName()
Get the type of the messages from which this subscriber handler is subscribed.
Definition: SubscriptionHandler.hh:265
virtual ~ISubscriptionHandler()=default
Destructor.
std::string hUuid
Unique handler's UUID.
Definition: SubscriptionHandler.hh:86
SubscriptionHandlerBase(const std::string &_nUuid, const SubscribeOptions &_opts=SubscribeOptions())
Constructor.
bool UpdateThrottling()
Check if message subscription is throttled. If so, verify whether the callback should be executed or ...
T reset(T... args)
bool RunLocalCallback(const ProtoMsg &_msg, const MessageInfo &_info)
Executes the local callback registered for this handler.
Definition: SubscriptionHandler.hh:278
A class to provide different options for a subscription.
Definition: SubscribeOptions.hh:35
void SetCallback(const RawCallback &_callback)
Set the callback of this handler.
virtual ~SubscriptionHandlerBase()=default
Destructor.
Timestamp lastCbTimestamp
Timestamp of the last callback executed.
Definition: SubscriptionHandler.hh:92
*brief Advertise a new service without any output parameter *In this version the callback is a free function *param[in] _topic Topic name associated to the service *param[in] _cb Callback to handle the service request with the *following void(* _cb)(const RequestT &_req)
Definition: Node.hh:527
virtual const std::shared_ptr< ProtoMsg > CreateMsg(const std::string &_data, const std::string &_type) const =0
Create a specific protobuf message given its serialized data.
std::chrono::steady_clock::time_point Timestamp
Definition: TransportTypes.hh:151
std::string TypeName() override
Get the type of the messages from which this subscriber handler is subscribed.
A class that provides information about the message received.
Definition: MessageInfo.hh:33
bool RunLocalCallback(const ProtoMsg &_msg, const MessageInfo &_info)
Executes the local callback registered for this handler.
Definition: SubscriptionHandler.hh:186
SubscribeOptions opts
Subscribe options.
Definition: SubscriptionHandler.hh:89
It creates a subscription handler for a specific protobuf message. 'T' is the Protobuf message type t...
Definition: SubscriptionHandler.hh:144
std::string NodeUuid() const
Get the node UUID.
Interface class used to manage generic protobuf messages.
Definition: SubscriptionHandler.hh:110
const std::shared_ptr< ProtoMsg > CreateMsg(const std::string &_data, const std::string &_type) const
Create a specific protobuf message given its serialized data.
Definition: SubscriptionHandler.hh:228
void SetCallback(const MsgCallback< ProtoMsg > &_cb)
Set the callback for this handler.
Definition: SubscriptionHandler.hh:272
T endl(T... args)
std::string TypeName()
Get the type of the messages from which this subscriber handler is subscribed.
Definition: SubscriptionHandler.hh:173
const std::string kGenericMessageType
The string type used for generic messages.
Definition: TransportTypes.hh:170
std::string HandlerUuid() const
Get the unique UUID of this handler.
ISubscriptionHandler(const std::string &_nUuid, const SubscribeOptions &_opts=SubscribeOptions())
Constructor.
SubscriptionHandler(const std::string &_nUuid, const SubscribeOptions &_opts=SubscribeOptions())
Definition: SubscriptionHandler.hh:148
virtual bool RunLocalCallback(const ProtoMsg &_msg, const MessageInfo &_info)=0
Executes the local callback registered for this handler.
const std::shared_ptr< ProtoMsg > CreateMsg(const std::string &_data, const std::string &) const
Create a specific protobuf message given its serialized data.
Definition: SubscriptionHandler.hh:155
Definition: SubscriptionHandler.hh:304
void SetCallback(const MsgCallback< T > &_cb)
Set the callback for this handler.
Definition: SubscriptionHandler.hh:180
virtual std::string TypeName()=0
Get the type of the messages from which this subscriber handler is subscribed.