9 #include <framework/core/Module.h>
10 #include <framework/core/ModuleManager.h>
11 #include <framework/utilities/FileSystem.h>
12 #include <framework/logging/Logger.h>
20 #define MAP_FILE_EXTENSION ".b2modmap"
21 #define LIB_FILE_EXTENSION ".so"
34 if (m_registeredProxyMap.count(moduleProxy->
getModuleName()) == 0) {
35 m_registeredProxyMap.insert(make_pair(moduleProxy->
getModuleName(), moduleProxy));
37 B2ERROR(
"There seems to be more than one module called '" << moduleProxy->
getModuleName() <<
38 "'. Since module names are unique, you must rename one of them!");
46 m_moduleSearchPathList.push_back(path);
49 auto fullPath = std::filesystem::absolute(std::filesystem::path(path));
50 std::filesystem::directory_iterator endIter;
53 map<string, string> moduleNameLibMap;
54 for (std::filesystem::directory_iterator dirItr(fullPath); dirItr != endIter; ++dirItr) {
56 if (std::filesystem::is_regular_file(dirItr->status())) {
57 if (std::filesystem::path(dirItr->path()).extension() == MAP_FILE_EXTENSION) {
58 fillModuleNameLibMap(moduleNameLibMap, *dirItr);
63 m_moduleNameLibMap.insert(moduleNameLibMap.begin(), moduleNameLibMap.end());
70 return m_moduleSearchPathList;
76 return m_moduleNameLibMap;
82 auto moduleIter = m_registeredProxyMap.find(moduleName);
85 auto error = [&moduleName](
const std::string & text) ->
void {
86 auto exception = ModuleNotCreatedError() << moduleName << text;
87 B2ERROR(exception.what());
92 if (moduleIter == m_registeredProxyMap.end()) {
94 if (sharedLibPath.empty()) {
95 auto libIter = m_moduleNameLibMap.find(moduleName);
96 if (libIter != m_moduleNameLibMap.end()) {
97 sharedLibPath = libIter->second;
99 error(
"The module is not known to the framework!");
104 error(
"Could not load shared library " + sharedLibPath +
", file does not exist!");
107 error(
"Could not load shared library " + sharedLibPath +
".");
110 moduleIter = m_registeredProxyMap.find(moduleName);
111 if (moduleIter == m_registeredProxyMap.end()) {
112 error(
"The shared library " + sharedLibPath +
" does not contain the module!");
118 ModulePtr currModulePtr = moduleIter->second->createModule();
119 m_createdModulesList.push_back(currModulePtr);
120 return currModulePtr;
126 return m_createdModulesList;
134 for (
const ModulePtr& module : modulePathList)
135 if (module->hasProperties(propertyFlags)) tmpModuleList.push_back(module);
137 return tmpModuleList;
142 for (
const auto& m : list) {
143 if (!m->hasProperties(flag))
155 const std::filesystem::directory_entry& mapPath)
158 string sharedLibPath = std::filesystem::path(mapPath).replace_extension(LIB_FILE_EXTENSION).string();
160 B2WARNING(
"The shared library file: " << sharedLibPath <<
" doesn't exist, but is required by " << mapPath.path().string());
165 ifstream mapFile(mapPath.path().string().c_str());
169 std::regex expression(
"^REG_MODULE\\((.+)\\)$");
170 std::match_results<std::string::const_iterator> matchResult;
173 while (getline(mapFile, currentLine)) {
176 if (!std::regex_match(currentLine, matchResult, expression)) {
177 B2ERROR(
"Problem parsing map file " << mapPath <<
": Invalid entry in line " << lineNr <<
", skipping remaining file");
181 string moduleName(matchResult[1].first, matchResult[1].second);
183 if (moduleNameLibMap.count(moduleName) == 0) {
184 moduleNameLibMap.insert(make_pair(moduleName, sharedLibPath));
186 B2ERROR(
"There seems to be more than one module called '" << moduleName <<
187 "'. Since module names are unique, you must rename one of them!");
201 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.
static void fillModuleNameLibMap(std::map< std::string, std::string > &moduleNameLibMap, const std::filesystem::directory_entry &mapPath)
Adds the module names defined in the map file to the list of known module names.
~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.
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.