common.h
Go to the documentation of this file.
1 /*+-------------------------------------------------------------------------+
2  | MultiVehicle simulator (libmvsim) |
3  | |
4  | Copyright (C) 2014-2024 Jose Luis Blanco Claraco |
5  | Copyright (C) 2017 Borys Tymchenko (Odessa Polytechnic University) |
6  | Distributed under 3-clause BSD License |
7  | See COPYING |
8  +-------------------------------------------------------------------------+ */
9 
10 #pragma once
11 
12 #if defined(MVSIM_HAS_ZMQ) && defined(MVSIM_HAS_PROTOBUF)
13 
14 #include <mrpt/io/CMemoryStream.h>
15 #include <mrpt/serialization/CArchive.h>
16 
17 #include <variant>
18 
19 #include "zmq_fwrds.h"
20 
21 namespace google::protobuf
22 {
23 class MessageLite;
24 }
25 
26 namespace mvsim
27 {
38 void sendMessage(const google::protobuf::MessageLite& m, zmq::socket_t& socket);
39 
41 zmq::message_t receiveMessage(zmq::socket_t& s);
42 
49 void parseMessage(const zmq::message_t& msg, google::protobuf::MessageLite& out);
50 
51 class UnexpectedMessageException : public std::runtime_error
52 {
53  public:
54  UnexpectedMessageException(const char* reason) : std::runtime_error(reason) {}
55 };
56 namespace internal
57 {
58 std::tuple<std::string, std::string> parseMessageToParts(const zmq::message_t& msg);
59 
60 template <typename variant_t, size_t IDX = 0>
61 variant_t recursiveParse(const std::string& typeName, const std::string& serializedData)
62 {
63  if constexpr (IDX < std::variant_size_v<variant_t>)
64  {
65  using this_t = std::variant_alternative_t<IDX, variant_t>;
66  this_t v;
67  const std::string expectedName = v.GetTypeName();
68  if (expectedName == typeName)
69  {
70  bool ok = v.ParseFromString(serializedData);
71  if (!ok)
72  THROW_EXCEPTION_FMT(
73  "Format error: protobuf could not decode binary message of "
74  "type '%s'",
75  typeName.c_str());
76  return {v};
77  }
78  else
79  return recursiveParse<variant_t, IDX + 1>(typeName, serializedData);
80  }
81  throw UnexpectedMessageException(
82  mrpt::format("Type '%s' not found in expected list of variant arguments.", typeName.c_str())
83  .c_str());
84 }
85 } // namespace internal
86 
87 std::string get_zmq_endpoint(const zmq::socket_t& s);
88 
94 template <typename variant_t>
95 variant_t parseMessageVariant(const zmq::message_t& msg)
96 {
97  const auto [typeName, serializedData] = internal::parseMessageToParts(msg);
98  return internal::recursiveParse<variant_t>(typeName, serializedData);
99 }
100 
102 template <class... Ts>
103 struct overloaded : Ts...
104 {
105  using Ts::operator()...;
106 };
107 
109 template <class... Ts>
110 overloaded(Ts...) -> overloaded<Ts...>;
111 
114 } // namespace mvsim
115 #endif
mvsim
Definition: Client.h:21
zmq_fwrds.h
google::protobuf
Definition: zmq_fwrds.h:19
ok
ROSCPP_DECL bool ok()
std


mvsim
Author(s):
autogenerated on Wed May 28 2025 02:13:07