9 #include <framework/core/Module.h>
10 #include <framework/core/ModuleManager.h>
11 #include <framework/utilities/FileSystem.h>
12 #include <framework/logging/Logger.h>
14 #include <boost/filesystem.hpp>
22 #define MAP_FILE_EXTENSION ".b2modmap"
23 #define LIB_FILE_EXTENSION ".so"
36 if (m_registeredProxyMap.count(moduleProxy->
getModuleName()) == 0) {
37 m_registeredProxyMap.insert(make_pair(moduleProxy->
getModuleName(), moduleProxy));
39 B2ERROR(
"There seems to be more than one module called '" << moduleProxy->
getModuleName() <<
40 "'. Since module names are unique, you must rename one of them!");
48 m_moduleSearchPathList.push_back(path);
51 auto fullPath = boost::filesystem::system_complete(boost::filesystem::path(path));
52 boost::filesystem::directory_iterator endIter;
55 map<string, string> moduleNameLibMap;
56 for (boost::filesystem::directory_iterator dirItr(fullPath); dirItr != endIter; ++dirItr) {
58 if (boost::filesystem::is_regular_file(dirItr->status())) {
59 if (boost::filesystem::extension(dirItr->path()) == MAP_FILE_EXTENSION) {
60 fillModuleNameLibMap(moduleNameLibMap, *dirItr);
65 m_moduleNameLibMap.insert(moduleNameLibMap.begin(), moduleNameLibMap.end());
72 return m_moduleSearchPathList;
78 return m_moduleNameLibMap;
84 auto moduleIter = m_registeredProxyMap.find(moduleName);
87 auto error = [&moduleName](
const std::string & text) ->
void {
88 auto exception = ModuleNotCreatedError() << moduleName << text;
89 B2ERROR(exception.what());
94 if (moduleIter == m_registeredProxyMap.end()) {
96 if (sharedLibPath.empty()) {
97 auto libIter = m_moduleNameLibMap.find(moduleName);
98 if (libIter != m_moduleNameLibMap.end()) {
99 sharedLibPath = libIter->second;
101 error(
"The module is not known to the framework!");
106 error(
"Could not load shared library " + sharedLibPath +
", file does not exist!");
109 error(
"Could not load shared library " + sharedLibPath +
".");
112 moduleIter = m_registeredProxyMap.find(moduleName);
113 if (moduleIter == m_registeredProxyMap.end()) {
114 error(
"The shared library " + sharedLibPath +
" does not contain the module!");
120 ModulePtr currModulePtr = moduleIter->second->createModule();
121 m_createdModulesList.push_back(currModulePtr);
122 return currModulePtr;
128 return m_createdModulesList;
136 for (
const ModulePtr& module : modulePathList)
137 if (module->hasProperties(propertyFlags)) tmpModuleList.push_back(module);
139 return tmpModuleList;
144 for (
const auto& m : list) {
145 if (!m->hasProperties(flag))
157 const boost::filesystem::directory_entry& mapPath)
160 string sharedLibPath = boost::filesystem::change_extension(mapPath, LIB_FILE_EXTENSION).string();
162 B2WARNING(
"The shared library file: " << sharedLibPath <<
" doesn't exist, but is required by " << mapPath.path().string());
167 ifstream mapFile(mapPath.path().string().c_str());
171 std::regex expression(
"^REG_MODULE\\((.+)\\)$");
172 std::match_results<std::string::const_iterator> matchResult;
175 while (getline(mapFile, currentLine)) {
178 if (!std::regex_match(currentLine, matchResult, expression)) {
179 B2ERROR(
"Problem parsing map file " << mapPath <<
": Invalid entry in line " << lineNr <<
", skipping remaining file");
183 string moduleName(matchResult[1].first, matchResult[1].second);
185 if (moduleNameLibMap.count(moduleName) == 0) {
186 moduleNameLibMap.insert(make_pair(moduleName, sharedLibPath));
188 B2ERROR(
"There seems to be more than one module called '" << moduleName <<
189 "'. Since module names are unique, you must rename one of them!");
203 m_createdModulesList.clear();
static bool loadLibrary(std::string library, bool fullname=true)
Load a shared library.
static bool isFile(const std::string &filename)
Check if filename points to an existing file.
static bool isDir(const std::string &filename)
Check if filename points to an existing directory.
static bool fileExists(const std::string &filename)
Check if the file with given filename exists.
void registerModuleProxy(ModuleProxyBase *moduleProxy)
Registers a module proxy.
const std::map< std::string, std::string > & getAvailableModules() const
Returns a map of all modules that were found in the module search paths.
const std::list< std::shared_ptr< Module > > & getCreatedModules() const
Returns a reference to the list of created modules.
static std::list< std::shared_ptr< Module > > getModulesByProperties(const std::list< std::shared_ptr< Module > > &modulePathList, unsigned int propertyFlags)
Returns a list of those modules which carry property flags matching the specified ones.
const std::list< std::string > & getModuleSearchPaths() const
Returns a reference to the list of the modules search filepaths.
std::shared_ptr< Module > registerModule(const std::string &moduleName, std::string sharedLibPath="") noexcept(false)
Creates an instance of a module and registers it to the ModuleManager.
static bool allModulesHaveFlag(const std::list< std::shared_ptr< Module >> &list, unsigned int flag)
Returns true if and only if all modules in list have the given flag (or list is empty).
static ModuleManager & Instance()
Exception is thrown if the requested module could not be created by the ModuleManager.
~ModuleManager()
The ModuleManager destructor.
ModuleManager()
The constructor is hidden to avoid that someone creates an instance of this class.
void reset()
Delete all created modules.
void addModuleSearchPath(const std::string &path)
Adds a new filepath to the list of filepaths which are searched for a requested module.
static void fillModuleNameLibMap(std::map< std::string, std::string > &moduleNameLibMap, const boost::filesystem::directory_entry &mapPath)
Adds the module names defined in the map file to the list of known module names.
The base module proxy class is used to create new instances of a module.
const std::string & getModuleName() const
Returns the module name of the module associated to this proxy.
std::shared_ptr< Module > ModulePtr
Defines a pointer to a module object as a boost shared pointer.
std::list< ModulePtr > ModulePtrList
Defines a std::list of shared module pointers.
Abstract base class for different kinds of events.