YARP
Yet Another Robot Platform
 
Loading...
Searching...
No Matches
PolyDriver.cpp
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: 2006-2021 Istituto Italiano di Tecnologia (IIT)
3 * SPDX-FileCopyrightText: 2006-2010 RobotCub Consortium
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
8
9#include <yarp/os/Log.h>
11#include <yarp/os/Property.h>
12
13using namespace yarp::os;
14using namespace yarp::dev;
15
16namespace {
17YARP_LOG_COMPONENT(POLYDRIVER, "yarp.dev.PolyDriver")
18}
19
21{
22private:
23 int count = 1;
24public:
26
27 void addRef()
28 {
29 count++;
30 }
31
33 {
34 count--;
35 return count;
36 }
37
38 int getRef()
39 {
40 return count;
41 }
42};
43
44
47 m_dd(nullptr),
48 m_Priv(nullptr)
49{
50}
51
52PolyDriver::PolyDriver(const std::string& txt) :
54 m_dd(nullptr),
55 m_Priv(nullptr)
56{
57 open(txt);
58}
59
62 m_dd(nullptr),
63 m_Priv(nullptr)
64{
65 open(config);
66}
67
69{
70 close();
71 yCAssert(POLYDRIVER, m_dd == nullptr);
72 yCAssert(POLYDRIVER, m_Priv == nullptr);
73}
74
75
76
77bool PolyDriver::open(const std::string& txt)
78{
79 Property p;
80 p.put("device",txt);
81 return open(p);
82}
83
84
86{
87 if (isValid()) {
88 // already open - should close first
89 return false;
90 }
91 if (m_Priv==nullptr) {
93 }
94 yCAssert(POLYDRIVER, m_Priv != nullptr);
95
96 coreOpen(config);
97 m_Priv->info.fromString(config.toString());
98
99 return isValid();
100}
101
102
104{
105 bool result = false;
106 if (m_Priv !=nullptr) {
107 int ct = m_Priv->removeRef();
108 if (ct==0) {
109 yCAssert(POLYDRIVER, m_Priv != nullptr);
110 delete m_Priv;
111 m_Priv = nullptr;
112 if (m_dd !=nullptr) {
113 result = m_dd->close();
114 delete m_dd;
115 m_dd = nullptr;
116 } else {
117 result = true;
118 }
119 }
120 m_dd = nullptr;
121 m_Priv = nullptr;
122 }
123 return result;
124}
125
127{
128 return m_dd != nullptr;
129}
130
132{
133 if (!alt.isValid()) {
134 return false;
135 }
136 if (isValid()) {
137 return false;
138 }
139 m_dd = alt.m_dd;
140 if (m_Priv !=nullptr) {
141 int ct = m_Priv->removeRef();
142 if (ct==0) {
143 yCAssert(POLYDRIVER, m_Priv != nullptr);
144 delete m_Priv;
145 }
146 }
147 m_Priv = alt.m_Priv;
148 yCAssert(POLYDRIVER, m_dd != nullptr);
149 yCAssert(POLYDRIVER, m_Priv != nullptr);
150 m_Priv->addRef();
151 return true;
152}
153
154bool PolyDriver::coreOpen(yarp::os::Searchable& prop)
155{
156 setId(prop.check("id", prop.check("device", Value("")), "Id assigned to this device").toString());
157 yarp::os::Searchable *config = &prop;
158 Property p;
159 std::string str = prop.toString();
160 Value *part;
161 if (prop.check("device",part)) {
162 str = part->toString();
163 }
164
165 DeviceDriver *driver = nullptr;
166
167 DriverCreator *creator = Drivers::factory().find(str.c_str());
168 if (creator!=nullptr)
169 {
170 Value *val;
171 //if the device has a wrapper..
172 if (config->check("wrapping_enabled",val) && (!creator->getWrapper().empty()))
173 {
174 std::string wrapper = creator->getWrapper();
176 // and this wrapper exists..
177 if (wrapCreator!=nullptr)
178 {
179 p.fromString(config->toString());
180 p.unput("wrapping_enabled");
181 config = &p;
182 //and this wrapper is not the device itself..
183 if (wrapCreator!=creator)
184 {
185 //..than open the wrapper instead of the device.
186 //this operation is done using the deviceBundler plugin, and passing to it
187 //the name of devices that it has to open and attach.
188 p.put("attached_device", str);
189 p.put("wrapper_device", wrapper);
190 p.put("device", "deviceBundler");
191 driver = wrapCreator->create();
193 }
194 else
195 {
196 //otherwise the device itself is already the wrapper
197 driver = creator->create();
198 }
199 }
200 }
201 //..the device does not have a wrapper
202 else
203 {
204 driver = creator->create();
205 }
206 }
207 else
208 {
209 // FIXME do not use yarpdev here
210 yCIError(POLYDRIVER, id(), "Could not find device <%s>", str.c_str());
211 return false;
212 }
213
214 if (driver!=nullptr)
215 {
216 PolyDriver *manager = creator->owner();
217 if (manager!=nullptr)
218 {
219 link(*manager);
220 return true;
221 }
222
223 yCIDebug(POLYDRIVER, id(), "Parameters are %s", config->toString().c_str());
224 driver->setId(id());
225 //try to open the device:
226 bool ok = driver->open(*config);
227 //if the device did not open successfully
228 if (!ok)
229 {
230 yCIError(POLYDRIVER, id(), "Driver <%s> was found but could not open", config->find("device").toString().c_str());
231 delete driver;
232 driver = nullptr;
233 }
234 //if the device opened successfully
235 else
236 {
237 //if the device is deprecated...
239 driver->view(ddd);
240 if(ddd)
241 {
242 //but the user requested it explicitly, than just print a warning
243 if(config->check("allow-deprecated-devices")) {
244 yCIWarning(POLYDRIVER, id(), R"(Device "%s" is deprecated. Opening since the "allow-deprecated-devices" option was passed in the configuration.)", str.c_str());
245 //if it is not requested explicitly, then close it with an error
246 } else {
247 yCIError(POLYDRIVER, id(), R"(Device "%s" is deprecated. Pass the "allow-deprecated-devices" option in the configuration if you want to open it anyway.)", str.c_str());
248 driver->close();
249 delete driver;
250 return false;
251 }
252 }
253 //print some info
254 std::string name = creator->getName();
255 std::string wrapper = creator->getWrapper();
256 std::string code = creator->getCode();
257 yCIInfo(POLYDRIVER, id(), "Created %s <%s>. See C++ class %s for documentation.",
258 ((name==wrapper)?"wrapper":"device"),
259 name.c_str(),
260 code.c_str());
261 }
262 m_dd = driver;
263 return true;
264 }
265
266 return false;
267}
268
269
271{
272 // this is not very careful
273 DeviceDriver *result = m_dd;
274 m_dd = nullptr;
275 return result;
276}
277
279{
280 close();
281 this->m_dd = dd;
282 if (dd!=nullptr) {
283 if (m_Priv ==nullptr) {
285 }
286 yCAssert(POLYDRIVER, m_Priv != nullptr);
287 if (!own) {
288 m_Priv->addRef();
289 }
290 }
291 return true;
292}
293
295{
296 if(isValid()) {
297 return m_dd->getImplementation();
298 } else {
299 return nullptr;
300 }
301}
Interface implemented by deprecated device drivers.
Interface implemented by all device drivers.
virtual void setId(const std::string &id)
Set the id for this device.
virtual DeviceDriver * getImplementation()
Some drivers are bureaucrats, pointing at others.
virtual bool close()
Close the DeviceDriver.
virtual bool open(yarp::os::Searchable &config)
Open the DeviceDriver.
bool view(T *&x)
Get an interface to the device driver.
A base class for factories that create driver objects.
Definition Drivers.h:27
static Drivers & factory()
Get the global factory for devices.
Definition Drivers.cpp:268
A container for a device driver.
Definition PolyDriver.h:23
DeviceDriver * take()
Gets the device this object manages.
bool close() override
Close the DeviceDriver.
bool give(DeviceDriver *dd, bool own)
Take on management of a device.
bool link(PolyDriver &alt)
Make this device be a link to an existing one.
virtual ~PolyDriver()
Destructor.
PolyDriver()
Constructor.
bool isValid() const
Check if device is valid.
DeviceDriver * getImplementation() override
Some drivers are bureaucrats, pointing at others.
bool open(const std::string &txt)
Construct and configure a device by its common name.
A mini-server for performing network communication in the background.
std::string getName() const override
Get name of port.
A class for storing options and configuration information.
Definition Property.h:33
A base class for nested structures that can be searched.
Definition Searchable.h:31
virtual bool check(const std::string &key) const =0
Check if there exists a property of the given name.
virtual std::string toString() const =0
Return a standard text representation of the content of the object.
virtual Value & find(const std::string &key) const =0
Gets a value corresponding to a given keyword.
A single value (typically within a Bottle).
Definition Value.h:43
std::string toString() const override
Return a standard text representation of the content of the object.
Definition Value.cpp:356
std::string toString(const T &value)
convert an arbitrary type to string.
#define yCAssert(component, x)
#define yCIError(component, id,...)
#define YARP_LOG_COMPONENT(name,...)
#define yCIInfo(component, id,...)
#define yCIDebug(component, id,...)
#define yCIWarning(component, id,...)
For streams capable of holding different kinds of content, check what they actually have.
An interface to the operating system, including Port based communication.