Gazebo Transport

API Reference

8.5.0
gz/transport/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 GZ_TRANSPORT_SUBSCRIPTIONHANDLER_HH_
19 #define GZ_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 && GOOGLE_PROTOBUF_VERSION < 4022000
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 <gz/msgs/Factory.hh>
42 
43 #include "gz/transport/config.hh"
44 #include "gz/transport/Export.hh"
48 #include "gz/transport/Uuid.hh"
49 
50 namespace ignition
51 {
52  namespace transport
53  {
54  // Inline bracket to help doxygen filtering.
55  inline namespace IGNITION_TRANSPORT_VERSION_NAMESPACE {
56  //
59  class IGNITION_TRANSPORT_VISIBLE SubscriptionHandlerBase
60  {
64  public: explicit SubscriptionHandlerBase(
65  const std::string &_nUuid,
66  const SubscribeOptions &_opts = SubscribeOptions());
67 
69  public: virtual ~SubscriptionHandlerBase() = default;
70 
74  public: virtual std::string TypeName() = 0;
75 
78  public: std::string NodeUuid() const;
79 
82  public: std::string HandlerUuid() const;
83 
87  protected: bool UpdateThrottling();
88 
90  protected: SubscribeOptions opts;
91 
94  protected: double periodNs;
95 
96 #ifdef _WIN32
97 // Disable warning C4251 which is triggered by
98 // std::*
99 #pragma warning(push)
100 #pragma warning(disable: 4251)
101 #endif
102  protected: std::string hUuid;
104 
107 
109  private: std::string nUuid;
110 #ifdef _WIN32
111 #pragma warning(pop)
112 #endif
113  };
114 
123  class IGNITION_TRANSPORT_VISIBLE ISubscriptionHandler
124  : public SubscriptionHandlerBase
125  {
129  public: explicit ISubscriptionHandler(
130  const std::string &_nUuid,
131  const SubscribeOptions &_opts = SubscribeOptions());
132 
134  public: virtual ~ISubscriptionHandler() = default;
135 
140  public: virtual bool RunLocalCallback(
141  const ProtoMsg &_msg,
142  const MessageInfo &_info) = 0;
143 
148  public: virtual const std::shared_ptr<ProtoMsg> CreateMsg(
149  const std::string &_data,
150  const std::string &_type) const = 0;
151  };
152 
157  template <typename T> class SubscriptionHandler
158  : public ISubscriptionHandler
159  {
160  // Documentation inherited.
161  public: explicit SubscriptionHandler(const std::string &_nUuid,
162  const SubscribeOptions &_opts = SubscribeOptions())
163  : ISubscriptionHandler(_nUuid, _opts)
164  {
165  }
166 
167  // Documentation inherited.
169  const std::string &_data,
170  const std::string &/*_type*/) const
171  {
172  // Instantiate a specific protobuf message
173  auto msgPtr = std::make_shared<T>();
174 
175  // Create the message using some serialized data
176  if (!msgPtr->ParseFromString(_data))
177  {
178  std::cerr << "SubscriptionHandler::CreateMsg() error: ParseFromString"
179  << " failed" << std::endl;
180  }
181 
182  return msgPtr;
183  }
184 
185  // Documentation inherited.
187  {
188  return T().GetTypeName();
189  }
190 
193  public: void SetCallback(const MsgCallback<T> &_cb)
194  {
195  this->cb = _cb;
196  }
197 
198  // Documentation inherited.
199  public: bool RunLocalCallback(const ProtoMsg &_msg,
200  const MessageInfo &_info)
201  {
202  // No callback stored.
203  if (!this->cb)
204  {
205  std::cerr << "SubscriptionHandler::RunLocalCallback() error: "
206  << "Callback is NULL" << std::endl;
207  return false;
208  }
209 
210  // Check the subscription throttling option.
211  if (!this->UpdateThrottling())
212  return true;
213 
214 #if GOOGLE_PROTOBUF_VERSION >= 4022000
215  auto msgPtr = google::protobuf::internal::DownCast<const T*>(&_msg);
216 #elif GOOGLE_PROTOBUF_VERSION >= 3000000
217  auto msgPtr = google::protobuf::down_cast<const T*>(&_msg);
218 #else
219  auto msgPtr = google::protobuf::internal::down_cast<const T*>(&_msg);
220 #endif
221 
222  this->cb(*msgPtr, _info);
223  return true;
224  }
225 
227  private: MsgCallback<T> cb;
228  };
229 
232  template <> class SubscriptionHandler<ProtoMsg>
233  : public ISubscriptionHandler
234  {
235  // Documentation inherited.
236  public: explicit SubscriptionHandler(const std::string &_nUuid,
237  const SubscribeOptions &_opts = SubscribeOptions())
238  : ISubscriptionHandler(_nUuid, _opts)
239  {
240  }
241 
242  // Documentation inherited.
244  const std::string &_data,
245  const std::string &_type) const
246  {
248 
249  const google::protobuf::Descriptor *desc =
250  google::protobuf::DescriptorPool::generated_pool()
251  ->FindMessageTypeByName(_type);
252 
253  // First, check if we have the descriptor from the generated proto
254  // classes.
255  if (desc)
256  {
257  msgPtr.reset(google::protobuf::MessageFactory::generated_factory()
258  ->GetPrototype(desc)->New());
259  }
260  else
261  {
262  // Fallback on Ignition Msgs if the message type is not found.
263  msgPtr = gz::msgs::Factory::New(_type);
264  }
265 
266  if (!msgPtr)
267  return nullptr;
268 
269  // Create the message using some serialized data
270  if (!msgPtr->ParseFromString(_data))
271  {
272  std::cerr << "CreateMsg() error: ParseFromString failed" << std::endl;
273  return nullptr;
274  }
275 
276  return msgPtr;
277  }
278 
279  // Documentation inherited.
281  {
282  return kGenericMessageType;
283  }
284 
287  public: void SetCallback(const MsgCallback<ProtoMsg> &_cb)
288  {
289  this->cb = _cb;
290  }
291 
292  // Documentation inherited.
293  public: bool RunLocalCallback(const ProtoMsg &_msg,
294  const MessageInfo &_info)
295  {
296  // No callback stored.
297  if (!this->cb)
298  {
299  std::cerr << "SubscriptionHandler::RunLocalCallback() "
300  << "error: Callback is NULL" << std::endl;
301  return false;
302  }
303 
304  // Check the subscription throttling option.
305  if (!this->UpdateThrottling())
306  return true;
307 
308  this->cb(_msg, _info);
309  return true;
310  }
311 
313  private: MsgCallback<ProtoMsg> cb;
314  };
315 
320  {
327  public: explicit RawSubscriptionHandler(
328  const std::string &_nUuid,
329  const std::string &_msgType = kGenericMessageType,
330  const SubscribeOptions &_opts = SubscribeOptions());
331 
332  // Documentation inherited
333  public: std::string TypeName() override;
334 
338  public: void SetCallback(const RawCallback &_callback);
339 
346  public: bool RunRawCallback(const char *_msgData, const size_t _size,
347  const MessageInfo &_info);
348 
350  public: ~RawSubscriptionHandler();
351 
352  private: class Implementation;
353 
354 #ifdef _WIN32
355 // Disable warning C4251 which is triggered by
356 // std::unique_ptr
357 #pragma warning(push)
358 #pragma warning(disable: 4251)
359 #endif
360  private: std::unique_ptr<Implementation> pimpl;
363 #ifdef _WIN32
364 #pragma warning(pop)
365 #endif
366  };
367  }
368  }
369 }
370 
371 #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: gz/transport/SubscriptionHandler.hh:236
Definition: gz/transport/AdvertiseOptions.hh:28
STL class.
STL class.
double periodNs
If throttling is enabled, the minimum period for receiving a message in nanoseconds.
Definition: gz/transport/SubscriptionHandler.hh:94
google::protobuf::Message ProtoMsg
Definition: gz/transport/TransportTypes.hh:70
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: gz/transport/SubscriptionHandler.hh:59
std::string TypeName()
Get the type of the messages from which this subscriber handler is subscribed.
Definition: gz/transport/SubscriptionHandler.hh:280
virtual ~ISubscriptionHandler()=default
Destructor.
std::string hUuid
Unique handler's UUID.
Definition: gz/transport/SubscriptionHandler.hh:103
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: gz/transport/SubscriptionHandler.hh:293
A class to provide different options for a subscription.
Definition: gz/transport/SubscribeOptions.hh:39
void SetCallback(const RawCallback &_callback)
Set the callback of this handler.
virtual ~SubscriptionHandlerBase()=default
Destructor.
Timestamp lastCbTimestamp
Timestamp of the last callback executed.
Definition: gz/transport/SubscriptionHandler.hh:106
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: gz/transport/TransportTypes.hh:155
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: gz/transport/MessageInfo.hh:37
bool RunLocalCallback(const ProtoMsg &_msg, const MessageInfo &_info)
Executes the local callback registered for this handler.
Definition: gz/transport/SubscriptionHandler.hh:199
SubscribeOptions opts
Subscribe options.
Definition: gz/transport/SubscriptionHandler.hh:90
It creates a subscription handler for a specific protobuf message. 'T' is the Protobuf message type t...
Definition: gz/transport/SubscriptionHandler.hh:157
std::string NodeUuid() const
Get the node UUID.
Interface class used to manage generic protobuf messages.
Definition: gz/transport/SubscriptionHandler.hh:123
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: gz/transport/SubscriptionHandler.hh:243
void SetCallback(const MsgCallback< ProtoMsg > &_cb)
Set the callback for this handler.
Definition: gz/transport/SubscriptionHandler.hh:287
T endl(T... args)
std::string TypeName()
Get the type of the messages from which this subscriber handler is subscribed.
Definition: gz/transport/SubscriptionHandler.hh:186
const std::string kGenericMessageType
The string type used for generic messages.
Definition: gz/transport/TransportTypes.hh:174
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: gz/transport/SubscriptionHandler.hh:161
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: gz/transport/SubscriptionHandler.hh:168
Definition: gz/transport/SubscriptionHandler.hh:319
void SetCallback(const MsgCallback< T > &_cb)
Set the callback for this handler.
Definition: gz/transport/SubscriptionHandler.hh:193
virtual std::string TypeName()=0
Get the type of the messages from which this subscriber handler is subscribed.