Ignition Transport

API Reference

8.1.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/config.hh"
44 #include "ignition/transport/Export.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 >= 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 = ignition::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 
369 #endif
SubscribeOptions opts
Subscribe options.
Definition: SubscriptionHandler.hh:90
void SetCallback(const MsgCallback< T > &_cb)
Set the callback for this handler.
Definition: SubscriptionHandler.hh:193
T endl(T... args)
A class to provide different options for a subscription.
Definition: SubscribeOptions.hh:39
std::string TypeName()
Get the type of the messages from which this subscriber handler is subscribed.
Definition: SubscriptionHandler.hh:278
Definition: SubscriptionHandler.hh:317
bool RunLocalCallback(const ProtoMsg &_msg, const MessageInfo &_info)
Executes the local callback registered for this handler.
Definition: SubscriptionHandler.hh:199
bool RunLocalCallback(const ProtoMsg &_msg, const MessageInfo &_info)
Executes the local callback registered for this handler.
Definition: SubscriptionHandler.hh:291
STL class.
const std::string kGenericMessageType
The string type used for generic messages.
Definition: TransportTypes.hh:174
double periodNs
If throttling is enabled, the minimum period for receiving a message in nanoseconds.
Definition: SubscriptionHandler.hh:94
void SetCallback(const MsgCallback< ProtoMsg > &_cb)
Set the callback for this handler.
Definition: SubscriptionHandler.hh:285
SubscriptionHandlerBase contains functions and data which are common to all SubscriptionHandler types...
Definition: SubscriptionHandler.hh:59
A class that provides information about the message received.
Definition: MessageInfo.hh:37
T reset(T... args)
std::string TypeName()
Get the type of the messages from which this subscriber handler is subscribed.
Definition: SubscriptionHandler.hh:186
Timestamp lastCbTimestamp
Timestamp of the last callback executed.
Definition: SubscriptionHandler.hh:106
SubscriptionHandler(const std::string &_nUuid, const SubscribeOptions &_opts=SubscribeOptions())
Definition: SubscriptionHandler.hh:161
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:241
SubscriptionHandler(const std::string &_nUuid, const SubscribeOptions &_opts=SubscribeOptions())
Definition: SubscriptionHandler.hh:234
google::protobuf::Message ProtoMsg
Definition: TransportTypes.hh:70
std::chrono::steady_clock::time_point Timestamp
Definition: TransportTypes.hh:155
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:168
It creates a subscription handler for a specific protobuf message. &#39;T&#39; is the Protobuf message type t...
Definition: SubscriptionHandler.hh:157
Definition: AdvertiseOptions.hh:28
Interface class used to manage generic protobuf messages.
Definition: SubscriptionHandler.hh:123