YARP
Yet Another Robot Platform
Nodes.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2006-2020 Istituto Italiano di Tecnologia (IIT)
3  * All rights reserved.
4  *
5  * This software may be modified and distributed under the terms of the
6  * BSD-3-Clause license. See the accompanying LICENSE file for details.
7  */
8 
9 #include <yarp/os/Nodes.h>
10 
11 #include <yarp/os/Log.h>
12 #include <yarp/os/NestedContact.h>
13 #include <yarp/os/Node.h>
14 
15 #include <map>
16 #include <mutex>
17 
18 using namespace yarp::os;
19 
21 {
22 public:
23  Private();
24  ~Private();
25 
26  void clear();
27  Node* getNode(const std::string& name, bool create);
28  void add(Contactable& contactable);
29  void update(Contactable& contactable);
30  void prepare(const std::string& name);
31  void remove(Contactable& contactable);
32  Contact query(const std::string& name, const std::string& category);
33  void interrupt();
34  bool enable(bool flag);
35  Contact getParent(const std::string& name);
36  Contact getURI(const std::string& name);
37  void setActiveName(const std::string& name);
38  std::string getActiveName();
39  bool requireActiveName();
40  void addExternalNode(const std::string& name, Node& node);
41  void removeExternalNode(const std::string& name);
42 
43  // Port name
44  // Pointer to Node
45  // true = is external
46  std::map<std::string, std::pair<Node*, bool>> nodes_map;
47 
48  std::mutex mutex;
49  bool active{false};
50  std::string active_name;
51  Node* dummy{nullptr};
52 };
53 
55 {
56  clear();
57 }
58 
60 {
61  clear();
62 }
63 
65 {
66  mutex.lock();
67  for (auto& n : nodes_map) {
68  if (n.second.first != nullptr) {
69  if (!n.second.second) {
70  delete n.second.first;
71  n.second.first = nullptr;
72  }
73  }
74  }
75  nodes_map.clear();
76  mutex.unlock();
77 
78  active = true;
79  active_name = "";
80  if (dummy != nullptr) {
81  delete dummy;
82  dummy = nullptr;
83  }
84 }
85 
86 Node* yarp::os::Nodes::Private::getNode(const std::string& name, bool create)
87 {
88  NestedContact nc(name);
89  if (!nc.isNested()) {
90  return nullptr;
91  }
92  Node* node = nullptr;
93  auto it = nodes_map.find(nc.getNodeName());
94  if (it != nodes_map.end()) {
95  node = it->second.first;
96  } else if (create) {
97  mutex.lock();
98  node = new Node();
99  it = nodes_map.find(nc.getNodeName());
100  if (it == nodes_map.end()) {
101  nodes_map[nc.getNodeName()] = std::make_pair(node, false);
102  node->prepare(nc.getNodeName());
103  } else {
104  // The node was created by some other thread while this
105  // thread was waiting on the lock.
106  delete node;
107  node = it->second.first;
108  }
109  mutex.unlock();
110  }
111  return node;
112 }
113 
115 {
116  NestedContact nc(contactable.getName());
117  if (!nc.isNested()) {
118  return;
119  }
120  if (!active) {
121  return;
122  }
123  Node* node = getNode(contactable.getName(), true);
124  if (node != nullptr) {
125  node->add(contactable);
126  }
127 }
128 
130 {
131  NestedContact nc(contactable.getName());
132  if (!nc.isNested()) {
133  return;
134  }
135  if (!active) {
136  return;
137  }
138  Node* node = getNode(contactable.getName(), true);
139  if (node != nullptr) {
140  node->update(contactable);
141  }
142 }
143 
144 void yarp::os::Nodes::Private::prepare(const std::string& name)
145 {
146  NestedContact nc(name);
147  if (!nc.isNested()) {
148  return;
149  }
150  if (!active) {
151  return;
152  }
153  getNode(name, true);
154 }
155 
157 {
158  if (!active) {
159  return;
160  }
161  Node* node = getNode(contactable.getName(), false);
162  if (node != nullptr) {
163  node->remove(contactable);
164  }
165 }
166 
167 Contact yarp::os::Nodes::Private::query(const std::string& name, const std::string& category)
168 {
169  if (!active) {
170  return Contact();
171  }
172  Contact result;
173  mutex.lock();
174  for (const auto& n : nodes_map) {
175  result = n.second.first->query(name, category);
176  if (result.isValid()) {
177  break;
178  }
179  }
180  mutex.unlock();
181  return result;
182 }
183 
185 {
186  if (!active) {
187  return;
188  }
189  for (const auto& n : nodes_map) {
190  n.second.first->interrupt();
191  }
192 }
193 
195 {
196  if (!flag) {
197  clear();
198  }
199  active = flag;
200  return active;
201 }
202 
204 {
205  Contact result;
206  NestedContact nc(name);
207  mutex.lock();
208  auto it = nodes_map.find(nc.getNodeName());
209  if (it != nodes_map.end()) {
210  result = it->second.first->where();
211  }
212  mutex.unlock();
213  return result;
214 }
216 {
217  Contact result;
218  NestedContact nc(name);
219  mutex.lock();
220  auto it = nodes_map.find(nc.getNodeName());
221  if (it != nodes_map.end()) {
222  result = it->second.first->query(nc.getNestedName());
223  }
224  mutex.unlock();
225  return result;
226 }
227 
228 void yarp::os::Nodes::Private::setActiveName(const std::string& name)
229 {
230  nodes_map[name].second = true;
231  active_name = name;
232 }
233 
235 {
236  return active_name;
237 }
238 
240 {
241  if (active_name.empty()) {
242  dummy = new Node("...");
243  }
244  return true;
245 }
246 
247 void yarp::os::Nodes::Private::addExternalNode(const std::string& name, Node& node)
248 {
249  mutex.lock();
250  yAssert(nodes_map.find(name) == nodes_map.end());
251  nodes_map[name] = std::make_pair(&node, true);
252  mutex.unlock();
253 }
254 
255 void yarp::os::Nodes::Private::removeExternalNode(const std::string& name)
256 {
257  mutex.lock();
258  nodes_map.erase(name);
259  mutex.unlock();
260 }
261 
262 
264  mPriv(new yarp::os::Nodes::Private())
265 {
266 }
267 
269 {
270  delete mPriv;
271 }
272 
273 void Nodes::add(Contactable& contactable)
274 {
275  mPriv->add(contactable);
276 }
277 
278 void Nodes::remove(Contactable& contactable)
279 {
280  mPriv->remove(contactable);
281 }
282 
283 Contact Nodes::query(const std::string& name, const std::string& category)
284 {
285  return mPriv->query(name, category);
286 }
287 
289 {
290  mPriv->interrupt();
291 }
292 
293 bool Nodes::enable(bool flag)
294 {
295  return mPriv->enable(flag);
296 }
297 
299 {
300  mPriv->clear();
301 }
302 
303 Contact Nodes::getParent(const std::string& name)
304 {
305  return mPriv->getParent(name);
306 }
307 
308 Contact Nodes::getURI(const std::string& name)
309 {
310  return mPriv->getURI(name);
311 }
312 
313 void Nodes::prepare(const std::string& name)
314 {
315  mPriv->prepare(name);
316 }
317 
318 void Nodes::update(Contactable& contactable)
319 {
320  mPriv->update(contactable);
321 }
322 
323 void Nodes::setActiveName(const std::string& name)
324 {
325  mPriv->setActiveName(name);
326 }
327 
328 std::string Nodes::getActiveName()
329 {
330  return mPriv->getActiveName();
331 }
332 
334 {
335  return mPriv->requireActiveName();
336 }
337 
338 void Nodes::addExternalNode(const std::string& name, Node& node)
339 {
340  mPriv->addExternalNode(name, node);
341 }
342 
343 void Nodes::removeExternalNode(const std::string& name)
344 {
345  mPriv->removeExternalNode(name);
346 }
yarp::os::Node::prepare
void prepare(const std::string &name)
prepare if it is not already been done, opens the port of the Node.
Definition: Node.cpp:610
yarp::os::Nodes::interrupt
void interrupt()
interrupt delegates interrupt call to all of the Node in this container.
Definition: Nodes.cpp:288
yarp::os::NestedContact
A placeholder for rich contact information.
Definition: NestedContact.h:27
yarp::os::Nodes::Private::update
void update(Contactable &contactable)
Definition: Nodes.cpp:129
yarp::os::Nodes::clear
void clear()
clear empties the container
Definition: Nodes.cpp:298
yarp::os::Nodes::add
void add(Contactable &contactable) override
add a Contactable to the Node specified in the contactable name (see NestedContact....
Definition: Nodes.cpp:273
yarp::os::Nodes::Private::clear
void clear()
Definition: Nodes.cpp:64
yarp::os::Nodes::Private::enable
bool enable(bool flag)
Definition: Nodes.cpp:194
yarp::os::Node::add
void add(Contactable &contactable) override
add a contactable to this node.
Definition: Node.cpp:576
yarp::os::NestedContact::getNodeName
std::string getNodeName() const
Definition: NestedContact.cpp:184
yarp::os::Nodes::remove
void remove(Contactable &contactable) override
remove a Contactable from the Node specified in the contactable's name.
Definition: Nodes.cpp:278
yarp::os::Nodes::Private::getParent
Contact getParent(const std::string &name)
Definition: Nodes.cpp:203
yarp::os::Nodes::Private::nodes_map
std::map< std::string, std::pair< Node *, bool > > nodes_map
Definition: Nodes.cpp:46
yarp::os::Nodes::Private::Private
Private()
Definition: Nodes.cpp:54
yarp::os::Nodes::Private::mutex
std::mutex mutex
Definition: Nodes.cpp:48
NestedContact.h
yarp::os::Nodes::Private
Definition: Nodes.cpp:21
yarp::os::Nodes::getURI
Contact getURI(const std::string &name)
getURI queries the Node specified in the name parameter to get Contact information about the specifie...
Definition: Nodes.cpp:308
yarp::os::Nodes::enable
bool enable(bool flag)
enable setter for the activity state of the container.
Definition: Nodes.cpp:293
Log.h
yarp::os::Nodes::Private::active_name
std::string active_name
Definition: Nodes.cpp:50
yarp::os::Nodes::getParent
Contact getParent(const std::string &name)
getParent get info about node associated with the specified port.
Definition: Nodes.cpp:303
yarp::os::Nodes::prepare
void prepare(const std::string &name)
prepare checks for the existence of the node specified in the name parameter.
Definition: Nodes.cpp:313
yarp::os::Nodes::addExternalNode
void addExternalNode(const std::string &name, Node &node)
addExternalNode adds a Node to this container.
Definition: Nodes.cpp:338
Node.h
yarp::os::Nodes::Private::add
void add(Contactable &contactable)
Definition: Nodes.cpp:114
yarp::os::Node
The Node class.
Definition: Node.h:27
yarp::os::Nodes::Private::addExternalNode
void addExternalNode(const std::string &name, Node &node)
Definition: Nodes.cpp:247
yarp::os::Contactable::getName
virtual std::string getName() const
Get name of port.
Definition: Contactable.cpp:17
yarp::os::Nodes::Private::requireActiveName
bool requireActiveName()
Definition: Nodes.cpp:239
yarp::os::Nodes::Private::setActiveName
void setActiveName(const std::string &name)
Definition: Nodes.cpp:228
yarp::os::Nodes::requireActiveName
bool requireActiveName()
requireActiveName if there is no active node, creates a temporary one.
Definition: Nodes.cpp:333
yarp::os::Nodes::Private::removeExternalNode
void removeExternalNode(const std::string &name)
Definition: Nodes.cpp:255
yarp::os::Nodes
The Nodes class.
Definition: Nodes.h:35
Nodes.h
yarp::os::Nodes::Private::getURI
Contact getURI(const std::string &name)
Definition: Nodes.cpp:215
yarp::os::Nodes::Private::interrupt
void interrupt()
Definition: Nodes.cpp:184
yarp::os::Nodes::setActiveName
void setActiveName(const std::string &name)
setActiveName setter for the currently active node
Definition: Nodes.cpp:323
yarp::os
An interface to the operating system, including Port based communication.
Definition: AbstractCarrier.h:17
yarp::os::Node::update
void update(Contactable &contactable)
update should update the contactable with new information.
Definition: Node.cpp:581
yarp::os::NestedContact::isNested
bool isNested() const
Definition: NestedContact.cpp:209
yarp::os::Contact::isValid
bool isValid() const
Checks if a Contact is tagged as valid.
Definition: Contact.cpp:301
yarp::os::Nodes::Private::remove
void remove(Contactable &contactable)
Definition: Nodes.cpp:156
yarp
The main, catch-all namespace for YARP.
Definition: environment.h:18
yarp::os::Nodes::Private::getActiveName
std::string getActiveName()
Definition: Nodes.cpp:234
yarp::os::Contact
Represents how to reach a part of a YARP network.
Definition: Contact.h:39
yarp::os::Nodes::Private::query
Contact query(const std::string &name, const std::string &category)
Definition: Nodes.cpp:167
yarp::os::Nodes::Private::~Private
~Private()
Definition: Nodes.cpp:59
yarp::os::Node::remove
void remove(Contactable &contactable) override
remove specified contactable from the list of contactables associated with this Node.
Definition: Node.cpp:586
yarp::os::Nodes::Private::getNode
Node * getNode(const std::string &name, bool create)
Definition: Nodes.cpp:86
yarp::os::Nodes::getActiveName
std::string getActiveName()
getActiveName getter for the currently active node's name
Definition: Nodes.cpp:328
yarp::os::Nodes::update
virtual void update(Contactable &contactable)
update a Node information in this container.
Definition: Nodes.cpp:318
yAssert
#define yAssert(x)
Definition: Log.h:297
yarp::os::Nodes::Private::dummy
Node * dummy
Definition: Nodes.cpp:51
yarp::os::Nodes::~Nodes
virtual ~Nodes()
Definition: Nodes.cpp:268
yarp::os::Nodes::Nodes
Nodes()
Definition: Nodes.cpp:263
yarp::os::NestedContact::getNestedName
std::string getNestedName() const
Definition: NestedContact.cpp:189
yarp::os::Nodes::Private::active
bool active
Definition: Nodes.cpp:49
yarp::os::Nodes::query
virtual Contact query(const std::string &name, const std::string &category="") override
query the list of Node to find a Contact with the specified name.
Definition: Nodes.cpp:283
yarp::os::Contactable
An abstract port.
Definition: Contactable.h:38
yarp::os::Nodes::removeExternalNode
void removeExternalNode(const std::string &name)
removeExternalNode erase the node from the container.
Definition: Nodes.cpp:343
yarp::os::Nodes::Private::prepare
void prepare(const std::string &name)
Definition: Nodes.cpp:144