Gazebo Transport

API Reference

14.1.0
TopicStorage.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_TOPICSTORAGE_HH_
19#define GZ_TRANSPORT_TOPICSTORAGE_HH_
20
21#include <algorithm>
22#include <map>
23#include <string>
24#include <vector>
25
26#include "gz/transport/config.hh"
27#include "gz/transport/Export.hh"
30
31namespace gz::transport
32{
33 // Inline bracket to help doxygen filtering.
34 inline namespace GZ_TRANSPORT_VERSION_NAMESPACE {
35 //
39 template<typename T> class TopicStorage
40 {
42 public: TopicStorage() = default;
43
45 public: virtual ~TopicStorage() = default;
46
51 public: bool AddPublisher(const T &_publisher)
52 {
53 // The topic does not exist.
54 if (this->data.find(_publisher.Topic()) == this->data.end())
55 {
56 // VS2013 is buggy with initializer list here {}
57 this->data[_publisher.Topic()] =
59 }
60
61 // Check if the process uuid exists.
62 auto &m = this->data[_publisher.Topic()];
63 if (m.find(_publisher.PUuid()) != m.end())
64 {
65 // Check that the Publisher does not exist.
66 auto &v = m[_publisher.PUuid()];
67 auto found = std::find_if(v.begin(), v.end(),
68 [&](const T &_pub)
69 {
70 return _pub.Addr() == _publisher.Addr() &&
71 _pub.NUuid() == _publisher.NUuid();
72 });
73
74 // The publisher was already existing, just exit.
75 if (found != v.end())
76 return false;
77 }
78
79 // Add a new Publisher entry.
80 m[_publisher.PUuid()].push_back(T(_publisher));
81 return true;
82 }
83
87 public: bool HasTopic(const std::string &_topic) const
88 {
89 return this->data.find(_topic) != this->data.end();
90 }
91
98 public: bool HasTopic(const std::string &_topic,
99 const std::string &_type) const
100 {
101 if (!this->HasTopic(_topic))
102 return false;
103
104 // m is {pUUID=>std::vector<Publisher>}.
105 auto &m = this->data.at(_topic);
106
107 for (auto const &procs : m)
108 {
109 // Vector of publishers for a given topic and pUuid.
110 auto &v = procs.second;
111 auto found = std::find_if(v.begin(), v.end(),
112 [&](const T &_pub)
113 {
114 return _pub.MsgTypeName() == _type ||
115 _pub.MsgTypeName() == kGenericMessageType;
116 });
117
118 // Type found!
119 if (found != v.end())
120 return true;
121 }
122
123 return false;
124 }
125
132 public: bool HasAnyPublishers(const std::string &_topic,
133 const std::string &_pUuid) const
134 {
135 if (!this->HasTopic(_topic))
136 return false;
137
138 return this->data.at(_topic).find(_pUuid) !=
139 this->data.at(_topic).end();
140 }
141
145 public: bool HasPublisher(const std::string &_addr) const
146 {
147 for (auto const &topic : this->data)
148 {
149 for (auto const &proc : topic.second)
150 {
151 for (auto const &pub : proc.second)
152 {
153 if (pub.Addr() == _addr)
154 return true;
155 }
156 }
157 }
158 return false;
159 }
160
167 public: bool Publisher(const std::string &_topic,
168 const std::string &_pUuid,
169 const std::string &_nUuid,
170 T &_publisher) const
171 {
172 // Topic not found.
173 if (this->data.find(_topic) == this->data.end())
174 return false;
175
176 // m is {pUUID=>Publisher}.
177 auto &m = this->data.at(_topic);
178
179 // pUuid not found.
180 if (m.find(_pUuid) == m.end())
181 return false;
182
183 // Vector of 0MQ known addresses for a given topic and pUuid.
184 auto &v = m.at(_pUuid);
185 auto found = std::find_if(v.begin(), v.end(),
186 [&](const T &_pub)
187 {
188 return _pub.NUuid() == _nUuid;
189 });
190 // Address found!
191 if (found != v.end())
192 {
193 _publisher = *found;
194 return true;
195 }
196
197 // nUuid not found.
198 return false;
199 }
200
205 public: bool Publishers(const std::string &_topic,
206 std::map<std::string, std::vector<T>> &_info) const
207 {
208 if (!this->HasTopic(_topic))
209 return false;
210
211 _info = this->data.at(_topic);
212 return true;
213 }
214
220 public: bool DelPublisherByNode(const std::string &_topic,
221 const std::string &_pUuid,
222 const std::string &_nUuid)
223 {
224 size_t counter = 0;
225
226 // Iterate over all the topics.
227 if (this->data.find(_topic) != this->data.end())
228 {
229 // m is {pUUID=>Publisher}.
230 auto &m = this->data[_topic];
231
232 // The pUuid exists.
233 if (m.find(_pUuid) != m.end())
234 {
235 // Vector of 0MQ known addresses for a given topic and pUuid.
236 auto &v = m[_pUuid];
237 auto priorSize = v.size();
238 v.erase(std::remove_if(v.begin(), v.end(),
239 [&](const T &_pub)
240 {
241 return _pub.NUuid() == _nUuid;
242 }),
243 v.end());
244 counter = priorSize - v.size();
245
246 if (v.empty())
247 m.erase(_pUuid);
248
249 if (m.empty())
250 this->data.erase(_topic);
251 }
252 }
253
254 return counter > 0;
255 }
256
260 public: bool DelPublishersByProc(const std::string &_pUuid)
261 {
262 size_t counter = 0;
263
264 // Iterate over all the topics.
265 for (auto it = this->data.begin(); it != this->data.end();)
266 {
267 // m is {pUUID=>Publisher}.
268 auto &m = it->second;
269 counter += m.erase(_pUuid);
270 if (m.empty())
271 this->data.erase(it++);
272 else
273 ++it;
274 }
275
276 return counter > 0;
277 }
278
284 public: void PublishersByProc(const std::string &_pUuid,
285 std::map<std::string, std::vector<T>> &_pubs) const
286 {
287 _pubs.clear();
288
289 // Iterate over all the topics.
290 for (auto const &topic : this->data)
291 {
292 // m is {pUUID=>Publisher}.
293 auto &m = topic.second;
294 if (m.find(_pUuid) != m.end())
295 {
296 auto &v = m.at(_pUuid);
297 for (auto const &pub : v)
298 {
299 _pubs[pub.NUuid()].push_back(T(pub));
300 }
301 }
302 }
303 }
304
310 public: void PublishersByNode(const std::string &_pUuid,
311 const std::string &_nUuid,
312 std::vector<T> &_pubs) const
313 {
314 _pubs.clear();
315
316 // Iterate over all the topics.
317 for (auto const &topic : this->data)
318 {
319 // m is {pUUID=>Publisher}.
320 auto const &m = topic.second;
321 if (m.find(_pUuid) != m.end())
322 {
323 auto const &v = m.at(_pUuid);
324 for (auto const &pub : v)
325 {
326 if (pub.NUuid() == _nUuid)
327 {
328 _pubs.push_back(T(pub));
329 }
330 }
331 }
332 }
333 }
334
337 public: void TopicList(std::vector<std::string> &_topics) const
338 {
339 for (auto const &topic : this->data)
340 _topics.push_back(topic.first);
341 }
342
344 public: void Print() const
345 {
346 std::cout << "---" << std::endl;
347 for (auto const &topic : this->data)
348 {
349 std::cout << "[" << topic.first << "]" << std::endl;
350 auto &m = topic.second;
351 for (auto const &proc : m)
352 {
353 std::cout << "\tProc. UUID: " << proc.first << std::endl;
354 auto &v = proc.second;
355 for (auto const &publisher : v)
356 {
357 std::cout << publisher;
358 }
359 }
360 }
361 }
362
364 public: void Clear()
365 {
366 this->data.clear();
367 }
368
371 private: std::map<std::string,
373 };
374 }
375}
376
377#endif