Gazebo Transport

API Reference

11.4.1
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::transport
51 {
52  // Inline bracket to help doxygen filtering.
53  inline namespace IGNITION_TRANSPORT_VERSION_NAMESPACE {
54  //
57  class IGNITION_TRANSPORT_VISIBLE SubscriptionHandlerBase
58  {
62  public: explicit SubscriptionHandlerBase(
63  const std::string &_nUuid,
64  const SubscribeOptions &_opts = SubscribeOptions());
65 
67  public: virtual ~SubscriptionHandlerBase() = default;
68 
72  public: virtual std::string TypeName() = 0;
73 
76  public: std::string NodeUuid() const;
77 
80  public: std::string HandlerUuid() const;
81 
85  protected: bool UpdateThrottling();
86 
88  protected: SubscribeOptions opts;
89 
92  protected: double periodNs;
93 
94 #ifdef _WIN32
95 // Disable warning C4251 which is triggered by
96 // std::*
97 #pragma warning(push)
98 #pragma warning(disable: 4251)
99 #endif
100  protected: std::string hUuid;
102 
105 
107  private: std::string nUuid;
108 #ifdef _WIN32
109 #pragma warning(pop)
110 #endif
111  };
112 
121  class IGNITION_TRANSPORT_VISIBLE ISubscriptionHandler
122  : public SubscriptionHandlerBase
123  {
127  public: explicit ISubscriptionHandler(
128  const std::string &_nUuid,
129  const SubscribeOptions &_opts = SubscribeOptions());
130 
132  public: virtual ~ISubscriptionHandler() = default;
133 
138  public: virtual bool RunLocalCallback(
139  const ProtoMsg &_msg,
140  const MessageInfo &_info) = 0;
141 
146  public: virtual const std::shared_ptr<ProtoMsg> CreateMsg(
147  const std::string &_data,
148  const std::string &_type) const = 0;
149  };
150 
155  template <typename T> class SubscriptionHandler
156  : public ISubscriptionHandler
157  {
158  // Documentation inherited.
159  public: explicit SubscriptionHandler(const std::string &_nUuid,
160  const SubscribeOptions &_opts = SubscribeOptions())
161  : ISubscriptionHandler(_nUuid, _opts)
162  {
163  }
164 
165  // Documentation inherited.
167  const std::string &_data,
168  const std::string &/*_type*/) const
169  {
170  // Instantiate a specific protobuf message
171  auto msgPtr = std::make_shared<T>();
172 
173  // Create the message using some serialized data
174  if (!msgPtr->ParseFromString(_data))
175  {
176  std::cerr << "SubscriptionHandler::CreateMsg() error: ParseFromString"
177  << " failed" << std::endl;
178  }
179 
180  return msgPtr;
181  }
182 
183  // Documentation inherited.
185  {
186  return std::string(T().GetTypeName());
187  }
188 
191  public: void SetCallback(const MsgCallback<T> &_cb)
192  {
193  this->cb = _cb;
194  }
195 
196  // Documentation inherited.
197  public: bool RunLocalCallback(const ProtoMsg &_msg,
198  const MessageInfo &_info)
199  {
200  // No callback stored.
201  if (!this->cb)
202  {
203  std::cerr << "SubscriptionHandler::RunLocalCallback() error: "
204  << "Callback is NULL" << std::endl;
205  return false;
206  }
207 
208  // Check the subscription throttling option.
209  if (!this->UpdateThrottling())
210  return true;
211 
212 #if GOOGLE_PROTOBUF_VERSION >= 4022000
213  auto msgPtr = google::protobuf::internal::DownCast<const T*>(&_msg);
214 #elif GOOGLE_PROTOBUF_VERSION >= 3000000
215  auto msgPtr = google::protobuf::down_cast<const T*>(&_msg);
216 #else
217  auto msgPtr = google::protobuf::internal::down_cast<const T*>(&_msg);
218 #endif
219 
220  this->cb(*msgPtr, _info);
221  return true;
222  }
223 
225  private: MsgCallback<T> cb;
226  };
227 
230  template <> class SubscriptionHandler<ProtoMsg>
231  : public ISubscriptionHandler
232  {
233  // Documentation inherited.
234  public: explicit SubscriptionHandler(const std::string &_nUuid,
235  const SubscribeOptions &_opts = SubscribeOptions())
236  : ISubscriptionHandler(_nUuid, _opts)
237  {
238  }
239 
240  // Documentation inherited.
242  const std::string &_data,
243  const std::string &_type) const
244  {
246 
247  const google::protobuf::Descriptor *desc =
248  google::protobuf::DescriptorPool::generated_pool()
249  ->FindMessageTypeByName(_type);
250 
251  // First, check if we have the descriptor from the generated proto
252  // classes.
253  if (desc)
254  {
255  msgPtr.reset(google::protobuf::MessageFactory::generated_factory()
256  ->GetPrototype(desc)->New());
257  }
258  else
259  {
260  // Fallback on Ignition Msgs if the message type is not found.
261  msgPtr = gz::msgs::Factory::New(_type);
262  }
263 
264  if (!msgPtr)
265  return nullptr;
266 
267  // Create the message using some serialized data
268  if (!msgPtr->ParseFromString(_data))
269  {
270  std::cerr << "CreateMsg() error: ParseFromString failed" << std::endl;
271  return nullptr;
272  }
273 
274  return msgPtr;
275  }
276 
277  // Documentation inherited.
279  {
280  return kGenericMessageType;
281  }
282 
285  public: void SetCallback(const MsgCallback<ProtoMsg> &_cb)
286  {
287  this->cb = _cb;
288  }
289 
290  // Documentation inherited.
291  public: bool RunLocalCallback(const ProtoMsg &_msg,
292  const MessageInfo &_info)
293  {
294  // No callback stored.
295  if (!this->cb)
296  {
297  std::cerr << "SubscriptionHandler::RunLocalCallback() "
298  << "error: Callback is NULL" << std::endl;
299  return false;
300  }
301 
302  // Check the subscription throttling option.
303  if (!this->UpdateThrottling())
304  return true;
305 
306  this->cb(_msg, _info);
307  return true;
308  }
309 
311  private: MsgCallback<ProtoMsg> cb;
312  };
313 
318  {
325  public: explicit RawSubscriptionHandler(
326  const std::string &_nUuid,
327  const std::string &_msgType = kGenericMessageType,
328  const SubscribeOptions &_opts = SubscribeOptions());
329 
330  // Documentation inherited
331  public: std::string TypeName() override;
332 
336  public: void SetCallback(const RawCallback &_callback);
337 
344  public: bool RunRawCallback(const char *_msgData, const size_t _size,
345  const MessageInfo &_info);
346 
348  public: ~RawSubscriptionHandler();
349 
350  private: class Implementation;
351 
352 #ifdef _WIN32
353 // Disable warning C4251 which is triggered by
354 // std::unique_ptr
355 #pragma warning(push)
356 #pragma warning(disable: 4251)
357 #endif
358  private: std::unique_ptr<Implementation> pimpl;
361 #ifdef _WIN32
362 #pragma warning(pop)
363 #endif
364  };
365  }
366 }
367 
368 #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:234
STL class.
STL class.
double periodNs
If throttling is enabled, the minimum period for receiving a message in nanoseconds.
Definition: gz/transport/SubscriptionHandler.hh:92
google::protobuf::Message ProtoMsg
Definition: gz/transport/TransportTypes.hh:68
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:57
std::string TypeName()
Get the type of the messages from which this subscriber handler is subscribed.
Definition: gz/transport/SubscriptionHandler.hh:278
virtual ~ISubscriptionHandler()=default
Destructor.
std::string hUuid
Unique handler's UUID.
Definition: gz/transport/SubscriptionHandler.hh:101
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:291
A class to provide different options for a subscription.
Definition: gz/transport/SubscribeOptions.hh:37
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:104
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:153
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:35
bool RunLocalCallback(const ProtoMsg &_msg, const MessageInfo &_info)
Executes the local callback registered for this handler.
Definition: gz/transport/SubscriptionHandler.hh:197
SubscribeOptions opts
Subscribe options.
Definition: gz/transport/SubscriptionHandler.hh:88
It creates a subscription handler for a specific protobuf message. 'T' is the Protobuf message type t...
Definition: gz/transport/SubscriptionHandler.hh:155
std::string NodeUuid() const
Get the node UUID.
Interface class used to manage generic protobuf messages.
Definition: gz/transport/SubscriptionHandler.hh:121
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:241
void SetCallback(const MsgCallback< ProtoMsg > &_cb)
Set the callback for this handler.
Definition: gz/transport/SubscriptionHandler.hh:285
T endl(T... args)
Definition: gz/transport/AdvertiseOptions.hh:28
std::string TypeName()
Get the type of the messages from which this subscriber handler is subscribed.
Definition: gz/transport/SubscriptionHandler.hh:184
const std::string kGenericMessageType
The string type used for generic messages.
Definition: gz/transport/TransportTypes.hh:172
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:159
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:166
Definition: gz/transport/SubscriptionHandler.hh:317
void SetCallback(const MsgCallback< T > &_cb)
Set the callback for this handler.
Definition: gz/transport/SubscriptionHandler.hh:191
virtual std::string TypeName()=0
Get the type of the messages from which this subscriber handler is subscribed.