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"
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!");
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) {
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;
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!");
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.
std::list< std::shared_ptr< Module > > m_createdModulesList
List of all 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.
std::list< std::string > m_moduleSearchPathList
List of all checked and validated filepaths that are searched for map files.
static ModuleManager & Instance()
Exception is thrown if the requested module could not be created by the ModuleManager.
std::map< std::string, std::string > m_moduleNameLibMap
Maps the module name to the filename of the shared library which containes the module.
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.
std::map< std::string, ModuleProxyBase * > m_registeredProxyMap
Maps the module name to a pointer of its proxy.
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 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).
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.