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_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  fptr_union_t registerFunc;
120  std::string registerName = "RegisterPlugin";
121 
122 #ifdef HAVE_DL
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 
145  static bool init_done = false;
146 
147  if (!init_done)
148  {
149  int errors = lt_dlinit();
150  if (errors)
151  {
152  gzerr << "Error(s) initializing dynamic loader ("
153  << errors << ", " << lt_dlerror() << ")";
154  return NULL;
155  }
156  else
157  init_done = true;
158  }
159 
160  lt_dlhandle handle = lt_dlopenext(fullname.c_str());
161 
162  if (!handle)
163  {
164  gzerr << "Failed to load " << fullname
165  << ": " << lt_dlerror();
166  return NULL;
167  }
168 
169  T *(*registerFunc)() =
170  (T *(*)())lt_dlsym(handle, registerName.c_str());
171  resigsterFunc.ptr = lt_dlsym(handle, registerName.c_str());
172  if (!registerFunc.ptr)
173  {
174  gzerr << "Failed to resolve " << registerName << ": "
175  << lt_dlerror();
176  return NULL;
177  }
178 
179  // Register the new controller.
180  result.result(registerFunc.func());
181 
182 #else // HAVE_LTDL
183 
184  gzthrow("Cannot load plugins as libtool is not installed.");
185 
186 #endif // HAVE_LTDL
187 
188  result->handle = _handle;
189  result->filename = _filename;
190 
191  return result;
192  }
193 
196  public: PluginType GetType() const
197  {
198  return this->type;
199  }
200 
202  protected: PluginType type;
203 
205  protected: std::string filename;
206 
208  protected: std::string handle;
209 
211  private: typedef union
212  {
213  T *(*func)();
214  void *ptr;
215  } fptr_union_t;
216  };
217 
222  class WorldPlugin : public PluginT<WorldPlugin>
223  {
225  public: WorldPlugin()
226  {this->type = WORLD_PLUGIN;}
227 
229  public: virtual ~WorldPlugin() {}
230 
237  public: virtual void Load(physics::WorldPtr _world,
238  sdf::ElementPtr _sdf) = 0;
239 
240  public: virtual void Init() {}
241  public: virtual void Reset() {}
242  };
243 
247  class ModelPlugin : public PluginT<ModelPlugin>
248  {
250  public: ModelPlugin()
251  {this->type = MODEL_PLUGIN;}
252 
254  public: virtual ~ModelPlugin() {}
255 
262  public: virtual void Load(physics::ModelPtr _model,
263  sdf::ElementPtr _sdf) = 0;
264 
266  public: virtual void Init() {}
267 
269  public: virtual void Reset() {}
270  };
271 
276  class SensorPlugin : public PluginT<SensorPlugin>
277  {
279  public: SensorPlugin()
280  {this->type = SENSOR_PLUGIN;}
281 
283  public: virtual ~SensorPlugin() {}
284 
291  public: virtual void Load(sensors::SensorPtr _sensor,
292  sdf::ElementPtr _sdf) = 0;
293 
295  public: virtual void Init() {}
296 
298  public: virtual void Reset() {}
299  };
300 
305  class SystemPlugin : public PluginT<SystemPlugin>
306  {
308  public: SystemPlugin()
309  {this->type = SYSTEM_PLUGIN;}
310 
312  public: virtual ~SystemPlugin() {}
313 
319  public: virtual void Load(int _argc = 0, char **_argv = NULL) = 0;
320 
324  public: virtual void Init() {}
325 
327  public: virtual void Reset() {}
328  };
329 
333  class VisualPlugin : public PluginT<VisualPlugin>
334  {
335  public: VisualPlugin()
336  {this->type = VISUAL_PLUGIN;}
337 
344  public: virtual void Load(rendering::VisualPtr _visual,
345  sdf::ElementPtr _sdf) = 0;
346 
350  public: virtual void Init() {}
351 
353  public: virtual void Reset() {}
354  };
355 
357 
362 #define GZ_REGISTER_MODEL_PLUGIN(classname) \
363  extern "C" gazebo::ModelPlugin *RegisterPlugin(); \
364  gazebo::ModelPlugin *RegisterPlugin() \
365  {\
366  return new classname();\
367  }
368 
373 #define GZ_REGISTER_WORLD_PLUGIN(classname) \
374  extern "C" gazebo::WorldPlugin *RegisterPlugin(); \
375  gazebo::WorldPlugin *RegisterPlugin() \
376  {\
377  return new classname();\
378  }
379 
384 #define GZ_REGISTER_SENSOR_PLUGIN(classname) \
385  extern "C" gazebo::SensorPlugin *RegisterPlugin(); \
386  gazebo::SensorPlugin *RegisterPlugin() \
387  {\
388  return new classname();\
389  }
390 
395 #define GZ_REGISTER_SYSTEM_PLUGIN(classname) \
396  extern "C" gazebo::SystemPlugin *RegisterPlugin(); \
397  gazebo::SystemPlugin *RegisterPlugin() \
398  {\
399  return new classname();\
400  }
401 
406 #define GZ_REGISTER_VISUAL_PLUGIN(classname) \
407  extern "C" gazebo::VisualPlugin *RegisterPlugin(); \
408  gazebo::VisualPlugin *RegisterPlugin() \
409  {\
410  return new classname();\
411  }
412 }
413 
414 #endif