Fawkes API  Fawkes Development Version
module_manager_template.h
00001 
00002 /***************************************************************************
00003  *  module_manager.h - manager for modules (i.e. shared objects)
00004  *
00005  *  Generated: Wed Aug 23 16:15:02 2006
00006  *  Copyright  2006  Tim Niemueller [www.niemueller.de]
00007  *
00008  ****************************************************************************/
00009 
00010 /*  This program is free software; you can redistribute it and/or modify
00011  *  it under the terms of the GNU General Public License as published by
00012  *  the Free Software Foundation; either version 2 of the License, or
00013  *  (at your option) any later version. A runtime exception applies to
00014  *  this software (see LICENSE.GPL_WRE file mentioned below for details).
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 Library General Public License for more details.
00020  *
00021  *  Read the full text in the LICENSE.GPL_WRE file in the doc directory.
00022  */
00023 
00024 #ifndef __UTILS_SYSTEM_DYNAMIC_MODULE_MODULE_MANAGER_TEMPLATE_H_
00025 #define __UTILS_SYSTEM_DYNAMIC_MODULE_MODULE_MANAGER_TEMPLATE_H_
00026 
00027 #include <core/threading/mutex.h>
00028 #include <core/threading/mutex_locker.h>
00029 #include <utils/system/dynamic_module/module.h>
00030 #include <utils/system/dynamic_module/module_manager.h>
00031 #include <map>
00032 #include <string>
00033 
00034 namespace fawkes {
00035 
00036 /** Manager to load and unload modules, keeps track of loaded modules and
00037  * does not reload modules if they are already loaded
00038  * This implementation is a simple template that takes the Module
00039  * implementation class name as its template parameter
00040  */
00041 template <class MODULE_CLASS>
00042 class ModuleManagerTemplate : public ModuleManager {
00043 
00044  public:
00045 
00046   /** Constructor of NetworkManagerTemplate
00047    * @param module_base_dir The module basedir where to look for plugins
00048    */
00049   ModuleManagerTemplate(const char *module_base_dir = "")
00050   {
00051     modules.clear();
00052     this->module_base_dir = module_base_dir;
00053     mutex = new Mutex();
00054   }
00055 
00056   /** Destructor. */
00057   ~ModuleManagerTemplate()
00058   {
00059     for (typename std::map<std::string, MODULE_CLASS * >::iterator i = modules.begin(); i != modules.end(); ++i) {
00060       delete (*i).second;
00061     }
00062     modules.clear();
00063     delete mutex;
00064   }
00065 
00066   MODULE_CLASS *  open_module(const char *filename)
00067   {
00068     mutex->lock();
00069     if ( modules.find(filename) != modules.end() ) {
00070       modules[filename]->ref();
00071       mutex->unlock();
00072       return modules[filename];
00073     } else {
00074       MODULE_CLASS *module = new MODULE_CLASS(std::string(module_base_dir) + "/" + filename);
00075       try {
00076         module->open();
00077         // ref count of module is now 1
00078         modules[module->get_base_filename()] = module;
00079         mutex->unlock();
00080         return module;
00081       } catch (ModuleOpenException &e) {
00082         delete module;
00083         mutex->unlock();
00084         throw;
00085       }
00086     }
00087     mutex->unlock();
00088   }
00089 
00090   void close_module(Module *module)
00091   {
00092     close_module(module->get_base_filename().c_str());
00093   }
00094 
00095   void close_module(const char *filename)
00096   {
00097     mutex->lock();
00098     if ( modules.find(filename) != modules.end() ) {
00099       modules[filename]->unref();
00100       if (modules[filename]->notref()) {
00101         delete modules[filename];
00102         modules.erase( filename );
00103       }
00104     }
00105     mutex->unlock();
00106   }
00107 
00108 
00109   Module *  get_module(const char *filename)
00110   {
00111     MutexLocker lock(mutex);
00112     if ( modules.find(filename) != modules.end() ) {
00113       modules[filename]->ref();
00114       return modules[filename];
00115     } else {
00116       return NULL;
00117     }
00118   }
00119 
00120 
00121   bool module_opened(const char *filename)
00122   {
00123     return ( modules.find(filename) != modules.end() );
00124   }
00125 
00126   
00127   const char *get_module_file_extension()
00128   {
00129     return MODULE_CLASS::get_file_extension();
00130   }
00131 
00132  private:
00133   std::map<std::string, MODULE_CLASS * >            modules;
00134 
00135   const char *module_base_dir;
00136   Mutex *mutex;
00137 
00138 };
00139 
00140 } // end namespace fawkes
00141 
00142 #endif