Gazebo Transport

API Reference

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