Gazebo Transport

API Reference

13.4.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 
31 namespace 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