Scine::Core  3.0.0
Module management and core interface definitions
 All Classes Files Functions Variables Typedefs Pages
ModuleManager.h
Go to the documentation of this file.
1 
8 #ifndef CORE_MODULEMANAGER_H_
9 #define CORE_MODULEMANAGER_H_
10 
11 /* Internal Includes */
12 #include "Core/ExportControl.h"
13 #include "Core/Module.h"
14 /* External Includes */
15 #include <boost/filesystem.hpp>
16 #include <memory>
17 #include <vector>
18 
19 namespace boost {
20 namespace dll {
21 class shared_library;
22 } // namespace dll
23 } // namespace boost
24 
25 namespace Scine {
26 namespace Core {
27 
44 class CORE_EXPORT ModuleManager {
45  public:
55  static ModuleManager instance;
56  return instance;
57  }
58 
67  ModuleManager(ModuleManager const&) = delete;
68 
77  void operator=(ModuleManager const&) = delete;
78 
96  void load(const boost::filesystem::path& libraryPath);
97 
104  void load(boost::dll::shared_library library);
105 
112  std::vector<std::string> getLoadedModuleNames() const;
113 
114  //* Announces a list of all interfaces for which at least one model is loaded.
115  std::vector<std::string> getLoadedInterfaces() const;
116 
124  template<typename Interface>
125  std::vector<std::string> getLoadedModels() const {
126  return getLoadedModels(Interface::interface);
127  }
128 
136  std::vector<std::string> getLoadedModels(const std::string& interface) const;
137 
149  template<typename Interface>
150  bool has(const std::string& model, const std::string& moduleName = "") const {
151  return has(Interface::interface, model, moduleName);
152  }
153 
166  bool has(const std::string& interface, const std::string& model, const std::string& moduleName = "") const;
167 
187  template<typename Interface>
188  std::shared_ptr<Interface> get(const std::string& model, const std::string& moduleName = "") const {
189  auto any = _get(Interface::interface, model, moduleName);
190  assert(!any.empty() && "Contract of a module's get states that the any may not be empty!");
191  return boost::any_cast<std::shared_ptr<Interface>>(any);
192  }
193 
208  template<typename Interface, typename UnaryPredicate>
209  std::enable_if_t<!std::is_convertible<UnaryPredicate, std::string>::value, std::shared_ptr<Interface>>
210  get(UnaryPredicate&& predicate, const std::string& moduleName = "") const {
211  /* NOTE: Yes, this implementation is a little wasteful in that it gathers
212  * all models, and only then tests the predicate, but this is necessary
213  * to maintain type erasure. Only here do we know what interface type the
214  * models actually are and only here can we call a predicate on them.
215  */
216  auto anys = _getAll(Interface::interface, moduleName);
217 
218  if (anys.empty()) {
219  throw std::runtime_error("There are no models of this interface loaded.");
220  }
221 
222  for (auto& any : anys) {
223  assert(!any.empty() && "Contract of a module's get states the any may not be empty!");
224  auto interfacePtr = boost::any_cast<std::shared_ptr<Interface>>(any);
225  assert(interfacePtr && "Contract of module's get states the wrapped pointer may not be empty!");
226  if (predicate(interfacePtr)) {
227  return interfacePtr;
228  }
229  }
230 
231  throw std::runtime_error("No model matches the supplied predicate!");
232  }
233 
241  bool moduleLoaded(const std::string& moduleName) const;
242 
243  private:
244  // Private Constructor, as required by the singleton design pattern.
245  ModuleManager();
246 
263  boost::any _get(const std::string& interface, const std::string& model, const std::string& moduleName = "") const;
264 
277  std::vector<boost::any> _getAll(const std::string& interface, const std::string& moduleName = "") const;
278 
282  struct LibraryAndModules;
283 
284  static std::vector<LibraryAndModules> _sources;
285 };
286 
287 } /* namespace Core */
288 } /* namespace Scine */
289 
290 #endif /* CORE_MODULEMANAGER_H_ */
static ModuleManager & getInstance()
Static instance getter.
Definition: ModuleManager.h:54
The manager for all dynamically loaded modules.
Definition: ModuleManager.h:44
bool has(const std::string &model, const std::string &moduleName="") const
Checks whether a particular model of an interface is available.
Definition: ModuleManager.h:150
std::vector< std::string > getLoadedModels() const
Announces a list of all loaded models of a particular interface.
Definition: ModuleManager.h:125