Gazebo Transport

API Reference

14.1.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::transport
41{
42 // Inline bracket to help doxygen filtering.
43 inline namespace GZ_TRANSPORT_VERSION_NAMESPACE {
44 //
47 class GZ_TRANSPORT_VISIBLE IReqHandler
48 {
51 public: explicit IReqHandler(const std::string &_nUuid)
52 : rep(""),
53 hUuid(Uuid().ToString()),
54 nUuid(_nUuid),
55 result(false),
56 requested(false),
57 repAvailable(false)
58 {
59 }
60
62 public: virtual ~IReqHandler() = default;
63
70 public: virtual void NotifyResult(const std::string &_rep,
71 const bool _result) = 0;
72
75 public: std::string NodeUuid() const
76 {
77 return this->nUuid;
78 }
79
82 public: std::string Response() const
83 {
84 return this->rep;
85 }
86
89 public: bool Result() const
90 {
91 return this->result;
92 }
93
96 public: bool Requested() const
97 {
98 return this->requested;
99 }
100
103 public: void Requested(const bool _value)
104 {
105 this->requested = _value;
106 }
107
111 public: virtual bool Serialize(std::string &_buffer) const = 0;
112
115 public: std::string HandlerUuid() const
116 {
117 return this->hUuid;
118 }
119
127 public: template<typename Lock> bool WaitUntil(Lock &_lock,
128 const unsigned int _timeout)
129 {
131 return this->condition.wait_until(_lock,
132 now + std::chrono::milliseconds(_timeout),
133 [this]
134 {
135 return this->repAvailable;
136 });
137 }
138
141 public: virtual std::string ReqTypeName() const = 0;
142
145 public: virtual std::string RepTypeName() const = 0;
146
147#ifdef _WIN32
148// Disable warning C4251 which is triggered by
149// std::*
150#pragma warning(push)
151#pragma warning(disable: 4251)
152#endif
156
158 protected: std::string rep;
159
161 protected: std::string hUuid;
162
164 private: std::string nUuid;
165#ifdef _WIN32
166#pragma warning(pop)
167#endif
168
170 protected: bool result;
171
174 private: bool requested;
175
179 public: bool repAvailable;
180 };
181
187 template <typename Req, typename Rep> class ReqHandler
188 : public IReqHandler
189 {
190 // Documentation inherited.
191 public: explicit ReqHandler(const std::string &_nUuid)
192 : IReqHandler(_nUuid)
193 {
194 }
195
199 public: std::shared_ptr<Rep> CreateMsg(const std::string &_data) const
200 {
201 // Instantiate a specific protobuf message
202 auto msgPtr = std::make_shared<Rep>();
203
204 // Create the message using some serialized data
205 if (!msgPtr->ParseFromString(_data))
206 {
207 std::cerr << "ReqHandler::CreateMsg() error: ParseFromString failed"
208 << std::endl;
209 }
210
211 return msgPtr;
212 }
213
219 public: void SetCallback(const std::function <void(
220 const Rep &_rep, const bool _result)> &_cb)
221 {
222 this->cb = _cb;
223 }
224
228 public: void SetMessage(const Req *_reqMsg)
229 {
230 if (!_reqMsg)
231 {
232 std::cerr << "ReqHandler::SetMessage() _reqMsg is null" << std::endl;
233 return;
234 }
235
236 this->reqMsg.CopyFrom(*_reqMsg);
237 }
238
244 public: void SetResponse(const Rep *_repMsg)
245 {
246 (void)_repMsg;
247 }
248
249 // Documentation inherited
250 public: bool Serialize(std::string &_buffer) const
251 {
252 if (!this->reqMsg.SerializeToString(&_buffer))
253 {
254 std::cerr << "ReqHandler::Serialize(): Error serializing the request"
255 << std::endl;
256 return false;
257 }
258
259 return true;
260 }
261
262 // Documentation inherited.
263 public: void NotifyResult(const std::string &_rep, const bool _result)
264 {
265 // Execute the callback (if existing).
266 if (this->cb)
267 {
268 // Instantiate the specific protobuf message associated to this topic.
269 auto msg = this->CreateMsg(_rep);
270
271 this->cb(*msg, _result);
272 }
273 else
274 {
275 this->rep = _rep;
276 this->result = _result;
277 }
278
279 this->repAvailable = true;
280 this->condition.notify_one();
281 }
282
283 // Documentation inherited.
284 public: virtual std::string ReqTypeName() const
285 {
286 return std::string(Req().GetTypeName());
287 }
288
289 // Documentation inherited.
290 public: virtual std::string RepTypeName() const
291 {
292 return std::string(Rep().GetTypeName());
293 }
294
296 private: Req reqMsg;
297
303 private: std::function<void(const Rep &_rep, const bool _result)> cb;
304 };
305
309 template <> class ReqHandler<google::protobuf::Message,
310 google::protobuf::Message>
311 : public IReqHandler
312 {
313 // Documentation inherited.
314 public: explicit ReqHandler(const std::string &_nUuid)
315 : IReqHandler(_nUuid)
316 {
317 }
318
322 public: void SetMessage(const google::protobuf::Message *_reqMsg)
323 {
324 if (!_reqMsg)
325 {
326 std::cerr << "ReqHandler::SetMessage() _reqMsg is null" << std::endl;
327 return;
328 }
329
330 this->reqMsg = _reqMsg->New();
331 this->reqMsg->CopyFrom(*_reqMsg);
332 }
333
338 public: void SetResponse(const google::protobuf::Message *_repMsg)
339 {
340 if (!_repMsg)
341 {
342 std::cerr << "ReqHandler::SetResponse() _repMsg is null" << std::endl;
343 return;
344 }
345
346 this->repMsg = _repMsg->New();
347 this->repMsg->CopyFrom(*_repMsg);
348 }
349
350 // Documentation inherited
351 public: bool Serialize(std::string &_buffer) const
352 {
353 if (!this->reqMsg)
354 {
355 std::cerr << "ReqHandler::Serialize() reqMsg is null" << std::endl;
356 return false;
357 }
358
359 if (!this->reqMsg->SerializeToString(&_buffer))
360 {
361 std::cerr << "ReqHandler::Serialize(): Error serializing the request"
362 << std::endl;
363 return false;
364 }
365
366 return true;
367 }
368
369 // Documentation inherited.
370 public: void NotifyResult(const std::string &_rep, const bool _result)
371 {
372 this->rep = _rep;
373 this->result = _result;
374
375 this->repAvailable = true;
376 this->condition.notify_one();
377 }
378
379 // Documentation inherited.
380 public: virtual std::string ReqTypeName() const
381 {
382 if (this->reqMsg)
383 return std::string(this->reqMsg->GetTypeName());
384 else
385 {
386 std::cerr << "ReqHandler::ReqTypeName() Warning: Using ReqTypeName() "
387 << "without type information" << std::endl;
388 return "";
389 }
390 }
391
393 public: virtual std::string RepTypeName() const
394 {
395 if (this->repMsg)
396 return std::string(this->repMsg->GetTypeName());
397 else
398 {
399 std::cerr << "ReqHandler::RepTypeName() Warning: Using RepTypeName() "
400 << "without type information" << std::endl;
401 return "";
402 }
403 }
404
406 private: google::protobuf::Message *reqMsg = nullptr;
407
409 private: google::protobuf::Message *repMsg = nullptr;
410 };
411 }
412}
413
414#endif