All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Plugin.hh
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2012-2014 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 #include <unistd.h>
21 #include <sys/types.h>
22 #include <sys/stat.h>
23 
24 #include <gazebo/gazebo_config.h>
25 #ifdef HAVE_DL
26 #include <dlfcn.h>
27 #elif HAVE_LTDL
28 #include <ltdl.h>
29 #endif
30 
31 #include <list>
32 #include <string>
33 
34 #include <sdf/sdf.hh>
35 
38 #include "gazebo/common/Console.hh"
40 
44 
45 namespace gazebo
46 {
47  class Event;
48 
51 
55  {
66  };
67 
68 
71  template<class T>
72  class PluginT
73  {
75  public: typedef boost::shared_ptr<T> TPtr;
76 
78  public: PluginT()
79  {
80  this->dlHandle = NULL;
81  }
82 
84  public: virtual ~PluginT()
85  {
86 #ifdef HAVE_DL
87  dlclose(this->dlHandle);
88 #endif
89  }
90 
92  public: std::string GetFilename() const
93  {
94  return this->filename;
95  }
96 
98  public: std::string GetHandle() const
99  {
100  return this->handle;
101  }
102 
108  public: static TPtr Create(const std::string &_filename,
109  const std::string &_handle)
110  {
111  TPtr result;
112  // PluginPtr result;
113  struct stat st;
114  bool found = false;
115  std::string fullname;
116  std::list<std::string>::iterator iter;
117  std::list<std::string> pluginPaths =
118  common::SystemPaths::Instance()->GetPluginPaths();
119 
120  for (iter = pluginPaths.begin();
121  iter!= pluginPaths.end(); ++iter)
122  {
123  fullname = (*iter)+std::string("/")+_filename;
124  if (stat(fullname.c_str(), &st) == 0)
125  {
126  found = true;
127  break;
128  }
129  }
130 
131  if (!found)
132  fullname = _filename;
133 
134 #ifdef HAVE_DL
135  fptr_union_t registerFunc;
136  std::string registerName = "RegisterPlugin";
137 
138  void *dlHandle = dlopen(fullname.c_str(), RTLD_LAZY|RTLD_GLOBAL);
139  if (!dlHandle)
140  {
141  gzerr << "Failed to load plugin " << fullname << ": "
142  << dlerror() << "\n";
143  return result;
144  }
145 
146  registerFunc.ptr = dlsym(dlHandle, registerName.c_str());
147 
148  if (!registerFunc.ptr)
149  {
150  gzerr << "Failed to resolve " << registerName
151  << ": " << dlerror();
152  return result;
153  }
154 
155  // Register the new controller.
156  result.reset(registerFunc.func());
157  result->dlHandle = dlHandle;
158 
159 #elif HAVE_LTDL
160  gzerr << "LTDL is deprecated as of Gazebo 2.0\n";
161  fptr_union_t registerFunc;
162  std::string registerName = "RegisterPlugin";
163 
164  static bool init_done = false;
165 
166  if (!init_done)
167  {
168  int errors = lt_dlinit();
169  if (errors)
170  {
171  gzerr << "Error(s) initializing dynamic loader ("
172  << errors << ", " << lt_dlerror() << ")";
173  return NULL;
174  }
175  else
176  init_done = true;
177  }
178 
179  lt_dlhandle handle = lt_dlopenext(fullname.c_str());
180 
181  if (!handle)
182  {
183  gzerr << "Failed to load " << fullname
184  << ": " << lt_dlerror();
185  return NULL;
186  }
187 
188  T *(*registerFunc)() =
189  (T *(*)())lt_dlsym(handle, registerName.c_str());
190  resigsterFunc.ptr = lt_dlsym(handle, registerName.c_str());
191  if (!registerFunc.ptr)
192  {
193  gzerr << "Failed to resolve " << registerName << ": "
194  << lt_dlerror();
195  return NULL;
196  }
197 
198  // Register the new controller.
199  result.result(registerFunc.func());
200  result->dlHandle = NULL;
201 
202 #else // HAVE_LTDL
203 
204  gzthrow("Cannot load plugins as libtool is not installed.");
205 
206 #endif // HAVE_LTDL
207 
208  result->handle = _handle;
209  result->filename = _filename;
210 
211  return result;
212  }
213 
216  public: PluginType GetType() const
217  {
218  return this->type;
219  }
220 
222  protected: PluginType type;
223 
225  protected: std::string filename;
226 
228  protected: std::string handle;
229 
231  private: typedef union
232  {
233  T *(*func)();
234  void *ptr;
235  } fptr_union_t;
236 
238  private: void *dlHandle;
239  };
240 
245  class WorldPlugin : public PluginT<WorldPlugin>
246  {
248  public: WorldPlugin()
249  {this->type = WORLD_PLUGIN;}
250 
252  public: virtual ~WorldPlugin() {}
253 
260  public: virtual void Load(physics::WorldPtr _world,
261  sdf::ElementPtr _sdf) = 0;
262 
263  public: virtual void Init() {}
264  public: virtual void Reset() {}
265  };
266 
270  class ModelPlugin : public PluginT<ModelPlugin>
271  {
273  public: ModelPlugin()
274  {this->type = MODEL_PLUGIN;}
275 
277  public: virtual ~ModelPlugin() {}
278 
285  public: virtual void Load(physics::ModelPtr _model,
286  sdf::ElementPtr _sdf) = 0;
287 
289  public: virtual void Init() {}
290 
292  public: virtual void Reset() {}
293  };
294 
299  class SensorPlugin : public PluginT<SensorPlugin>
300  {
302  public: SensorPlugin()
303  {this->type = SENSOR_PLUGIN;}
304 
306  public: virtual ~SensorPlugin() {}
307 
314  public: virtual void Load(sensors::SensorPtr _sensor,
315  sdf::ElementPtr _sdf) = 0;
316 
318  public: virtual void Init() {}
319 
321  public: virtual void Reset() {}
322  };
323 
328  class SystemPlugin : public PluginT<SystemPlugin>
329  {
331  public: SystemPlugin()
332  {this->type = SYSTEM_PLUGIN;}
333 
335  public: virtual ~SystemPlugin() {}
336 
342  public: virtual void Load(int _argc = 0, char **_argv = NULL) = 0;
343 
347  public: virtual void Init() {}
348 
350  public: virtual void Reset() {}
351  };
352 
356  class VisualPlugin : public PluginT<VisualPlugin>
357  {
358  public: VisualPlugin()
359  {this->type = VISUAL_PLUGIN;}
360 
367  public: virtual void Load(rendering::VisualPtr _visual,
368  sdf::ElementPtr _sdf) = 0;
369 
373  public: virtual void Init() {}
374 
376  public: virtual void Reset() {}
377  };
378 
380 
385 #define GZ_REGISTER_MODEL_PLUGIN(classname) \
386  extern "C" gazebo::ModelPlugin *RegisterPlugin(); \
387  gazebo::ModelPlugin *RegisterPlugin() \
388  {\
389  return new classname();\
390  }
391 
396 #define GZ_REGISTER_WORLD_PLUGIN(classname) \
397  extern "C" gazebo::WorldPlugin *RegisterPlugin(); \
398  gazebo::WorldPlugin *RegisterPlugin() \
399  {\
400  return new classname();\
401  }
402 
407 #define GZ_REGISTER_SENSOR_PLUGIN(classname) \
408  extern "C" gazebo::SensorPlugin *RegisterPlugin(); \
409  gazebo::SensorPlugin *RegisterPlugin() \
410  {\
411  return new classname();\
412  }
413 
418 #define GZ_REGISTER_SYSTEM_PLUGIN(classname) \
419  extern "C" gazebo::SystemPlugin *RegisterPlugin(); \
420  gazebo::SystemPlugin *RegisterPlugin() \
421  {\
422  return new classname();\
423  }
424 
429 #define GZ_REGISTER_VISUAL_PLUGIN(classname) \
430  extern "C" gazebo::VisualPlugin *RegisterPlugin(); \
431  gazebo::VisualPlugin *RegisterPlugin() \
432  {\
433  return new classname();\
434  }
435 }
436 
437 #endif