loader.cpp
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include <plugin/loader.h>
00025
00026 #include <utils/system/dynamic_module/module_manager_factory.h>
00027 #include <utils/system/dynamic_module/module_manager.h>
00028 #include <utils/system/dynamic_module/module.h>
00029
00030 #include <map>
00031
00032 namespace fawkes {
00033 #if 0
00034 }
00035 #endif
00036
00037
00038 class PluginLoaderData
00039 {
00040 public:
00041 ModuleManager *mm;
00042 std::map< Plugin *, Module * > plugin_module_map;
00043 std::map< std::string, Plugin * > name_plugin_map;
00044 std::map< Plugin *, std::string > plugin_name_map;
00045 };
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056 PluginLoadException::PluginLoadException(const char *plugin, const char *message)
00057 : Exception()
00058 {
00059 append("Plugin '%s' could not be loaded: %s", plugin, message);
00060 }
00061
00062
00063
00064
00065
00066
00067
00068 PluginLoadException::PluginLoadException(const char *plugin, const char *message,
00069 Exception &e)
00070 : Exception()
00071 {
00072 append("Plugin '%s' could not be loaded: %s", plugin, message);
00073 copy_messages(e);
00074 }
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085 PluginUnloadException::PluginUnloadException(const char *plugin_name,
00086 const char *add_msg)
00087 : Exception()
00088 {
00089 append("Plugin '%s' could not be unloaded", plugin_name);
00090 append(add_msg);
00091 }
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107 PluginLoader::PluginLoader(const char *plugin_base_dir, Configuration *config)
00108 {
00109 d = new PluginLoaderData();
00110 __config = config;
00111 d->mm = ModuleManagerFactory::getInstance(ModuleManagerFactory::MMT_DL, plugin_base_dir);
00112 }
00113
00114
00115 PluginLoader::~PluginLoader()
00116 {
00117 delete d->mm;
00118 delete d;
00119 }
00120
00121
00122 Module *
00123 PluginLoader::open_module(const char *plugin_name)
00124 {
00125 std::string module_name = std::string(plugin_name) + "." + d->mm->get_module_file_extension();
00126
00127 try {
00128 return d->mm->open_module(module_name.c_str());
00129 } catch (ModuleOpenException &e) {
00130 throw PluginLoadException(plugin_name, "failed to open module", e);
00131 }
00132 }
00133
00134
00135 Plugin *
00136 PluginLoader::create_instance(const char *plugin_name, Module *module)
00137 {
00138 if ( ! module->has_symbol("plugin_factory") ) {
00139 throw PluginLoadException(plugin_name, "Symbol 'plugin_factory' not found. Forgot EXPORT_PLUGIN?");
00140 }
00141 if ( ! module->has_symbol("plugin_description") ) {
00142 throw PluginLoadException(plugin_name, "Symbol 'plugin_description' not found. Forgot PLUGIN_DESCRIPTION?");
00143 }
00144
00145 PluginFactoryFunc pff = (PluginFactoryFunc)module->get_symbol("plugin_factory");
00146 Plugin *p = NULL;
00147
00148 p = pff(__config);
00149 if ( p == NULL ) {
00150 throw PluginLoadException(plugin_name, "Plugin could not be instantiated");
00151 } else {
00152 p->set_name(plugin_name);
00153 }
00154
00155 return p;
00156 }
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175 Plugin *
00176 PluginLoader::load(const char *plugin_name)
00177 {
00178 std::string pn = plugin_name;
00179
00180 if ( d->name_plugin_map.find(pn) != d->name_plugin_map.end() ) {
00181 return d->name_plugin_map[pn];
00182 }
00183
00184 try {
00185 Module *module = open_module(plugin_name);
00186 Plugin *p = create_instance(plugin_name, module);
00187
00188 d->plugin_module_map[p] = module;
00189 d->name_plugin_map[pn] = p;
00190 d->plugin_name_map[p] = pn;
00191
00192 return p;
00193 } catch (PluginLoadException &e) {
00194 throw;
00195 }
00196 }
00197
00198
00199
00200
00201
00202
00203
00204 std::string
00205 PluginLoader::get_description(const char *plugin_name)
00206 {
00207 Module *module = open_module(plugin_name);
00208
00209 if ( ! module->has_symbol("plugin_description") ) {
00210 throw PluginLoadException(plugin_name, "Symbol 'plugin_description' not found. Forgot PLUGIN_DESCRIPTION?");
00211 }
00212
00213 PluginDescriptionFunc pdf = (PluginDescriptionFunc)module->get_symbol("plugin_description");
00214 std::string rv = pdf();
00215 d->mm->close_module(module);
00216
00217 return rv;
00218 }
00219
00220
00221
00222
00223
00224
00225 bool
00226 PluginLoader::is_loaded(const char *plugin_name)
00227 {
00228 return ( d->name_plugin_map.find(plugin_name) != d->name_plugin_map.end() );
00229 }
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243 void
00244 PluginLoader::unload(Plugin *plugin)
00245 {
00246 if ( d->plugin_module_map.find(plugin) != d->plugin_module_map.end() ) {
00247
00248 PluginDestroyFunc pdf = (PluginDestroyFunc)d->plugin_module_map[plugin]->get_symbol("plugin_destroy");
00249 if ( pdf != NULL ) {
00250 pdf(plugin);
00251 }
00252 d->mm->close_module(d->plugin_module_map[plugin]);
00253 d->plugin_module_map.erase(plugin);
00254
00255 d->name_plugin_map.erase(d->plugin_name_map[plugin]);
00256 d->plugin_name_map.erase(plugin);
00257 }
00258 }
00259
00260 }