Plugin.hh
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2012 Open Source Robotics Foundation
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17 #ifndef _GZ_PLUGIN_HH_
18 #define _GZ_PLUGIN_HH_
19 
20 #ifndef _WIN32
21  #include <unistd.h>
22 #endif
23 
24 #include <sys/types.h>
25 #include <sys/stat.h>
26 
27 #include <gazebo/gazebo_config.h>
28 #include <dlfcn.h>
29 
30 #include <list>
31 #include <string>
32 
33 #include <sdf/sdf.hh>
34 #include <boost/filesystem.hpp>
35 
38 #include "gazebo/common/Console.hh"
40 
44 #include "gazebo/util/system.hh"
45 
46 namespace gazebo
47 {
48  class Event;
49 
52 
56  {
69  };
70 
71 
74  template<class T>
75  class PluginT
76  {
78  public: typedef boost::shared_ptr<T> TPtr;
79 
81  public: PluginT()
82  {
83  this->dlHandle = nullptr;
84  }
85 
87  public: virtual ~PluginT()
88  {
89  // dlclose has been disabled due to segfaults in the test suite
90  // This workaround is detailed in #1026 and #1066. After the test
91  // or gazebo execution the plugin is not loaded in memory anymore
92  // \todo Figure out the right thing to do.
93 
94  // dlclose(this->dlHandle);
95  }
96 
98  public: std::string GetFilename() const
99  {
100  return this->filename;
101  }
102 
104  public: std::string GetHandle() const
105  {
106  return this->handleName;
107  }
108 
114  public: static TPtr Create(const std::string &_filename,
115  const std::string &_name)
116  {
117  TPtr result;
118  // PluginPtr result;
119  struct stat st;
120  bool found = false;
121  std::string fullname, filename(_filename);
122  std::list<std::string>::iterator iter;
123  std::list<std::string> pluginPaths =
124  common::SystemPaths::Instance()->GetPluginPaths();
125 
126 #ifdef __APPLE__
127  // This is a hack to work around issue #800,
128  // error loading plugin libraries with different extensions
129  {
130  size_t soSuffix = filename.rfind(".so");
131  if (soSuffix != std::string::npos)
132  {
133  const std::string macSuffix(".dylib");
134  filename.replace(soSuffix, macSuffix.length(), macSuffix);
135  }
136  }
137 #elif _WIN32
138  // Corresponding windows hack
139  {
140  // replace .so with .dll
141  size_t soSuffix = filename.rfind(".so");
142  if (soSuffix != std::string::npos)
143  {
144  const std::string winSuffix(".dll");
145  filename.replace(soSuffix, winSuffix.length(), winSuffix);
146  }
147  size_t libPrefix = filename.find("lib");
148  if (libPrefix == 0)
149  {
150  // remove the lib prefix
151  filename.erase(0, 3);
152  }
153  }
154 #endif // ifdef __APPLE__
155 
156  for (iter = pluginPaths.begin();
157  iter!= pluginPaths.end(); ++iter)
158  {
159  fullname = (*iter)+std::string("/")+filename;
160  fullname = boost::filesystem::path(fullname)
161  .make_preferred().string();
162  if (stat(fullname.c_str(), &st) == 0)
163  {
164  found = true;
165  break;
166  }
167  }
168 
169  if (!found)
170  fullname = filename;
171 
172  fptr_union_t registerFunc;
173  std::string registerName = "RegisterPlugin";
174 
175  void *dlHandle = dlopen(fullname.c_str(), RTLD_LAZY|RTLD_GLOBAL);
176  if (!dlHandle)
177  {
178  gzerr << "Failed to load plugin " << fullname << ": "
179  << dlerror() << "\n";
180  return result;
181  }
182 
183  registerFunc.ptr = dlsym(dlHandle, registerName.c_str());
184 
185  if (!registerFunc.ptr)
186  {
187  gzerr << "Failed to resolve " << registerName
188  << ": " << dlerror();
189  return result;
190  }
191 
192  // Register the new controller.
193  result.reset(registerFunc.func());
194  result->dlHandle = dlHandle;
195 
196  result->handleName = _name;
197  result->filename = filename;
198 
199  return result;
200  }
201 
204  public: PluginType GetType() const
205  {
206  return this->type;
207  }
208 
217  protected: template <typename V> void LoadParam(const sdf::ElementPtr &_sdf,
218  const std::string &_name, V &_target,
219  V _defaultValue = V()) const
220  {
221  auto result = _sdf->Get<V>(_name, _defaultValue);
222 
223  if (!result.second)
224  {
225  gzmsg << this->handleName.c_str() << " Plugin missing <"
226  << _name.c_str() << ">, defaults to "
227  << result.first << std::endl;
228  }
229  else
230  {
231  gzmsg << this->handleName.c_str() << " Plugin <"
232  << _name.c_str() << "> set to "
233  << result.first << std::endl;
234  }
235  _target = result.first;
236  }
237 
247  protected: void LoadParam(sdf::ElementPtr &_sdf,
248  const std::string &_name, std::string &_target,
249  const char* _defaultValue) const
250  {
251  this->LoadParam<std::string>(_sdf, _name, _target, _defaultValue);
252  }
253 
255  protected: PluginType type;
256 
258  protected: std::string filename;
259 
261  protected: std::string handleName;
262 
264  private: typedef union
265  {
266  T *(*func)();
267  void *ptr;
268  } fptr_union_t;
269 
271  private: void *dlHandle;
272  };
273 
278  class WorldPlugin : public PluginT<WorldPlugin>
279  {
281  public: WorldPlugin()
282  {this->type = WORLD_PLUGIN;}
283 
285  public: virtual ~WorldPlugin() {}
286 
293  public: virtual void Load(physics::WorldPtr _world,
294  sdf::ElementPtr _sdf) = 0;
295 
296  public: virtual void Init() {}
297  public: virtual void Reset() {}
298  };
299 
303  class ModelPlugin : public PluginT<ModelPlugin>
304  {
306  public: ModelPlugin()
307  {this->type = MODEL_PLUGIN;}
308 
310  public: virtual ~ModelPlugin() {}
311 
318  public: virtual void Load(physics::ModelPtr _model,
319  sdf::ElementPtr _sdf) = 0;
320 
322  public: virtual void Init() {}
323 
325  public: virtual void Reset() {}
326  };
327 
332  class SensorPlugin : public PluginT<SensorPlugin>
333  {
335  public: SensorPlugin()
336  {this->type = SENSOR_PLUGIN;}
337 
339  public: virtual ~SensorPlugin() {}
340 
347  public: virtual void Load(sensors::SensorPtr _sensor,
348  sdf::ElementPtr _sdf) = 0;
349 
351  public: virtual void Init() {}
352 
354  public: virtual void Reset() {}
355  };
356 
361  class SystemPlugin : public PluginT<SystemPlugin>
362  {
364  public: SystemPlugin()
365  {this->type = SYSTEM_PLUGIN;}
366 
368  public: virtual ~SystemPlugin() {}
369 
375  public: virtual void Load(int _argc = 0, char **_argv = nullptr) = 0;
376 
380  public: virtual void Init() {}
381 
383  public: virtual void Reset() {}
384  };
385 
389  class VisualPlugin : public PluginT<VisualPlugin>
390  {
391  public: VisualPlugin()
392  {this->type = VISUAL_PLUGIN;}
393 
400  public: virtual void Load(rendering::VisualPtr _visual,
401  sdf::ElementPtr _sdf) = 0;
402 
406  public: virtual void Init() {}
407 
409  public: virtual void Reset() {}
410  };
411 
412 
414 
419 #define GZ_REGISTER_MODEL_PLUGIN(classname) \
420  extern "C" GZ_PLUGIN_VISIBLE gazebo::ModelPlugin *RegisterPlugin(); \
421  gazebo::ModelPlugin *RegisterPlugin() \
422  {\
423  return new classname();\
424  }
425 
430 #define GZ_REGISTER_WORLD_PLUGIN(classname) \
431  extern "C" GZ_PLUGIN_VISIBLE gazebo::WorldPlugin *RegisterPlugin(); \
432  gazebo::WorldPlugin *RegisterPlugin() \
433  {\
434  return new classname();\
435  }
436 
441 #define GZ_REGISTER_SENSOR_PLUGIN(classname) \
442  extern "C" GZ_PLUGIN_VISIBLE gazebo::SensorPlugin *RegisterPlugin(); \
443  gazebo::SensorPlugin *RegisterPlugin() \
444  {\
445  return new classname();\
446  }
447 
452 #define GZ_REGISTER_SYSTEM_PLUGIN(classname) \
453  extern "C" GZ_PLUGIN_VISIBLE gazebo::SystemPlugin *RegisterPlugin(); \
454  gazebo::SystemPlugin *RegisterPlugin() \
455  {\
456  return new classname();\
457  }
458 
463 #define GZ_REGISTER_VISUAL_PLUGIN(classname) \
464  extern "C" GZ_PLUGIN_VISIBLE gazebo::VisualPlugin *RegisterPlugin(); \
465  gazebo::VisualPlugin *RegisterPlugin() \
466  {\
467  return new classname();\
468  }
469 }
470 
471 #endif
#define gzmsg
Output a message.
Definition: Console.hh:41
std::shared_ptr< Sensor > SensorPtr
Definition: SensorTypes.hh:64
std::string handleName
Short name.
Definition: Plugin.hh:261
boost::shared_ptr< World > WorldPtr
Definition: PhysicsTypes.hh:90
Forward declarations for the common classes.
Definition: Animation.hh:26
std::string filename
Path to the shared library file.
Definition: Plugin.hh:258
std::string GetFilename() const
Get the name of the handler.
Definition: Plugin.hh:98
static TPtr Create(const std::string &_filename, const std::string &_name)
a class method that creates a plugin from a file name.
Definition: Plugin.hh:114
virtual void Reset()
Definition: Plugin.hh:297
std::string GetHandle() const
Get the short name of the handler.
Definition: Plugin.hh:104
PluginType type
Type of plugin.
Definition: Plugin.hh:255
A plugin with access to physics::World.
Definition: Plugin.hh:278
A plugin with access to rendering::Visual.
Definition: Plugin.hh:389
virtual void Init()
Override this method for custom plugin initialization behavior.
Definition: Plugin.hh:351
#define gzerr
Output an error message.
Definition: Console.hh:50
A World plugin.
Definition: Plugin.hh:58
virtual void Reset()
Override this method for custom plugin reset behavior.
Definition: Plugin.hh:383
default namespace for gazebo
virtual void Reset()
Override this method for custom plugin reset behavior.
Definition: Plugin.hh:409
A plugin loaded within the gzserver on startup.
Definition: Plugin.hh:361
A GUI plugin.
Definition: Plugin.hh:68
PluginType
Used to specify the type of plugin.
Definition: Plugin.hh:55
A Sensor plugin.
Definition: Plugin.hh:62
virtual void Reset()
Override this method for custom plugin reset behavior.
Definition: Plugin.hh:325
virtual void Reset()
Override this method for custom plugin reset behavior.
Definition: Plugin.hh:354
virtual void Init()
Definition: Plugin.hh:296
virtual ~PluginT()
Destructor.
Definition: Plugin.hh:87
virtual ~SystemPlugin()
Destructor.
Definition: Plugin.hh:368
boost::shared_ptr< T > TPtr
plugin pointer type definition
Definition: Plugin.hh:78
VisualPlugin()
Definition: Plugin.hh:391
virtual void Init()
Initialize the plugin.
Definition: Plugin.hh:406
PluginType GetType() const
Returns the type of the plugin.
Definition: Plugin.hh:204
A class which all plugins must inherit from.
Definition: Plugin.hh:75
SystemPlugin()
Constructor.
Definition: Plugin.hh:364
A Model plugin.
Definition: Plugin.hh:60
ModelPlugin()
Constructor.
Definition: Plugin.hh:306
virtual ~WorldPlugin()
Destructor.
Definition: Plugin.hh:285
std::shared_ptr< Visual > VisualPtr
Definition: RenderTypes.hh:114
boost::shared_ptr< Model > ModelPtr
Definition: PhysicsTypes.hh:94
SensorPlugin()
Constructor.
Definition: Plugin.hh:335
Forward declarations and typedefs for sensors.
WorldPlugin()
Constructor.
Definition: Plugin.hh:281
virtual void Init()
Initialize the plugin.
Definition: Plugin.hh:380
virtual ~SensorPlugin()
Destructor.
Definition: Plugin.hh:339
A Visual plugin.
Definition: Plugin.hh:66
PluginT()
Constructor.
Definition: Plugin.hh:81
A plugin with access to physics::Sensor.
Definition: Plugin.hh:332
A plugin with access to physics::Model.
Definition: Plugin.hh:303
void LoadParam(const sdf::ElementPtr &_sdf, const std::string &_name, V &_target, V _defaultValue=V()) const
Load parameter value from _sdf and store it to the given reference, using the supplied default value ...
Definition: Plugin.hh:217
void LoadParam(sdf::ElementPtr &_sdf, const std::string &_name, std::string &_target, const char *_defaultValue) const
Load parameter value from _sdf and store it to the given reference, using the supplied default value ...
Definition: Plugin.hh:247
virtual ~ModelPlugin()
Destructor.
Definition: Plugin.hh:310
virtual void Init()
Override this method for custom plugin initialization behavior.
Definition: Plugin.hh:322
static SystemPaths * Instance()
Get an instance of the singleton.
Definition: SingletonT.hh:36
A System plugin.
Definition: Plugin.hh:64