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 device_name = prop.toString();
160 Value *part;
161 if (prop.check("device",part)) {
162 device_name = part->toString();
163 }
164
165 DeviceDriver *driver = nullptr;
166
167 DriverCreator *deviceCreator = Drivers::factory().find(device_name.c_str());
168 if (deviceCreator !=nullptr)
169 {
170 Value *val;
171 //if the device has a wrapper..
172 if (config->check("wrapping_enabled",val) && (!deviceCreator->getWrapper().empty()))
173 {
174 std::string wrapper_name = deviceCreator->getWrapper();
175 DriverCreator *wrapperCreator = Drivers::factory().find(wrapper_name.c_str());
176 // and this wrapper exists..
177 if (wrapperCreator !=nullptr)
178 {
179 p.fromString(config->toString());
180 p.unput("wrapping_enabled");
181 config = &p;
182 //and this wrapper is not the device itself..
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", device_name);
189 p.put("wrapper_device", wrapper_name);
190 p.put("device", "deviceBundler");
191 DriverCreator* bundlerCreator = Drivers::factory().find("deviceBundler");
192 driver = bundlerCreator->create();
194 }
195 else
196 {
197 //otherwise the device itself is already the wrapper
198 driver = deviceCreator->create();
199 }
200 }
201 }
202 //..the device does not have a wrapper
203 else
204 {
205 driver = deviceCreator->create();
206 }
207 }
208 else
209 {
210 // FIXME do not use yarpdev here
211 yCIError(POLYDRIVER, id(), "Could not find device <%s>", device_name.c_str());
212 return false;
213 }
214
215 if (driver!=nullptr)
216 {
217 PolyDriver *manager = deviceCreator->owner();
218 if (manager!=nullptr)
219 {
220 link(*manager);
221 return true;
222 }
223
224 std::string param_string = config->toString();
225 yCIDebug(POLYDRIVER, id(), "Parameters are %s", param_string.c_str());
226 driver->setId(id());
227 //try to open the device:
228 bool ok = driver->open(*config);
229 //if the device did not open successfully
230 if (!ok)
231 {
232 yCIError(POLYDRIVER, id(), "Driver <%s> was found but could not open", config->find("device").toString().c_str());
233 delete driver;
234 driver = nullptr;
235 }
236 //if the device opened successfully
237 else
238 {
239 //if the device is deprecated...
241 driver->view(ddd);
242 if(ddd)
243 {
244 //but the user requested it explicitly, than just print a warning
245 if(config->check("allow-deprecated-devices")) {
246 yCIWarning(POLYDRIVER, id(), R"(Device "%s" is deprecated. Opening since the "allow-deprecated-devices" option was passed in the configuration.)", device_name.c_str());
247 //if it is not requested explicitly, then close it with an error
248 } else {
249 yCIError(POLYDRIVER, id(), R"(Device "%s" is deprecated. Pass the "allow-deprecated-devices" option in the configuration if you want to open it anyway.)", device_name.c_str());
250 driver->close();
251 delete driver;
252 return false;
253 }
254 }
255 //print some info
256 std::string name = deviceCreator->getName();
257 std::string wrapper = deviceCreator->getWrapper();
258 std::string code = deviceCreator->getCode();
259 yCIInfo(POLYDRIVER, id(), "Created %s <%s>. See C++ class %s for documentation.",
260 ((name==wrapper)?"wrapper":"device"),
261 name.c_str(),
262 code.c_str());
263 }
264 m_dd = driver;
265 return true;
266 }
267
268 return false;
269}
270
271
273{
274 // this is not very careful
275 DeviceDriver *result = m_dd;
276 m_dd = nullptr;
277 return result;
278}
279
281{
282 close();
283 this->m_dd = dd;
284 if (dd!=nullptr) {
285 if (m_Priv ==nullptr) {
287 }
288 yCAssert(POLYDRIVER, m_Priv != nullptr);
289 if (!own) {
290 m_Priv->addRef();
291 }
292 }
293 return true;
294}
295
297{
298 if(isValid()) {
299 return m_dd->getImplementation();
300 } else {
301 return nullptr;
302 }
303}
std::string toString(const T &value)
convert an arbitrary type to string.
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
#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.
Definition jointData.cpp:13
An interface to the operating system, including Port based communication.