Plugin.hh
00001 /* 00002 * Copyright 2011 Nate Koenig & Andrew Howard 00003 * 00004 * Licensed under the Apache License, Version 2.0 (the "License"); 00005 * you may not use this file except in compliance with the License. 00006 * You may obtain a copy of the License at 00007 * 00008 * http://www.apache.org/licenses/LICENSE-2.0 00009 * 00010 * Unless required by applicable law or agreed to in writing, software 00011 * distributed under the License is distributed on an "AS IS" BASIS, 00012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00013 * See the License for the specific language governing permissions and 00014 * limitations under the License. 00015 * 00016 */ 00017 #ifndef PLUGIN_HH 00018 #define PLUGIN_HH 00019 00020 #include <string> 00021 #include <unistd.h> 00022 #include <sys/types.h> 00023 #include <list> 00024 #include <sys/stat.h> 00025 00026 #include "common/CommonTypes.hh" 00027 #include "common/SystemPaths.hh" 00028 #include "common/Console.hh" 00029 #include "common/Exception.hh" 00030 00031 #include "physics/PhysicsTypes.hh" 00032 #include "sensors/SensorTypes.hh" 00033 #include "sdf/sdf.h" 00034 00035 #include "gazebo_config.h" 00036 00037 #ifdef HAVE_DL 00038 #include <dlfcn.h> 00039 #elif HAVE_LTDL 00040 #include <ltdl.h> 00041 #endif 00042 00043 00044 namespace gazebo 00045 { 00046 class Event; 00047 00050 00052 template<class T> 00053 class PluginT 00054 { 00055 public: typedef boost::shared_ptr<T> TPtr; 00056 00058 public: std::string GetFilename() const 00059 { 00060 return this->filename; 00061 } 00062 00064 public: std::string GetHandle() const 00065 { 00066 return this->handle; 00067 } 00068 00069 public: static TPtr Create(const std::string &_filename, 00070 const std::string &_handle) 00071 { 00072 TPtr result; 00073 //PluginPtr result; 00074 struct stat st; 00075 bool found = false; 00076 std::string fullname; 00077 std::list<std::string>::iterator iter; 00078 std::list<std::string> pluginPaths= common::SystemPaths::Instance()->GetPluginPaths(); 00079 00080 for (iter=pluginPaths.begin(); iter!=pluginPaths.end(); ++iter) 00081 { 00082 fullname = (*iter)+std::string("/")+_filename; 00083 if (stat(fullname.c_str(), &st) == 0) 00084 { 00085 found=true; 00086 break; 00087 } 00088 } 00089 00090 if (!found) 00091 fullname = _filename; 00092 std::string registerName = "RegisterPlugin"; 00093 00094 typedef T *(*fptr)(); 00095 typedef union 00096 { 00097 fptr func; 00098 void *ptr; 00099 } fptr_union; 00100 fptr_union registerFunc; 00101 00102 #ifdef HAVE_DL 00103 void* handle = dlopen(fullname.c_str(), RTLD_LAZY|RTLD_GLOBAL); 00104 if (!handle) 00105 { 00106 gzerr << "Failed to load plugin " << fullname << ": " << dlerror() << "\n"; 00107 return result; 00108 } 00109 00110 registerFunc.ptr = dlsym(handle, registerName.c_str()); 00111 00112 if(!registerFunc.ptr) 00113 { 00114 gzerr << "Failed to resolve " << registerName << ": " << dlerror(); 00115 return result; 00116 } 00117 00118 // Register the new controller. 00119 result.reset( registerFunc.func() ); 00120 00121 #elif HAVE_LTDL 00122 00123 static bool init_done = false; 00124 00125 if (!init_done) 00126 { 00127 int errors = lt_dlinit(); 00128 if (errors) 00129 { 00130 gzerr << "Error(s) initializing dynamic loader (" 00131 << errors << ", " << lt_dlerror() << ")"; 00132 return NULL; 00133 } 00134 else 00135 init_done = true; 00136 } 00137 00138 lt_dlhandle handle = lt_dlopenext(fullname.c_str()); 00139 00140 if (!handle) 00141 { 00142 gzerr << "Failed to load " << fullname << ": " << lt_dlerror(); 00143 return NULL; 00144 } 00145 00146 T *(*registerFunc)() = (T *(*)())lt_dlsym(handle, registerName.c_str()); 00147 resigsterFunc.ptr = lt_dlsym(handle, registerName.c_str()); 00148 if(!registerFunc.ptr) 00149 { 00150 gzerr << "Failed to resolve " << registerName << ": " << lt_dlerror(); 00151 return NULL; 00152 } 00153 00154 // Register the new controller. 00155 result.result( registerFunc.func() ); 00156 00157 #else // HAVE_LTDL 00158 00159 gzthrow("Cannot load plugins as libtool is not installed."); 00160 00161 #endif // HAVE_LTDL 00162 00163 result->handle = _handle; 00164 result->filename = _filename; 00165 00166 return result; 00167 } 00168 00169 protected: std::string filename; 00170 protected: std::string handle; 00171 }; 00172 00173 class WorldPlugin : public PluginT<WorldPlugin> 00174 { 00176 public: virtual void Load(physics::WorldPtr &_world, 00177 sdf::ElementPtr &_sdf) = 0; 00178 public: virtual void Init() {}; 00179 public: virtual void Reset() {}; 00180 }; 00181 00182 class ModelPlugin : public PluginT<ModelPlugin> 00183 { 00185 public: virtual void Load(physics::ModelPtr &_model, 00186 sdf::ElementPtr &_sdf ) = 0; 00187 public: virtual void Init() {}; 00188 public: virtual void Reset() {}; 00189 }; 00190 00191 class SensorPlugin : public PluginT<SensorPlugin> 00192 { 00194 public: virtual void Load( 00195 sensors::SensorPtr &_sensor, sdf::ElementPtr &_sdf) = 0; 00196 public: virtual void Init() {}; 00197 public: virtual void Reset() {}; 00198 }; 00199 00200 class SystemPlugin : public PluginT<SystemPlugin> 00201 { 00203 public: virtual void Load() = 0; 00204 public: virtual void Init() {} 00205 public: virtual void Reset() {}; 00206 }; 00207 00209 00210 #define GZ_REGISTER_MODEL_PLUGIN(classname) \ 00211 extern "C" gazebo::ModelPlugin *RegisterPlugin(); \ 00212 gazebo::ModelPlugin *RegisterPlugin() \ 00213 {\ 00214 return new classname();\ 00215 } 00216 00217 #define GZ_REGISTER_WORLD_PLUGIN(classname) \ 00218 extern "C" gazebo::WorldPlugin *RegisterPlugin(); \ 00219 gazebo::WorldPlugin *RegisterPlugin() \ 00220 {\ 00221 return new classname();\ 00222 } 00223 00224 #define GZ_REGISTER_SENSOR_PLUGIN(classname) \ 00225 extern "C" gazebo::SensorPlugin *RegisterPlugin(); \ 00226 gazebo::SensorPlugin *RegisterPlugin() \ 00227 {\ 00228 return new classname();\ 00229 } 00230 00231 #define GZ_REGISTER_SYSTEM_PLUGIN(classname) \ 00232 extern "C" gazebo::SystemPlugin *RegisterPlugin(); \ 00233 gazebo::SystemPlugin *RegisterPlugin() \ 00234 {\ 00235 return new classname();\ 00236 } 00237 } 00238 #endif

1.7.5.1