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 <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: std::string GetFilename() const
79  {
80  return this->filename;
81  }
82 
84  public: std::string GetHandle() const
85  {
86  return this->handle;
87  }
88 
94  public: static TPtr Create(const std::string &_filename,
95  const std::string &_handle)
96  {
97  TPtr result;
98  // PluginPtr result;
99  struct stat st;
100  bool found = false;
101  std::string fullname;
102  std::list<std::string>::iterator iter;
103  std::list<std::string> pluginPaths =
104  common::SystemPaths::Instance()->GetPluginPaths();
105 
106  for (iter = pluginPaths.begin();
107  iter!= pluginPaths.end(); ++iter)
108  {
109  fullname = (*iter)+std::string("/")+_filename;
110  if (stat(fullname.c_str(), &st) == 0)
111  {
112  found = true;
113  break;
114  }
115  }
116 
117  if (!found)
118  fullname = _filename;
119 
120 #ifdef HAVE_DL
121  fptr_union_t registerFunc;
122  std::string registerName = "RegisterPlugin";
123 
124  void* handle = dlopen(fullname.c_str(), RTLD_LAZY|RTLD_GLOBAL);
125  if (!handle)
126  {
127  gzerr << "Failed to load plugin " << fullname << ": "
128  << dlerror() << "\n";
129  return result;
130  }
131 
132  registerFunc.ptr = dlsym(handle, registerName.c_str());
133 
134  if (!registerFunc.ptr)
135  {
136  gzerr << "Failed to resolve " << registerName
137  << ": " << dlerror();
138  return result;
139  }
140 
141  // Register the new controller.
142  result.reset(registerFunc.func());
143 
144 #elif HAVE_LTDL
145  fptr_union_t registerFunc;
146  std::string registerName = "RegisterPlugin";
147 
148  static bool init_done = false;
149 
150  if (!init_done)
151  {
152  int errors = lt_dlinit();
153  if (errors)
154  {
155  gzerr << "Error(s) initializing dynamic loader ("
156  << errors << ", " << lt_dlerror() << ")";
157  return NULL;
158  }
159  else
160  init_done = true;
161  }
162 
163  lt_dlhandle handle = lt_dlopenext(fullname.c_str());
164 
165  if (!handle)
166  {
167  gzerr << "Failed to load " << fullname
168  << ": " << lt_dlerror();
169  return NULL;
170  }
171 
172  T *(*registerFunc)() =
173  (T *(*)())lt_dlsym(handle, registerName.c_str());
174  resigsterFunc.ptr = lt_dlsym(handle, registerName.c_str());
175  if (!registerFunc.ptr)
176  {
177  gzerr << "Failed to resolve " << registerName << ": "
178  << lt_dlerror();
179  return NULL;
180  }
181 
182  // Register the new controller.
183  result.result(registerFunc.func());
184 
185 #else // HAVE_LTDL
186 
187  gzthrow("Cannot load plugins as libtool is not installed.");
188 
189 #endif // HAVE_LTDL
190 
191  result->handle = _handle;
192  result->filename = _filename;
193 
194  return result;
195  }
196 
199  public: PluginType GetType() const
200  {
201  return this->type;
202  }
203 
205  protected: PluginType type;
206 
208  protected: std::string filename;
209 
211  protected: std::string handle;
212 
214  private: typedef union
215  {
216  T *(*func)();
217  void *ptr;
218  } fptr_union_t;
219  };
220 
225  class WorldPlugin : public PluginT<WorldPlugin>
226  {
228  public: WorldPlugin()
229  {this->type = WORLD_PLUGIN;}
230 
232  public: virtual ~WorldPlugin() {}
233 
240  public: virtual void Load(physics::WorldPtr _world,
241  sdf::ElementPtr _sdf) = 0;
242 
243  public: virtual void Init() {}
244  public: virtual void Reset() {}
245  };
246 
250  class ModelPlugin : public PluginT<ModelPlugin>
251  {
253  public: ModelPlugin()
254  {this->type = MODEL_PLUGIN;}
255 
257  public: virtual ~ModelPlugin() {}
258 
265  public: virtual void Load(physics::ModelPtr _model,
266  sdf::ElementPtr _sdf) = 0;
267 
269  public: virtual void Init() {}
270 
272  public: virtual void Reset() {}
273  };
274 
279  class SensorPlugin : public PluginT<SensorPlugin>
280  {
282  public: SensorPlugin()
283  {this->type = SENSOR_PLUGIN;}
284 
286  public: virtual ~SensorPlugin() {}
287 
294  public: virtual void Load(sensors::SensorPtr _sensor,
295  sdf::ElementPtr _sdf) = 0;
296 
298  public: virtual void Init() {}
299 
301  public: virtual void Reset() {}
302  };
303 
308  class SystemPlugin : public PluginT<SystemPlugin>
309  {
311  public: SystemPlugin()
312  {this->type = SYSTEM_PLUGIN;}
313 
315  public: virtual ~SystemPlugin() {}
316 
322  public: virtual void Load(int _argc = 0, char **_argv = NULL) = 0;
323 
327  public: virtual void Init() {}
328 
330  public: virtual void Reset() {}
331  };
332 
336  class VisualPlugin : public PluginT<VisualPlugin>
337  {
338  public: VisualPlugin()
339  {this->type = VISUAL_PLUGIN;}
340 
347  public: virtual void Load(rendering::VisualPtr _visual,
348  sdf::ElementPtr _sdf) = 0;
349 
353  public: virtual void Init() {}
354 
356  public: virtual void Reset() {}
357  };
358 
360 
365 #define GZ_REGISTER_MODEL_PLUGIN(classname) \
366  extern "C" gazebo::ModelPlugin *RegisterPlugin(); \
367  gazebo::ModelPlugin *RegisterPlugin() \
368  {\
369  return new classname();\
370  }
371 
376 #define GZ_REGISTER_WORLD_PLUGIN(classname) \
377  extern "C" gazebo::WorldPlugin *RegisterPlugin(); \
378  gazebo::WorldPlugin *RegisterPlugin() \
379  {\
380  return new classname();\
381  }
382 
387 #define GZ_REGISTER_SENSOR_PLUGIN(classname) \
388  extern "C" gazebo::SensorPlugin *RegisterPlugin(); \
389  gazebo::SensorPlugin *RegisterPlugin() \
390  {\
391  return new classname();\
392  }
393 
398 #define GZ_REGISTER_SYSTEM_PLUGIN(classname) \
399  extern "C" gazebo::SystemPlugin *RegisterPlugin(); \
400  gazebo::SystemPlugin *RegisterPlugin() \
401  {\
402  return new classname();\
403  }
404 
409 #define GZ_REGISTER_VISUAL_PLUGIN(classname) \
410  extern "C" gazebo::VisualPlugin *RegisterPlugin(); \
411  gazebo::VisualPlugin *RegisterPlugin() \
412  {\
413  return new classname();\
414  }
415 }
416 
417 #endif