PCMPluginManager.cpp

Go to the documentation of this file.
00001 
00002 //
00003 // This source file is a part of ParCompMark
00004 // Parallel Compositing Benchmark Framework
00005 //
00006 // for latest info see http://parcompmark.sourceforge.net
00007 
00008 //
00009 // Copyright (C) 2006 IT2 ParCompMark Dev. Team
00010 // 
00011 // This program is free software; you can redistribute it and/or
00012 // modify it under the terms of the GNU General Public License
00013 // as published by the Free Software Foundation; either version 2
00014 // of the License, or (at your option) any later version.
00015 // 
00016 // This program is distributed in the hope that it will be useful,
00017 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00018 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00019 // GNU General Public License for more details.
00020 // 
00021 // You should have received a copy of the GNU General Public License
00022 // along with this program; if not, write to the Free Software
00023 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
00024 
00025 //
00026 // Inner includes
00027 //
00028 
00029 #include "../include/PCMPluginManager.h"
00030 
00031 #include "../include/PCMFileSystemManager.h"
00032 
00033 #include "../include/PCMStringConverter.h"
00034 
00035 #include "../include/PCMRendererPlugin.h"
00036 
00037 //
00038 // Outer includes
00039 //
00040 
00041 #include <iostream>
00042 #include <fstream>
00043 
00044 namespace ParCompMark
00045 {
00046 
00047   // Inherited static attribute initialization
00048   template <> PluginManager * Singleton < PluginManager >::mInstance = 0;
00049 
00050   //
00051   // Constructors & destructor
00052   //
00053 
00054   PluginManager::PluginManager(const std::string & pluginDirectory, const std::string & iniFile)
00055         // You have to initialize the following attributes:
00056         // - mPlugins
00057         // - mPluginDirectory
00058         // - mPluginIniFile
00059         // - mInitialized
00060   {
00061         mPlugins = new Container < Plugin, Mutex > ();
00062         mPluginDirectory = pluginDirectory;
00063         mPluginIniFile = iniFile;
00064         mInitialized = false;
00065 
00066         Logger::getInstance()->log(Logger::NOTICE, "Plugin manager has been created.");
00067   }
00068 
00069  /*----------------------------------------------------------------------*/
00070 
00071   PluginManager::~PluginManager()
00072   {
00073         if(mInitialized)
00074          finalize();
00075 
00076         Logger::getInstance()->log(Logger::NOTICE, "Plugin manager has been destroyed.");
00077   }
00078 
00079  /*----------------------------------------------------------------------*/
00080 
00081   //
00082   // Methods
00083   //
00084 
00085   void PluginManager::initialize()
00086   {
00087         Assert(!mInitialized, INVALID_OPERATION_ERROR, "PluginManager::initialize()");
00088 
00089         loadPlugins();
00090 
00091         mInitialized = true;
00092 
00093         Logger::getInstance()->log(Logger::DEBUG, "Plugin manager has been initialized.");
00094   }
00095 
00096  /*----------------------------------------------------------------------*/
00097 
00098   void PluginManager::finalize()
00099   {
00100         Assert(mInitialized, INVALID_OPERATION_ERROR, "PluginManager::finalize()");
00101 
00102         unloadPlugins();
00103 
00104         mInitialized = false;
00105 
00106         Logger::getInstance()->log(Logger::DEBUG, "Plugin manager has been finalized.");
00107   }
00108 
00109  /*----------------------------------------------------------------------*/
00110 
00111   void PluginManager::loadPlugins()
00112   {
00113         // Load renderer plugins
00114         std::list < std::string > plugins = FileSystemManager::getInstance()->listDataDirectory("plugins/renderers/");
00115         for(std::list < std::string >::iterator plugini = plugins.begin(); plugini != plugins.end(); plugini++)
00116         {
00117          if(plugini->find(".so") == std::string::npos)
00118                 continue;
00119 
00120          // Load plugin
00121          Plugin::Pointer plugin(_loadPlugin(Plugin::RENDERER_PLUGIN, *plugini));
00122 
00123          // Check libraries for the plugin
00124          _checkNeededLibs(plugin);
00125 
00126          // Initialize the plugin
00127          plugin->initialize();
00128         }
00129 
00130         Logger::getInstance()->log(Logger::NOTICE, "All plugins has been loaded.");
00131   }
00132 
00133  /*----------------------------------------------------------------------*/
00134 
00135   void PluginManager::loadPlugins_old()
00136   {
00137         FileSystemManager::CppFilePointer fp(FileSystemManager::getInstance()->
00138                                           openDataFileCpp(mPluginDirectory + mPluginIniFile,
00139                                                           FileSystemManager::READ));
00140 
00141         const u32 lineBufSize = 1024;
00142         char lineBuf[lineBufSize];
00143 
00144         std::string line = "";
00145 
00146         while(!fp->eof())
00147         {
00148          // Read line, trim, and test comment
00149          fp->getline(lineBuf, lineBufSize);
00150 
00151          line = lineBuf;
00152          StringConverter::trim(line);
00153          if(!line.length() || line[0] == '#')
00154                 continue;
00155 
00156          // Plugin name and option
00157          std::string filename;
00158          std::string option;
00159 
00160          // Look for option
00161          if(line.find('[') != std::string::npos)
00162          {
00163                 filename = line.substr(0, line.find('['));
00164                 StringConverter::trim(filename);
00165 
00166                 option = line.substr(line.find('[')).substr(0, line.find(']'));
00167                 StringConverter::trim(option);
00168          }
00169 
00170          else
00171                 filename = line;
00172 
00173          // Test filename
00174          Assert(filename.length(), INVALID_NAME_ERROR, "PluginManager::loadPlugins()");
00175 
00176          // Convert option string to plugin type
00177          Plugin::PluginType pluginType = Plugin::BASIC_PLUGIN;
00178          if(option == "[renderer]")
00179                 pluginType = Plugin::RENDERER_PLUGIN;
00180          else if(option.length())
00181                 Except(INVALID_ENUM_ERROR, "PluginManager::loadPlugins()",
00182                    "Unknown option `" + option + "\' for plugin `" + filename + "\'");
00183 
00184          // Load plugin
00185          Plugin::Pointer plugin(_loadPlugin(pluginType, filename));
00186 
00187          // Check libraries for the plugin
00188          _checkNeededLibs(plugin);
00189 
00190          // Initialize the plugin
00191          plugin->initialize();
00192         }
00193 
00194         FileSystemManager::getInstance()->closeFile(fp);
00195 
00196         Logger::getInstance()->log(Logger::NOTICE, "All plugins has been loaded.");
00197   }
00198 
00199  /*----------------------------------------------------------------------*/
00200 
00201   void PluginManager::unloadPlugins()
00202   {
00203         mPlugins.kill();
00204 
00205         Logger::getInstance()->log(Logger::NOTICE, "All plugins has been unloaded.");
00206   }
00207 
00208  /*----------------------------------------------------------------------*/
00209 
00210   Plugin::Pointer PluginManager::getPlugin(const std::string & name)
00211   {
00212         Assert(mInitialized, INVALID_OPERATION_ERROR, "PluginManager::getPlugin()");
00213 
00214         mPlugins.lock();
00215         Plugin::Pointer plugin = mPlugins->get(name);
00216         mPlugins.unlock();
00217 
00218         return plugin;
00219   }
00220 
00221  /*----------------------------------------------------------------------*/
00222 
00223   Plugin::Pointer PluginManager::_loadPlugin(const Plugin::PluginType & type,
00224                                            const std::string & filename)
00225   {
00226         std::string name = filename.substr(filename.rfind('/') + 1);
00227         //std::string _filename = FileSystemManager::getInstance()->getPathDataFile(mPluginDirectory + filename);
00228         std::string _filename = FileSystemManager::getInstance()->getPathDataFile(filename);
00229 
00230         Plugin::Pointer plugin;
00231 
00232         switch (type)
00233         {
00234          case Plugin::RENDERER_PLUGIN:
00235                 plugin = new RendererPlugin(type, name, _filename);
00236                 break;
00237          default:
00238                 Except(INVALID_ENUM_ERROR, "PluginManager::_loadPlugin()",
00239                    "Cannot create instance from basic plugin `" + filename + "\'.");
00240         }
00241 
00242         mPlugins.lock();
00243         mPlugins->add(name, plugin);
00244         mPlugins.unlock();
00245 
00246         Logger::getInstance()->log(Logger::DEBUG, "Plugin `" + filename + "\' has been loaded.");
00247 
00248         return plugin;
00249   }
00250 
00251  /*----------------------------------------------------------------------*/
00252 
00253   void PluginManager::_checkNeededLibs(Plugin::Pointer & plugin)
00254   {
00255         // TODO: implement
00256 
00257         Logger::getInstance()->log(Logger::DEBUG,
00258                                  "Every library needed by plugin `" + plugin->getName() +
00259                                  "\' is linked to parcompmark.");
00260   }
00261 
00262  /*----------------------------------------------------------------------*/
00263 
00264 }