summaryrefslogtreecommitdiff
path: root/src/ModuleLoader.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/ModuleLoader.hpp')
-rw-r--r--src/ModuleLoader.hpp90
1 files changed, 63 insertions, 27 deletions
diff --git a/src/ModuleLoader.hpp b/src/ModuleLoader.hpp
index 1a89d38..524a0e1 100644
--- a/src/ModuleLoader.hpp
+++ b/src/ModuleLoader.hpp
@@ -14,29 +14,28 @@
#include "TypeList.hpp"
#include "TypeInfo.hpp"
-template< typename Interface >
+template< typename Interface, typename CtorParams = NullType >
struct Module {
void *handle;
- ModuleRegistry<Interface> *registry;
+ ModuleRegistry< Interface, CtorParams > *registry;
};
-template< typename Interface >
-class ModuleLoader {
+template< typename Interface, typename CtorParams = NullType >
+class BaseModuleLoader {
+
+ public:
- typedef typename std::map<std::string, Module< Interface > > mapType;
+ typedef typename std::map<std::string, Module< Interface, CtorParams > > mapType;
- protected:
+ protected:
+
mapType m_modules;
-
+
public:
-
- ModuleLoader<Interface>( )
- {
- }
-
- ModuleLoader<Interface>( const std::vector<std::string> files )
+
+ BaseModuleLoader( const std::vector<std::string> files )
{
- Module<Interface> m;
+ Module< Interface, CtorParams> m;
for( std::vector<string>::const_iterator it = files.begin( ); it != files.end( ); it++ ) {
m.handle = dlopen( it->c_str( ), RTLD_NOW );
@@ -46,7 +45,7 @@ class ModuleLoader {
std::string registryName = "registry_" + demangle( typeid( Interface ) );
- m.registry = static_cast<ModuleRegistry<Interface> *>( dlsym( m.handle, registryName.c_str( ) ) );
+ m.registry = static_cast< ModuleRegistry< Interface, CtorParams > *>( dlsym( m.handle, registryName.c_str( ) ) );
if( !m.registry ) {
dlclose( m.handle );
throw std::runtime_error( "missing module registry" );
@@ -56,7 +55,7 @@ class ModuleLoader {
}
}
- ~ModuleLoader<Interface>( )
+ virtual ~BaseModuleLoader< Interface, CtorParams >( )
{
for( typename mapType::iterator it = m_modules.begin( ); it != m_modules.end( ); it++ ) {
if( (*it).second.handle ) {
@@ -65,11 +64,35 @@ class ModuleLoader {
}
}
}
-
- Interface *create( std::string subclass )
+
+ void destroy( Interface *obj )
{
- typename mapType::const_iterator it = m_modules.find( subclass );
+ std::string clazz = demangle( typeid( *obj ) );
+
+ typename mapType::const_iterator it = m_modules.find( clazz );
if( it == m_modules.end( ) ) {
+ throw std::runtime_error( "calling unknown destructor" );
+ }
+
+ (*it).second.registry->destroy( obj );
+ }
+};
+
+template< typename Interface, typename CtorParams = NullType >
+class ModuleLoader;
+
+template< typename Interface >
+class ModuleLoader< Interface, NullType > : public BaseModuleLoader< Interface, NullType >
+{
+ public:
+
+ ModuleLoader< Interface >( const std::vector<std::string> files )
+ : BaseModuleLoader< Interface >(files ) { }
+
+ Interface *create( std::string subclass )
+ {
+ typename BaseModuleLoader< Interface >::mapType::const_iterator it = BaseModuleLoader< Interface >::m_modules.find( subclass );
+ if( it == BaseModuleLoader< Interface >::m_modules.end( ) ) {
throw std::runtime_error( "calling unknown constructor" );
}
@@ -77,21 +100,34 @@ class ModuleLoader {
std::string clazz = demangle( typeid( *obj ) );
- m_modules.insert( std::make_pair( clazz, (*it).second ) );
+ BaseModuleLoader< Interface >::m_modules.insert( std::make_pair( clazz, (*it).second ) );
return obj;
}
-
- void destroy( Interface *obj )
+};
+
+template< typename Interface, typename P1 >
+class ModuleLoader< Interface, TYPELIST_1( P1 ) > : public BaseModuleLoader< Interface, TYPELIST_1( P1 ) >
+{
+ public:
+
+ ModuleLoader< Interface, TYPELIST_1( P1 ) >( const std::vector<std::string> files )
+ : BaseModuleLoader< Interface, TYPELIST_1( P1 ) >( files ) { }
+
+ Interface *create( std::string subclass, P1 p1 )
{
+ typename BaseModuleLoader< Interface, TYPELIST_1( P1 ) >::mapType::const_iterator it = BaseModuleLoader< Interface, TYPELIST_1( P1 ) >::m_modules.find( subclass );
+ if( it == BaseModuleLoader< Interface, TYPELIST_1( P1 ) >::m_modules.end( ) ) {
+ throw std::runtime_error( "calling unknown constructor" );
+ }
+
+ Interface *obj = (*it).second.registry->create( p1 );
+
std::string clazz = demangle( typeid( *obj ) );
- typename mapType::const_iterator it = m_modules.find( clazz );
- if( it == m_modules.end( ) ) {
- throw std::runtime_error( "calling unknown destructor" );
- }
+ BaseModuleLoader< Interface, TYPELIST_1( P1 ) >::m_modules.insert( std::make_pair( clazz, (*it).second ) );
- (*it).second.registry->destroy( obj );
+ return obj;
}
};