LCOV - code coverage report
Current view: top level - lunchbox - pluginFactory.ipp (source / functions) Hit Total Coverage
Test: Lunchbox Lines: 16 17 94.1 %
Date: 2015-07-07 14:54:45 Functions: 8 8 100.0 %

          Line data    Source code
       1             : 
       2             : /* Copyright (c) 2013-2015, EPFL/Blue Brain Project
       3             :  *                          Raphael Dumusc <raphael.dumusc@epfl.ch>
       4             :  *                          Stefan.Eilemann@epfl.ch
       5             :  *
       6             :  * This file is part of Lunchbox <https://github.com/Eyescale/Lunchbox>
       7             :  *
       8             :  * This library is free software; you can redistribute it and/or modify it under
       9             :  * the terms of the GNU Lesser General Public License version 2.1 as published
      10             :  * by the Free Software Foundation.
      11             :  *
      12             :  * This library is distributed in the hope that it will be useful, but WITHOUT
      13             :  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
      14             :  * FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
      15             :  * details.
      16             :  *
      17             :  * You should have received a copy of the GNU Lesser General Public License
      18             :  * along with this library; if not, write to the Free Software Foundation, Inc.,
      19             :  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
      20             :  */
      21             : 
      22             : namespace lunchbox
      23             : {
      24             : template< typename PluginT, typename InitDataT >
      25             : PluginFactory< PluginT, InitDataT >&
      26          24 : PluginFactory< PluginT, InitDataT >::getInstance()
      27             : {
      28          24 :     static PluginFactory< PluginT, InitDataT > factory;
      29          24 :     return factory;
      30             : }
      31             : 
      32             : template< typename PluginT, typename InitDataT >
      33           8 : PluginT* PluginFactory< PluginT, InitDataT >::create( const InitDataT& initData )
      34             : {
      35          12 :     BOOST_FOREACH( PluginHolder& plugin, _plugins )
      36           8 :         if( plugin.handles( initData ))
      37           8 :             return plugin.constructor( initData );
      38             : 
      39           4 :     LBTHROW( std::runtime_error( "No plugin implementation available for " +
      40             :                                  boost::lexical_cast<std::string>( initData )));
      41             : }
      42             : 
      43             : template< typename PluginT, typename InitDataT >
      44           8 : void PluginFactory< PluginT, InitDataT >::register_(
      45             :     const Plugin< PluginT, InitDataT >& plugin )
      46             : {
      47           8 :     _plugins.push_back( plugin );
      48           8 : }
      49             : 
      50             : template< typename PluginT, typename InitDataT >
      51             : bool PluginFactory< PluginT, InitDataT >::deregister(
      52             :     const Plugin< PluginT, InitDataT >& plugin )
      53             : {
      54             :     typename Plugins::iterator i =
      55             :         std::find( _plugins.begin(), _plugins.end(), plugin );
      56             :     if( i == _plugins.end( ))
      57             :         return false;
      58             : 
      59             :     _plugins.erase( i );
      60             :     return true;
      61             : }
      62             : 
      63             : template< typename PluginT, typename InitDataT >
      64           8 : void PluginFactory< PluginT, InitDataT >::deregisterAll()
      65             : {
      66           8 :     _plugins.clear();
      67           8 :     BOOST_FOREACH( typename PluginMap::value_type& plugin, _libraries )
      68           0 :         delete plugin.first;
      69           8 :     _libraries.clear();
      70           8 : }
      71             : 
      72             : template< typename PluginT, typename InitDataT >
      73             : DSOs PluginFactory< PluginT, InitDataT >::load( const int version,
      74             :                                                 const Strings& paths,
      75             :                                                 const std::string& pattern )
      76             : {
      77             :     Strings unique = paths;
      78             :     lunchbox::usort( unique );
      79             : 
      80             :     DSOs result;
      81             :     BOOST_FOREACH( const std::string& path, unique )
      82             :         _load( result, version, path, pattern );
      83             :     return result;
      84             : }
      85             : 
      86             : template< typename PluginT, typename InitDataT >
      87             : DSOs PluginFactory< PluginT, InitDataT >::load( const int version,
      88             :                                                 const std::string& path,
      89             :                                                 const std::string& pattern )
      90             : {
      91             :     DSOs loaded;
      92             :     _load( loaded, version, path, pattern );
      93             :     return loaded;
      94             : }
      95             : 
      96             : template< typename PluginT, typename InitDataT >
      97             : void PluginFactory< PluginT, InitDataT >::_load( DSOs& result,
      98             :                                                  const int version,
      99             :                                                  const std::string& path,
     100             :                                                  const std::string& pattern )
     101             : {
     102             : #ifdef _MSC_VER
     103             :     const std::string regex( pattern + ".dll" );
     104             : #elif __APPLE__
     105             :     const std::string regex( "lib" + pattern + ".dylib" );
     106             : #else
     107             :     const std::string regex( "lib" + pattern + ".so" );
     108             : #endif
     109             :     const Strings& libs = searchDirectory( path, regex );
     110             : 
     111             :     BOOST_FOREACH( const std::string& lib, libs )
     112             :     {
     113             :         lunchbox::DSO* dso = new lunchbox::DSO( path + "/" + lib );
     114             :         if( !dso->isOpen())
     115             :         {
     116             :             delete dso;
     117             :             continue;
     118             :         }
     119             : 
     120             :         typedef int( *GetVersion_t )();
     121             :         typedef bool( *Register_t )();
     122             : 
     123             :         GetVersion_t getVersion = dso->getFunctionPointer< GetVersion_t >(
     124             :             "LunchboxPluginGetVersion" );
     125             :         Register_t registerFunc = dso->getFunctionPointer< Register_t >(
     126             :             "LunchboxPluginRegister" );
     127             :         const bool matchesVersion = getVersion && (getVersion() == version);
     128             : 
     129             :         if( !getVersion || !registerFunc || !matchesVersion )
     130             :         {
     131             :             LBERROR << "Disable " << lib << ": "
     132             :                     << ( getVersion ? "" :
     133             :                         "Symbol for LunchboxPluginGetVersion missing " )
     134             :                     << ( registerFunc ? "" :
     135             :                         "Symbol for LunchboxPluginRegister missing " );
     136             :             if( getVersion && !matchesVersion )
     137             :                 LBERROR << "Plugin version " << getVersion() << " does not"
     138             :                         << " match application version " << version;
     139             :             LBERROR << std::endl;
     140             : 
     141             :             delete dso;
     142             :             continue;
     143             :         }
     144             : 
     145             :         if( registerFunc( ))
     146             :         {
     147             :             _libraries.insert( std::make_pair( dso, _plugins.back( )));
     148             :             result.push_back( dso );
     149             :             LBINFO << "Enabled plugin " << lib << std::endl;
     150             :         }
     151             :         else
     152             :             delete dso;
     153             :     }
     154             : }
     155             : 
     156             : template< typename PluginT, typename InitDataT >
     157             : bool PluginFactory< PluginT, InitDataT >::unload( DSO* dso )
     158             : {
     159             :     typename PluginMap::iterator i = _libraries.find( dso );
     160             :     if( i == _libraries.end( ))
     161             :         return false;
     162             : 
     163             :     delete i->first;
     164             :     const bool ret = deregister( i->second );
     165             :     _libraries.erase( i );
     166             :     return ret;
     167             : }
     168             : }

Generated by: LCOV version 1.11