/* * ModuleManager.cpp * * Copyright (C) 2008 Matthias Schiffer * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program. If not, see . */ #include #include "ModuleManager.h" #include "Application.h" #include #include //extern const lt_dlsymlist lt_preloaded_symbols[]; namespace Mad { namespace Common { /*int ModuleManager::preopenCallback(lt_dlhandle handle) { moduleManager.modules.insert(std::make_pair(lt_dlgetinfo(handle)->name, std::make_pair(handle, false))); return 0; }*/ ModuleManager::ModuleManager(Application *application0) : application(application0) { lt_dlinit(); //lt_dlpreload_default(lt_preloaded_symbols); //lt_dlpreload(0); //lt_dlpreload_open("@PROGRAM@", &ModuleManager::preopenCallback); application->getConfigManager()->registerConfigurable(this); } ModuleManager::~ModuleManager() { application->getConfigManager()->unregisterConfigurable(this); while(!moduleOrder.empty()) { unloadModule(moduleOrder.top()); moduleOrder.pop(); } lt_dlexit(); } bool ModuleManager::handleConfigEntry(const Core::ConfigEntry &entry, bool handled) { if(handled) return false; if(entry[0].getKey().matches("LoadModule")) { if(!loadModule(entry[0][0].c_str())) application->logf(Core::LoggerBase::ERROR, "Can't load module '%s'.", entry[0][0].c_str()); return true; } return false; } lt_dlhandle ModuleManager::loadModule(const std::string &name) { std::map >::iterator mod = modules.find(name); if(mod == modules.end()) { lt_dlhandle handle = lt_dlopen((name + MODULE_SUFFIX).c_str()); if(!handle) return 0; mod = modules.insert(std::make_pair(lt_dlgetinfo(handle)->name, std::make_pair(handle, (Module*)0))).first; } if(!mod->second.second) { ModuleLoadFunc loader = (ModuleLoadFunc)lt_dlsym(mod->second.first, (name + "_create").c_str()); if(!loader) return 0; mod->second.second = loader(application); if(mod->second.second) moduleOrder.push(name); } return mod->second.first; } void ModuleManager::unloadModule(const std::string &name) { delete modules[name].second; lt_dlclose(modules[name].first); modules.erase(name); } } }