All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
common/Plugin.hh
Go to the documentation of this file.
1 /*
2  * Copyright 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 #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 "common/CommonTypes.hh"
35 #include "common/SystemPaths.hh"
36 #include "common/Console.hh"
37 #include "common/Exception.hh"
38 
39 #include "physics/PhysicsTypes.hh"
40 #include "sensors/SensorTypes.hh"
41 #include "sdf/sdf.hh"
42 #include "rendering/RenderTypes.hh"
43 
44 namespace gazebo
45 {
46  class Event;
47 
50 
54  {
65  };
66 
67 
70  template<class T>
71  class PluginT
72  {
74  public: typedef boost::shared_ptr<T> TPtr;
75 
77  public: std::string GetFilename() const
78  {
79  return this->filename;
80  }
81 
83  public: std::string GetHandle() const
84  {
85  return this->handle;
86  }
87 
93  public: static TPtr Create(const std::string &_filename,
94  const std::string &_handle)
95  {
96  TPtr result;
97  // PluginPtr result;
98  struct stat st;
99  bool found = false;
100  std::string fullname;
101  std::list<std::string>::iterator iter;
102  std::list<std::string> pluginPaths =
103  common::SystemPaths::Instance()->GetPluginPaths();
104 
105  for (iter = pluginPaths.begin();
106  iter!= pluginPaths.end(); ++iter)
107  {
108  fullname = (*iter)+std::string("/")+_filename;
109  if (stat(fullname.c_str(), &st) == 0)
110  {
111  found = true;
112  break;
113  }
114  }
115 
116  if (!found)
117  fullname = _filename;
118 
119 #ifdef HAVE_DL
120  fptr_union_t registerFunc;
121  std::string registerName = "RegisterPlugin";
122 
123  void* handle = dlopen(fullname.c_str(), RTLD_LAZY|RTLD_GLOBAL);
124  if (!handle)
125  {
126  gzerr << "Failed to load plugin " << fullname << ": "
127  << dlerror() << "\n";
128  return result;
129  }
130 
131  registerFunc.ptr = dlsym(handle, registerName.c_str());
132 
133  if (!registerFunc.ptr)
134  {
135  gzerr << "Failed to resolve " << registerName
136  << ": " << dlerror();
137  return result;
138  }
139 
140  // Register the new controller.
141  result.reset(registerFunc.func());
142 
143 #elif HAVE_LTDL
144  fptr_union_t registerFunc;
145  std::string registerName = "RegisterPlugin";
146 
147  static bool init_done = false;
148 
149  if (!init_done)
150  {
151  int errors = lt_dlinit();
152  if (errors)
153  {
154  gzerr << "Error(s) initializing dynamic loader ("
155  << errors << ", " << lt_dlerror() << ")";
156  return NULL;
157  }
158  else
159  init_done = true;
160  }
161 
162  lt_dlhandle handle = lt_dlopenext(fullname.c_str());
163 
164  if (!handle)
165  {
166  gzerr << "Failed to load " << fullname
167  << ": " << lt_dlerror();
168  return NULL;
169  }
170 
171  T *(*registerFunc)() =
172  (T *(*)())lt_dlsym(handle, registerName.c_str());
173  resigsterFunc.ptr = lt_dlsym(handle, registerName.c_str());
174  if (!registerFunc.ptr)
175  {
176  gzerr << "Failed to resolve " << registerName << ": "
177  << lt_dlerror();
178  return NULL;
179  }
180 
181  // Register the new controller.
182  result.result(registerFunc.func());
183 
184 #else // HAVE_LTDL
185 
186  gzthrow("Cannot load plugins as libtool is not installed.");
187 
188 #endif // HAVE_LTDL
189 
190  result->handle = _handle;
191  result->filename = _filename;
192 
193  return result;
194  }
195 
198  public: PluginType GetType() const
199  {
200  return this->type;
201  }
202 
204  protected: PluginType type;
205 
207  protected: std::string filename;
208 
210  protected: std::string handle;
211 
213  private: typedef union
214  {
215  T *(*func)();
216  void *ptr;
217  } fptr_union_t;
218  };
219 
224  class WorldPlugin : public PluginT<WorldPlugin>
225  {
227  public: WorldPlugin()
228  {this->type = WORLD_PLUGIN;}
229 
231  public: virtual ~WorldPlugin() {}
232 
239  public: virtual void Load(physics::WorldPtr _world,
240  sdf::ElementPtr _sdf) = 0;
241 
242  public: virtual void Init() {}
243  public: virtual void Reset() {}
244  };
245 
249  class ModelPlugin : public PluginT<ModelPlugin>
250  {
252  public: ModelPlugin()
253  {this->type = MODEL_PLUGIN;}
254 
256  public: virtual ~ModelPlugin() {}
257 
264  public: virtual void Load(physics::ModelPtr _model,
265  sdf::ElementPtr _sdf) = 0;
266 
268  public: virtual void Init() {}
269 
271  public: virtual void Reset() {}
272  };
273 
278  class SensorPlugin : public PluginT<SensorPlugin>
279  {
281  public: SensorPlugin()
282  {this->type = SENSOR_PLUGIN;}
283 
285  public: virtual ~SensorPlugin() {}
286 
293  public: virtual void Load(sensors::SensorPtr _sensor,
294  sdf::ElementPtr _sdf) = 0;
295 
297  public: virtual void Init() {}
298 
300  public: virtual void Reset() {}
301  };
302 
307  class SystemPlugin : public PluginT<SystemPlugin>
308  {
310  public: SystemPlugin()
311  {this->type = SYSTEM_PLUGIN;}
312 
314  public: virtual ~SystemPlugin() {}
315 
321  public: virtual void Load(int _argc = 0, char **_argv = NULL) = 0;
322 
326  public: virtual void Init() {}
327 
329  public: virtual void Reset() {}
330  };
331 
335  class VisualPlugin : public PluginT<VisualPlugin>
336  {
337  public: VisualPlugin()
338  {this->type = VISUAL_PLUGIN;}
339 
346  public: virtual void Load(rendering::VisualPtr _visual,
347  sdf::ElementPtr _sdf) = 0;
348 
352  public: virtual void Init() {}
353 
355  public: virtual void Reset() {}
356  };
357 
359 
364 #define GZ_REGISTER_MODEL_PLUGIN(classname) \
365  extern "C" gazebo::ModelPlugin *RegisterPlugin(); \
366  gazebo::ModelPlugin *RegisterPlugin() \
367  {\
368  return new classname();\
369  }
370 
375 #define GZ_REGISTER_WORLD_PLUGIN(classname) \
376  extern "C" gazebo::WorldPlugin *RegisterPlugin(); \
377  gazebo::WorldPlugin *RegisterPlugin() \
378  {\
379  return new classname();\
380  }
381 
386 #define GZ_REGISTER_SENSOR_PLUGIN(classname) \
387  extern "C" gazebo::SensorPlugin *RegisterPlugin(); \
388  gazebo::SensorPlugin *RegisterPlugin() \
389  {\
390  return new classname();\
391  }
392 
397 #define GZ_REGISTER_SYSTEM_PLUGIN(classname) \
398  extern "C" gazebo::SystemPlugin *RegisterPlugin(); \
399  gazebo::SystemPlugin *RegisterPlugin() \
400  {\
401  return new classname();\
402  }
403 
408 #define GZ_REGISTER_VISUAL_PLUGIN(classname) \
409  extern "C" gazebo::VisualPlugin *RegisterPlugin(); \
410  gazebo::VisualPlugin *RegisterPlugin() \
411  {\
412  return new classname();\
413  }
414 }
415 
416 #endif