Gazebo Transport

API Reference

14.0.0
ReqHandler.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_REQHANDLER_HH_
19#define GZ_TRANSPORT_REQHANDLER_HH_
20
21#ifdef _MSC_VER
22#pragma warning(push)
23#pragma warning(disable: 4251)
24#endif
25#include <google/protobuf/message.h>
26#ifdef _MSC_VER
27#pragma warning(pop)
28#endif
29
30#include <condition_variable>
31#include <functional>
32#include <memory>
33#include <string>
34
35#include "gz/transport/config.hh"
36#include "gz/transport/Export.hh"
38#include "gz/transport/Uuid.hh"
39
40namespace gz
41{
42 namespace transport
43 {
44 // Inline bracket to help doxygen filtering.
45 inline namespace GZ_TRANSPORT_VERSION_NAMESPACE {
46 //
49 class GZ_TRANSPORT_VISIBLE IReqHandler
50 {
53 public: explicit IReqHandler(const std::string &_nUuid)
54 : rep(""),
55 hUuid(Uuid().ToString()),
56 nUuid(_nUuid),
57 result(false),
58 requested(false),
59 repAvailable(false)
60 {
61 }
62
64 public: virtual ~IReqHandler() = default;
65
72 public: virtual void NotifyResult(const std::string &_rep,
73 const bool _result) = 0;
74
77 public: std::string NodeUuid() const
78 {
79 return this->nUuid;
80 }
81
84 public: std::string Response() const
85 {
86 return this->rep;
87 }
88
91 public: bool Result() const
92 {
93 return this->result;
94 }
95
98 public: bool Requested() const
99 {
100 return this->requested;
101 }
102
105 public: void Requested(const bool _value)
106 {
107 this->requested = _value;
108 }
109
113 public: virtual bool Serialize(std::string &_buffer) const = 0;
114
117 public: std::string HandlerUuid() const
118 {
119 return this->hUuid;
120 }
121
129 public: template<typename Lock> bool WaitUntil(Lock &_lock,
130 const unsigned int _timeout)
131 {
133 return this->condition.wait_until(_lock,
134 now + std::chrono::milliseconds(_timeout),
135 [this]
136 {
137 return this->repAvailable;
138 });
139 }
140
143 public: virtual std::string ReqTypeName() const = 0;
144
147 public: virtual std::string RepTypeName() const = 0;
148
149#ifdef _WIN32
150// Disable warning C4251 which is triggered by
151// std::*
152#pragma warning(push)
153#pragma warning(disable: 4251)
154#endif
158
160 protected: std::string rep;
161
163 protected: std::string hUuid;
164
166 private: std::string nUuid;
167#ifdef _WIN32
168#pragma warning(pop)
169#endif
170
172 protected: bool result;
173
176 private: bool requested;
177
181 public: bool repAvailable;
182 };
183
189 template <typename Req, typename Rep> class ReqHandler
190 : public IReqHandler
191 {
192 // Documentation inherited.
193 public: explicit ReqHandler(const std::string &_nUuid)
194 : IReqHandler(_nUuid)
195 {
196 }
197
201 public: std::shared_ptr<Rep> CreateMsg(const std::string &_data) const
202 {
203 // Instantiate a specific protobuf message
204 std::shared_ptr<Rep> msgPtr(new Rep());
205
206 // Create the message using some serialized data
207 if (!msgPtr->ParseFromString(_data))
208 {
209 std::cerr << "ReqHandler::CreateMsg() error: ParseFromString failed"
210 << std::endl;
211 }
212
213 return msgPtr;
214 }
215
221 public: void SetCallback(const std::function <void(
222 const Rep &_rep, const bool _result)> &_cb)
223 {
224 this->cb = _cb;
225 }
226
230 public: void SetMessage(const Req *_reqMsg)
231 {
232 if (!_reqMsg)
233 {
234 std::cerr << "ReqHandler::SetMessage() _reqMsg is null" << std::endl;
235 return;
236 }
237
238 this->reqMsg.CopyFrom(*_reqMsg);
239 }
240
246 public: void SetResponse(const Rep *_repMsg)
247 {
248 (void)_repMsg;
249 }
250
251 // Documentation inherited
252 public: bool Serialize(std::string &_buffer) const
253 {
254 if (!this->reqMsg.SerializeToString(&_buffer))
255 {
256 std::cerr << "ReqHandler::Serialize(): Error serializing the request"
257 << std::endl;
258 return false;
259 }
260
261 return true;
262 }
263
264 // Documentation inherited.
265 public: void NotifyResult(const std::string &_rep, const bool _result)
266 {
267 // Execute the callback (if existing).
268 if (this->cb)
269 {
270 // Instantiate the specific protobuf message associated to this topic.
271 auto msg = this->CreateMsg(_rep);
272
273 this->cb(*msg, _result);
274 }
275 else
276 {
277 this->rep = _rep;
278 this->result = _result;
279 }
280
281 this->repAvailable = true;
282 this->condition.notify_one();
283 }
284
285 // Documentation inherited.
286 public: virtual std::string ReqTypeName() const
287 {
288 return Req().GetTypeName();
289 }
290
291 // Documentation inherited.
292 public: virtual std::string RepTypeName() const
293 {
294 return Rep().GetTypeName();
295 }
296
298 private: Req reqMsg;
299
305 private: std::function<void(const Rep &_rep, const bool _result)> cb;
306 };
307
311 template <> class ReqHandler<google::protobuf::Message,
312 google::protobuf::Message>
313 : public IReqHandler
314 {
315 // Documentation inherited.
316 public: explicit ReqHandler(const std::string &_nUuid)
317 : IReqHandler(_nUuid)
318 {
319 }
320
324 public: void SetMessage(const google::protobuf::Message *_reqMsg)
325 {
326 if (!_reqMsg)
327 {
328 std::cerr << "ReqHandler::SetMessage() _reqMsg is null" << std::endl;
329 return;
330 }
331
332 this->reqMsg = _reqMsg->New();
333 this->reqMsg->CopyFrom(*_reqMsg);
334 }
335
340 public: void SetResponse(const google::protobuf::Message *_repMsg)
341 {
342 if (!_repMsg)
343 {
344 std::cerr << "ReqHandler::SetResponse() _repMsg is null" << std::endl;
345 return;
346 }
347
348 this->repMsg = _repMsg->New();
349 this->repMsg->CopyFrom(*_repMsg);
350 }
351
352 // Documentation inherited
353 public: bool Serialize(std::string &_buffer) const
354 {
355 if (!this->reqMsg)
356 {
357 std::cerr << "ReqHandler::Serialize() reqMsg is null" << std::endl;
358 return false;
359 }
360
361 if (!this->reqMsg->SerializeToString(&_buffer))
362 {
363 std::cerr << "ReqHandler::Serialize(): Error serializing the request"
364 << std::endl;
365 return false;
366 }
367
368 return true;
369 }
370
371 // Documentation inherited.
372 public: void NotifyResult(const std::string &_rep, const bool _result)
373 {
374 this->rep = _rep;
375 this->result = _result;
376
377 this->repAvailable = true;
378 this->condition.notify_one();
379 }
380
381 // Documentation inherited.
382 public: virtual std::string ReqTypeName() const
383 {
384 if (this->reqMsg)
385 return this->reqMsg->GetTypeName();
386 else
387 {
388 std::cerr << "ReqHandler::ReqTypeName() Warning: Using ReqTypeName() "
389 << "without type information" << std::endl;
390 return "";
391 }
392 }
393
395 public: virtual std::string RepTypeName() const
396 {
397 if (this->repMsg)
398 return this->repMsg->GetTypeName();
399 else
400 {
401 std::cerr << "ReqHandler::RepTypeName() Warning: Using RepTypeName() "
402 << "without type information" << std::endl;
403 return "";
404 }
405 }
406
408 private: google::protobuf::Message *reqMsg = nullptr;
409
411 private: google::protobuf::Message *repMsg = nullptr;
412 };
413 }
414 }
415}
416
417#endif