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