Lunchbox  1.13.0
Multi-threaded C++ toolbox library for all application developers creating high-performance multi-threaded programs.
lunchbox::PluginFactory< PluginT, InitDataT > Class Template Reference

Factory for Plugin classes. More...

#include <pluginFactory.h>

+ Inheritance diagram for lunchbox::PluginFactory< PluginT, InitDataT >:
+ Collaboration diagram for lunchbox::PluginFactory< PluginT, InitDataT >:

Public Types

typedef Plugin< PluginT, InitDataT > PluginHolder
 
typedef std::vector< PluginHolderPlugins
 

Public Member Functions

PluginT * create (const InitDataT &initData)
 Create a plugin instance. More...
 
void register_ (const Plugin< PluginT, InitDataT > &plugin)
 Register a plugin type. More...
 
bool deregister (const Plugin< PluginT, InitDataT > &plugin)
 Deregister a plugin type. More...
 
void deregisterAll ()
 Unregister all plugin types. More...
 
Automatic loading of plugin DSOs.
DSOs load (const int version, const std::string &path, const std::string &pattern)
 Load all compatible plugin libraries from a directory matching a pattern. More...
 
DSOs load (const int version, const Strings &paths, const std::string &pattern)
 
bool unload (DSO *dso)
 Unload and deregister a previously loaded plugin. More...
 

Static Public Member Functions

static PluginFactorygetInstance ()
 Get the single class instance. More...
 

Detailed Description

template<class PluginT, class InitDataT = servus::URI>
class lunchbox::PluginFactory< PluginT, InitDataT >

Factory for Plugin classes.

The PluginFactory selects the a plugin for a given InitDataT, based on a plugin's handles() function. In case a InitDataT can be handled by multiple plugins, which plugin is chosen is undefined.

This class has been designed as a singleton to allow for link time plugin registration, but nothing prevents an application from registering new types at run time.

To do the registration of a plugin during the static initialization phase use the PluginRegisterer.

Example:

