YARP
Yet Another Robot Platform
 
Loading...
Searching...
No Matches
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
55
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
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:388
A mini-server for performing network communication in the background.
Contact where() const override
Returns information about how this port can be reached.
void interrupt() override
Interrupt any current reads or writes attached to the port.
T & prepare()
Access the object which will be transmitted by the next call to yarp::os::BufferedPort::write.
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.
A placeholder for rich contact information.
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