Show plugin_manager.h syntax highlighted
#ifndef __GEN_PROG_PLUGIN_PLUGIN_MANAGER_H__
#define __GEN_PROG_PLUGIN_PLUGIN_MANAGER_H__ 1
// ** standart include
#include <vector>
#include <string>
#include <list>
#include <map>
#include <iostream>
// ** logger include
#include <osg/Notify>
// ** thread include
#include <boost/thread/recursive_mutex.hpp>
// ** filesystem include
#include <boost/filesystem/path.hpp>
#include <boost/filesystem/operations.hpp>
// ** meta-programming include
#include <boost/type_traits/is_same.hpp>
#include <boost/preprocessor/if.hpp>
// ** plugin include
#include <gen_prog/plugin/detail/tracker.h>
#include <gen_prog/plugin/dynamic_library_manager.h>
#include <gen_prog/plugin/detail/singleton.h>
namespace gen_prog
{
namespace plugin
{
template < typename PM >
class plugin_manager_traits
{
public:
//typedef typename PM::self_type self_type;
//
typedef typename PM::registry_type registry_type;
typedef typename PM::dynamic_library_manager_type dynamic_library_manager_type;
typedef typename PM::module_identifier_type module_identifier_type;
typedef typename PM::dynamic_library_identifier_type dynamic_library_identifier_type;
typedef typename PM::plugin_type plugin_type;
typedef typename PM::plugin_key_type plugin_key_type;
typedef typename PM::plugin_key_list plugin_key_list;
typedef typename PM::module_type module_type;
typedef typename PM::module_path_type module_path_type;
typedef typename PM::module_path_list module_path_list;
typedef typename PM::module_key_type module_key_type;
typedef typename PM::module_key_list module_key_list;
typedef typename PM::scoped_lock_type scoped_lock_type;
};
namespace detail
{
template < typename PM >
class plugin_manager_loader
{
public:
plugin_manager_loader(typename PM::dynamic_library_manager_type * manager)
: _manager(*manager) {}
void operator()(const typename PM::module_path_type & modulePath)
{ _manager.loadPath(modulePath); }
private:
typename PM::dynamic_library_manager_type & _manager;
};
template < typename PM >
struct plugin_manager_key_unloader
{
public:
plugin_manager_key_unloader(typename PM::dynamic_library_manager_type * manager, typename PM::module_identifier_type & identifier)
: _manager(*manager), _identifier(identifier) {}
void operator()(const typename PM::module_key_type & moduleKey)
{ _manager.unloadKey(_identifier.toDynamicLibraryKey(moduleKey)); }
private:
typename PM::dynamic_library_manager_type & _manager;
typename PM::module_identifier_type & _identifier;
};
template < typename PM >
struct plugin_manager_path_unloader
{
public:
plugin_manager_path_unloader(typename PM::dynamic_library_manager_type * manager)
: _manager(*manager) {}
void operator()(const typename PM::module_path_type & modulePath)
{ _manager.unloadPath(modulePath); }
private:
typename PM::dynamic_library_manager_type & _manager;
};
}
/*!
* This class is used to manage Plugins.
* the PluginRegister parameter is the implementation
*/
struct own_dynamic_library_manager_tag {};
struct singleton_dynamic_library_manager_tag {};
template < typename R,
typename I,
//template < typename I > class T, //= detail::path_tracker< detail::dynamic_library_tracker >,
typename DLM = dynamic_library_manager< dynamic_library,
detail::dynamic_library_identifier,
detail::thread_locker< boost::recursive_mutex,
boost::recursive_mutex::scoped_lock > >,
typename accessor_dynamic_library_manager_tag = own_dynamic_library_manager_tag >
class plugin_manager
{
public:
typedef plugin_manager<R, I, DLM, accessor_dynamic_library_manager_tag> self_type;
// typedef R registry_type;
typedef R singleton_registry_type;
// template < typename I > typedef T tracker_template< typename I >;
typedef I plugin_identifier_type;
typedef DLM dynamic_library_manager_type;
typedef typename dynamic_library_manager_type::identifier_type dynamic_library_identifier_type;
// typedef typename tracker_template< identifier_type > tracker_type;
typedef typename detail::module_identifier_helper< plugin_identifier_type,
dynamic_library_identifier_type >
module_identifier_type;
private:
template < typename S, typename T >
class singleton_accessor
{
public:
T * get()
{ return S::instance(); }
};
template < typename T >
class own_accessor
{
public:
own_accessor()
: _instance(new T) {}
T * get()
{ return _instance.get(); }
private:
std::auto_ptr< T > _instance;
};
typedef typename boost::mpl::if_< typename boost::is_same< accessor_dynamic_library_manager_tag,
own_dynamic_library_manager_tag >::type,
own_accessor< dynamic_library_manager_type >,
singleton_accessor< detail::singleton<dynamic_library_manager_type>, dynamic_library_manager_type > >::type dynamic_library_manager_accessor_type;
typedef typename dynamic_library_manager_type::key_type dynamic_library_key_type;
typedef typename dynamic_library_manager_type::key_list dynamic_library_key_list;
typedef typename detail::plugin_manager_loader<self_type > loader_policy;
typedef typename detail::plugin_manager_path_unloader<self_type > path_unloader_policy;
typedef typename detail::plugin_manager_key_unloader<self_type > key_unloader_policy;
public:
typedef typename dynamic_library_manager_type::scoped_lock_type scoped_lock_type;
typedef typename dynamic_library_manager_type::mutex_type mutex_type;
typedef typename singleton_registry_type::plugin_type plugin_type;
typedef typename singleton_registry_type::plugin_instance_type plugin_instance_type;
typedef typename singleton_registry_type::key_type plugin_key_type;
typedef typename singleton_registry_type::key_list plugin_key_list;
typedef typename dynamic_library_manager_type::dynamic_library_type module_type;
typedef typename module_identifier_type::path_type module_path_type;
typedef typename module_identifier_type::path_list module_path_list;
typedef typename module_identifier_type::module_key_type module_key_type;
typedef typename std::vector< module_key_type > module_key_list;
plugin_manager()
{
// ** force instanciation of the singleton
singleton_registry_type::instance();
_dlManager.get();
}
////////////////////////////
// ** Module interface ** //
////////////////////////////
// ** Manipulator
//! Load a module from a path.
bool loadModulePath(const module_path_type & modulePath)
{
scoped_lock_type lock(_dlManager.get()->toMutex());
return (_dlManager.get()->loadPath(modulePath));
}
//! Load a module list from a path list.
void loadModulePathList(const module_path_list & modulePathList)
{
scoped_lock_type lock(_dlManager.get()->toMutex());
std::for_each(modulePathList.begin(), modulePathList.end(), loader_policy(_dlManager.get()));
}
//! Load a module from a key.
bool loadModuleKey(const module_key_type & moduleKey)
{
scoped_lock_type lock(_dlManager.get()->toMutex());
module_path_list modulePathList;
getAvailableModulePathListForKey(modulePathList, moduleKey);
return ((modulePathList.empty() == false) ? (loadModulePath(modulePathList.front())) : (false));
}
//! Load a module list from a key list.
void loadModuleKeyList(const module_key_list & moduleKeyList)
{
scoped_lock_type lock(_dlManager.get()->toMutex());
module_path_list tmpPathList, modulePathList;
for (typename module_key_list::iterator it = moduleKeyList.begin(); it = moduleKeyList.end(); ++it)
{
getAvailableModulePathListForKey(tmpPathList, *it);
if (tmpPathList.empty() == false)
modulePathList.push_back(tmpPathList.front());
}
std::for_each(modulePathList.begin(), modulePathList.end(), loader_policy(_dlManager.get()));
}
//! Load all available module
void loadAllModule()
{
scoped_lock_type lock(_dlManager.get()->toMutex());
module_path_list modulePathList;
_identifier.getAvailablePath(modulePathList);
std::for_each(modulePathList.begin(), modulePathList.end(), loader_policy(_dlManager.get()));
}
//! Unload a module from a path.
bool unloadModulePath(const module_path_type & modulePath)
{
scoped_lock_type lock(_dlManager.get()->toMutex());
return (_dlManager.get()->unloadPath(modulePath));
}
//! Unload a module list from a key list.
void unloadModulePathList(const module_path_list & modulePathList)
{
scoped_lock_type lock(_dlManager.get()->toMutex());
std::for_each(modulePathList.begin(), modulePathList.end(), path_unloader_policy(_dlManager.get()));
}
//! Unload a module from a key.
bool unloadModuleKey(const module_key_type & moduleKey)
{
scoped_lock_type lock(_dlManager.get()->toMutex());
return (_dlManager.get()->unload(moduleKey));
}
//! Unload a module list from a key list.
void unloadModuleKeyList(const module_key_list & moduleKeyList)
{
scoped_lock_type lock(_dlManager.get()->toMutex());
std::for_each(moduleKeyList.begin(), moduleKeyList.end(), key_unloader_policy(_dlManager.get(), _identifier));
}
//! Unload all module.
void unloadAllModule()
{
// ** optimize for own and singleton dynamic library manager (with a dispatch method ??)
scoped_lock_type lock(_dlManager.get()->toMutex());
module_key_list moduleKeyList;
getLoadedModuleList(moduleKeyList);
unloadModuleKeyList(moduleKeyList);
}
//! return an instance of the module.
module_type * getModule(const module_key_type & moduleKey)
{
return (_dlManager.get()->get(_identifier.toDynamicLibraryKey(moduleKey)));
}
// ** Accessor
//! return the module path for the module key. the module must be loaded
module_path_type moduleKeyToPath(const module_key_type & moduleKey) const
{ return (_dlManager.get()->keyToPath(_identifier.toDynamicLibraryKey(moduleKey))); }
//! return the module key for the module path
module_key_type modulePathToKey(const module_path_type & modulePath) const
{ return (_identifier.toModuleKey(_dlManager.get()->pathToKey(modulePath))); }
//! return true if the module identified by the path give in parameter is loaded, false otherwise.
bool isLoadedModulePath(const module_path_type & modulePath) const
{
return (_dlManager.get()->isLoadedPath(modulePath));
}
//! return true if the module identified by the key give in parameter is loaded, false otherwise.
bool isLoadedModuleKey(const module_key_type & moduleKey) const
{
return (_dlManager.get()->isLoadedKey(_identifier.toDynamicLibraryKey(moduleKey)));
}
//! fill the module key list give in parameter with the module actually loaded.
void getLoadedModuleList(module_key_list & moduleKeyList) const
{
scoped_lock_type lock(_dlManager.get()->toMutex());
dynamic_library_key_list dlKeyList;
_dlManager.get()->getLoadedKeyList(dlKeyList);
for (typename dynamic_library_key_list::iterator it = dlKeyList.begin(); it != dlKeyList.end(); ++it)
{
if (_identifier.isValidModuleKey(*it))
moduleKeyList.push_back(_identifier.toModuleKey(*it));
}
}
//! fill the modulePathList give in parameter with module available on the system.
void getAvailableModulePathList(module_path_list & modulePathList) const
{
_identifier.getAvailablePath(modulePathList);
}
//! fill the modulePathList give in parameter with module available on the system.
void getAvailableModulePathListForKey(module_path_list & modulePathList, const module_key_type & moduleKey) const
{
module_path_list tmpList;
_identifier.getAvailablePath(tmpList);
for (typename module_path_list::iterator it = tmpList.begin(); it != tmpList.end(); ++it)
if (modulePathToKey(*it) == moduleKey)
modulePathList.push_back(*it);
}
// //! fill the moduleKeyList give in parameter with module available on the system.
// void getAvailableModuleKeyList(module_key_list & moduleKeyList) const
// {
// _tracker.getAvailableKey(moduleKeyList);
// }
////////////////////////////
// ** Plugin interface ** //
////////////////////////////
//! fill the pluginKeyList give in parameter with the plugin available on the system.
void getAvailablePluginKeyList(plugin_key_list & pluginKeyList) const
{
singleton_registry_type::instance()->getAvailable(pluginKeyList);
}
//! return an instance of the plugin.
plugin_type * getPlugin(const plugin_key_type & pluginKey)
{
return (singleton_registry_type::instance()->get(pluginKey));
}
//! return an instance of the plugin.
plugin_instance_type * getPluginInstance(const plugin_key_type & pluginKey)
{
plugin_type * plugin_ = singleton_registry_type::instance()->get(pluginKey);
return ((plugin_ != NULL) ? (plugin_->getNewInstance()) : (NULL));
}
private:
module_identifier_type _identifier;
mutable dynamic_library_manager_accessor_type _dlManager;
};
}
}
#endif // ** __GEN_PROG_PLUGIN_PLUGIN_MANAGER_H__ ** //
See more files for this project here