/* Copyright (c) 2013-2015, EPFL/Blue Brain Project
* Raphael Dumusc <raphael.dumusc@epfl.ch>
*
* This file is part of Lunchbox <https://github.com/Eyescale/Lunchbox>
*
* This library is free software; you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License version 2.1 as published
* by the Free Software Foundation.
*
* This library 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 Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#define BOOST_TEST_MODULE PluginFactory
#include <lunchbox/types.h>
#include <lunchbox/pluginFactory.h>
#include <lunchbox/pluginRegisterer.h>
#include <servus/uri.h>
#include <boost/test/unit_test.hpp>
#include <boost/scoped_ptr.hpp>
#define VALID_VALUE 10
#define INVALID_VALUE 0
struct InitData
{
servus::URI uri;
};
namespace boost
{
template<> inline std::string lexical_cast( const InitData& data )
{
return lexical_cast< std::string >( data.uri );
}
}
class PluginInterface
{
public:
typedef PluginInterface PluginT;
virtual ~PluginInterface() {}
virtual int getValue() = 0;
};
class TypedPluginInterface
{
public:
typedef TypedPluginInterface PluginT;
typedef InitData InitDataT;
virtual ~TypedPluginInterface() {}
virtual int getValue() = 0;
};
class MyPlugin : public PluginInterface
{
public:
explicit MyPlugin( const servus::URI& ) {}
static bool handles( const servus::URI& ) { return true; }
int getValue() final { return VALID_VALUE; }
};
class MyTypedPlugin : public TypedPluginInterface
{
public:
explicit MyTypedPlugin( const InitData& ) {}
static bool handles( const InitData& ) { return true; }
int getValue() final { return VALID_VALUE; }
};
class MyDummyPlugin : public PluginInterface
{
public:
explicit MyDummyPlugin( const servus::URI& ) {}
static bool handles( const servus::URI& ) { return false; }
int getValue() final { return INVALID_VALUE; }
};
class MyTypedDummyPlugin : public TypedPluginInterface
{
public:
explicit MyTypedDummyPlugin( const InitData& ) {}
static bool handles( const InitData& ) { return false; }
int getValue() final { return INVALID_VALUE; }
};
typedef lunchbox::PluginFactory< TypedPluginInterface,
InitData > MyTypedPluginFactory;
typedef boost::scoped_ptr< PluginInterface > PluginInterfacePtr;
typedef boost::scoped_ptr< TypedPluginInterface > TypedPluginInterfacePtr;
void tryCreatePlugin( PluginInterfacePtr& plugin )
{
MyPluginFactory& factory = MyPluginFactory::getInstance();
plugin.reset( factory.create( servus::URI( "XYZ" )));
}
void tryCreateTypedPlugin( TypedPluginInterfacePtr& plugin )
{
MyTypedPluginFactory& factory = MyTypedPluginFactory::getInstance();
plugin.reset( factory.create( InitData() ));
}
BOOST_AUTO_TEST_CASE( testWhenNoPluginIsRegisteredCreateThrowsRuntimeError )
{
MyPluginFactory::getInstance().deregisterAll();
PluginInterfacePtr plugin;
BOOST_CHECK_THROW( tryCreatePlugin( plugin ), std::runtime_error );
}
BOOST_AUTO_TEST_CASE( testWhenNoTypedPluginIsRegisteredCreateThrowsRuntimeErr )
{
MyTypedPluginFactory::getInstance().deregisterAll();
TypedPluginInterfacePtr plugin;
BOOST_CHECK_THROW( tryCreateTypedPlugin( plugin ), std::runtime_error );
}
BOOST_AUTO_TEST_CASE( testWhenPluginRegistererIsInstantiatedPluginIsRegistered )
{
MyPluginFactory::getInstance().deregisterAll();
PluginInterfacePtr plugin;
BOOST_REQUIRE_NO_THROW( tryCreatePlugin( plugin ));
BOOST_CHECK_EQUAL( plugin->getValue(), VALID_VALUE );
}
BOOST_AUTO_TEST_CASE(
testWhenTypedPluginRegistererIsInstantiatedPluginIsRegistered )
{
MyTypedPluginFactory::getInstance().deregisterAll();
TypedPluginInterfacePtr plugin;
BOOST_REQUIRE_NO_THROW( tryCreateTypedPlugin( plugin ));
BOOST_CHECK_EQUAL( plugin->getValue(), VALID_VALUE );
}
BOOST_AUTO_TEST_CASE( testWhenPluginsDontHandleURICreateThrowsRuntimeError )
{
MyPluginFactory::getInstance().deregisterAll();
PluginInterfacePtr plugin;
BOOST_CHECK_THROW( tryCreatePlugin( plugin ), std::runtime_error );
}
BOOST_AUTO_TEST_CASE( testWhenTypedPlginsDontHandleURICreateThrowsRuntimeError )
{
MyTypedPluginFactory::getInstance().deregisterAll();
TypedPluginInterfacePtr plugin;
BOOST_CHECK_THROW( tryCreateTypedPlugin( plugin ), std::runtime_error );
}
BOOST_AUTO_TEST_CASE( testWhenOnePluginHandlesURICreateInstanciesCorrectType )
{
MyPluginFactory::getInstance().deregisterAll();
PluginInterfacePtr plugin;
BOOST_REQUIRE_NO_THROW( tryCreatePlugin( plugin ));
BOOST_CHECK_EQUAL( plugin->getValue(), VALID_VALUE );
}
BOOST_AUTO_TEST_CASE( testWhenOneTypedPluginHandlesURICreateInstCorrectType )
{
MyTypedPluginFactory::getInstance().deregisterAll();
TypedPluginInterfacePtr plugin;
BOOST_REQUIRE_NO_THROW( tryCreateTypedPlugin( plugin ));
BOOST_CHECK_EQUAL( plugin->getValue(), VALID_VALUE );
}
Version
1.11.0

Definition at line 59 of file pluginFactory.h.

Member Function Documentation

template<typename PluginT , typename InitDataT >
PluginT * lunchbox::PluginFactory< PluginT, InitDataT >::create ( const InitDataT &  initData)

Create a plugin instance.

Parameters
initDataThe initData passed to the plugin constructor.
Returns
A new PluginT instance. The user is responsible for deleting the returned object.
Exceptions
std::runtime_errorif no plugin can handle the initData.
Version
1.11.0

Definition at line 43 of file pluginFactory.ipp.

References LBTHROW.

template<typename PluginT , typename InitDataT >
bool lunchbox::PluginFactory< PluginT, InitDataT >::deregister ( const Plugin< PluginT, InitDataT > &  plugin)

Deregister a plugin type.

Version
1.11.0

Definition at line 61 of file pluginFactory.ipp.

template<typename PluginT , typename InitDataT >
void lunchbox::PluginFactory< PluginT, InitDataT >::deregisterAll ( )

Unregister all plugin types.

Version
1.11.0

Definition at line 74 of file pluginFactory.ipp.

template<typename PluginT , typename InitDataT >
PluginFactory< PluginT, InitDataT > & lunchbox::PluginFactory< PluginT, InitDataT >::getInstance ( )
static

Get the single class instance.

Version
1.11.0

Definition at line 26 of file pluginFactory.ipp.

Referenced by lunchbox::PluginRegisterer< Impl, false >::PluginRegisterer().

+ Here is the caller graph for this function:

template<typename PluginT , typename InitDataT >
DSOs lunchbox::PluginFactory< PluginT, InitDataT >::load ( const int  version,
const std::string &  path,
const std::string &  pattern 
)

Load all compatible plugin libraries from a directory matching a pattern.

The pattern is the core name of the library, and is extended by the system-specific shared library suffix and postfix. The plugin has to implement the C functions 'int LunchboxPluginGetVersion()' and 'bool LunchboxPluginRegister()'. Only plugins with the same ABI version as the given one are registered.

Parameters
versionthe current ABI version of the application loading the plugins.
paththe directory to search for plugins.
patternthe core pattern of plugin names.
Returns
the loaded plugins, ownership remains with the PluginFactory.
Version
1.11.0
See also
getLibraryPath()

Definition at line 97 of file pluginFactory.ipp.

template<typename PluginT , typename InitDataT >
void lunchbox::PluginFactory< PluginT, InitDataT >::register_ ( const Plugin< PluginT, InitDataT > &  plugin)

Register a plugin type.

Version
1.11.0

Definition at line 54 of file pluginFactory.ipp.

template<typename PluginT , typename InitDataT >
bool lunchbox::PluginFactory< PluginT, InitDataT >::unload ( DSO dso)

Unload and deregister a previously loaded plugin.

Returns
true if the plugin was loaded, false on error.
Version
1.11.0

Definition at line 167 of file pluginFactory.ipp.


The documentation for this class was generated from the following files: