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 2011 Nate Koenig
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 
68  template<class T>
69  class PluginT
70  {
72  public: typedef boost::shared_ptr<T> TPtr;
73 
75  public: std::string GetFilename() const
76  {
77  return this->filename;
78  }
79 
81  public: std::string GetHandle() const
82  {
83  return this->handle;
84  }
85 
90  public: static TPtr Create(const std::string &_filename,
91  const std::string &_handle)
92  {
93  TPtr result;
94  // PluginPtr result;
95  struct stat st;
96  bool found = false;
97  std::string fullname;
98  std::list<std::string>::iterator iter;
99  std::list<std::string> pluginPaths =
100  common::SystemPaths::Instance()->GetPluginPaths();
101 
102  for (iter = pluginPaths.begin();
103  iter!= pluginPaths.end(); ++iter)
104  {
105  fullname = (*iter)+std::string("/")+_filename;
106  if (stat(fullname.c_str(), &st) == 0)
107  {
108  found = true;
109  break;
110  }
111  }
112 
113  if (!found)
114  fullname = _filename;
115 
116  fptr_union_t registerFunc;
117  std::string registerName = "RegisterPlugin";
118 
119 #ifdef HAVE_DL
120  void* handle = dlopen(fullname.c_str(), RTLD_LAZY|RTLD_GLOBAL);
121  if (!handle)
122  {
123  gzerr << "Failed to load plugin " << fullname << ": "
124  << dlerror() << "\n";
125  return result;
126  }
127 
128  registerFunc.ptr = dlsym(handle, registerName.c_str());
129 
130  if (!registerFunc.ptr)
131  {
132  gzerr << "Failed to resolve " << registerName
133  << ": " << dlerror();
134  return result;
135  }
136 
137  // Register the new controller.
138  result.reset(registerFunc.func());
139 
140 #elif HAVE_LTDL
141 
142  static bool init_done = false;
143 
144  if (!init_done)
145  {
146  int errors = lt_dlinit();
147  if (errors)
148  {
149  gzerr << "Error(s) initializing dynamic loader ("
150  << errors << ", " << lt_dlerror() << ")";
151  return NULL;
152  }
153  else
154  init_done = true;
155  }
156 
157  lt_dlhandle handle = lt_dlopenext(fullname.c_str());
158 
159  if (!handle)
160  {
161  gzerr << "Failed to load " << fullname
162  << ": " << lt_dlerror();
163  return NULL;
164  }
165 
166  T *(*registerFunc)() =
167  (T *(*)())lt_dlsym(handle, registerName.c_str());
168  resigsterFunc.ptr = lt_dlsym(handle, registerName.c_str());
169  if (!registerFunc.ptr)
170  {
171  gzerr << "Failed to resolve " << registerName << ": "
172  << lt_dlerror();
173  return NULL;
174  }
175 
176  // Register the new controller.
177  result.result(registerFunc.func());
178 
179 #else // HAVE_LTDL
180 
181  gzthrow("Cannot load plugins as libtool is not installed.");
182 
183 #endif // HAVE_LTDL
184 
185  result->handle = _handle;
186  result->filename = _filename;
187 
188  return result;
189  }
190 
192  public: PluginType GetType() const
193  {
194  return this->type;
195  }
196 
198  protected: PluginType type;
199 
201  protected: std::string filename;
202 
204  protected: std::string handle;
205 
207  private: typedef union
208  {
209  T *(*func)();
210  void *ptr;
211  } fptr_union_t;
212  };
213 
217  class WorldPlugin : public PluginT<WorldPlugin>
218  {
220  public: WorldPlugin()
221  {this->type = WORLD_PLUGIN;}
222 
224  public: virtual ~WorldPlugin() {}
225 
232  public: virtual void Load(physics::WorldPtr _world,
233  sdf::ElementPtr _sdf) = 0;
234 
235  public: virtual void Init() {}
236  public: virtual void Reset() {}
237  };
238 
242  class ModelPlugin : public PluginT<ModelPlugin>
243  {
245  public: ModelPlugin()
246  {this->type = MODEL_PLUGIN;}
247 
249  public: virtual ~ModelPlugin() {}
250 
257  public: virtual void Load(physics::ModelPtr _model,
258  sdf::ElementPtr _sdf) = 0;
259 
261  public: virtual void Init() {}
262 
264  public: virtual void Reset() {}
265  };
266 
270  class SensorPlugin : public PluginT<SensorPlugin>
271  {
273  public: SensorPlugin()
274  {this->type = SENSOR_PLUGIN;}
275 
277  public: virtual ~SensorPlugin() {}
278 
285  public: virtual void Load(sensors::SensorPtr _sensor,
286  sdf::ElementPtr _sdf) = 0;
287 
289  public: virtual void Init() {}
290 
292  public: virtual void Reset() {}
293  };
294 
299  class SystemPlugin : public PluginT<SystemPlugin>
300  {
302  public: SystemPlugin()
303  {this->type = SYSTEM_PLUGIN;}
304 
306  public: virtual ~SystemPlugin() {}
307 
313  public: virtual void Load(int _argc = 0, char **_argv = NULL) = 0;
314 
318  public: virtual void Init() {}
319 
321  public: virtual void Reset() {}
322  };
323 
327  class VisualPlugin : public PluginT<VisualPlugin>
328  {
329  public: VisualPlugin()
330  {this->type = VISUAL_PLUGIN;}
331 
338  public: virtual void Load(rendering::VisualPtr _visual,
339  sdf::ElementPtr _sdf) = 0;
340 
344  public: virtual void Init() {}
345 
347  public: virtual void Reset() {}
348  };
349 
351 
356 #define GZ_REGISTER_MODEL_PLUGIN(classname) \
357  extern "C" gazebo::ModelPlugin *RegisterPlugin(); \
358  gazebo::ModelPlugin *RegisterPlugin() \
359  {\
360  return new classname();\
361  }
362 
367 #define GZ_REGISTER_WORLD_PLUGIN(classname) \
368  extern "C" gazebo::WorldPlugin *RegisterPlugin(); \
369  gazebo::WorldPlugin *RegisterPlugin() \
370  {\
371  return new classname();\
372  }
373 
378 #define GZ_REGISTER_SENSOR_PLUGIN(classname) \
379  extern "C" gazebo::SensorPlugin *RegisterPlugin(); \
380  gazebo::SensorPlugin *RegisterPlugin() \
381  {\
382  return new classname();\
383  }
384 
389 #define GZ_REGISTER_SYSTEM_PLUGIN(classname) \
390  extern "C" gazebo::SystemPlugin *RegisterPlugin(); \
391  gazebo::SystemPlugin *RegisterPlugin() \
392  {\
393  return new classname();\
394  }
395 
400 #define GZ_REGISTER_VISUAL_PLUGIN(classname) \
401  extern "C" gazebo::VisualPlugin *RegisterPlugin(); \
402  gazebo::VisualPlugin *RegisterPlugin() \
403  {\
404  return new classname();\
405  }
406 }
407 
408 #endif