24 #include <unordered_map> 27 #include <momemta/Logging.h> 32 template<
typename Interface,
typename... Args>
35 using type = Interface* (Args...);
39 virtual std::shared_ptr<Interface> create(Args...)
const = 0;
40 virtual ~PMakerBase() {}
43 template<
class PluginType>
44 struct PMaker:
public PMakerBase {
45 PMaker(
const std::string& name) {
46 Factory::get().registerPMaker(
this, name);
49 virtual std::shared_ptr<Interface> create(Args... args)
const override {
50 return std::shared_ptr<PluginType>(
new PluginType(std::forward<Args>(args)...));
54 std::shared_ptr<Interface> create(
const std::string& name, Args... args)
const {
55 return find(name)->create(std::forward<Args>(args)...);
60 void registerPMaker(PMakerBase* pMaker,
const std::string& name) {
61 auto it = m_plugins.find(name);
62 if (it != m_plugins.end())
63 throw plugin_already_exists_error(
"The plugin type '" + name +
"' is already registered in the factory.");
65 m_plugins.emplace(name, pMaker);
68 PMakerBase* find(
const std::string& name)
const {
69 auto it = m_plugins.find(name);
70 if (it == m_plugins.end()) {
71 LOG(fatal) <<
"No such plugin type '" << name <<
"' registered in the factory (" << m_plugins.size() <<
" plugins).";
72 throw plugin_not_found_error(
"No such plugin type '" + name +
"' registered in the factory.");
78 std::vector<std::string> getPluginsList()
const {
79 std::vector<std::string> result;
80 for (
const auto& plugin: m_plugins) {
81 result.push_back(plugin.first);
88 class plugin_already_exists_error:
public std::runtime_error {
89 using std::runtime_error::runtime_error;
92 class plugin_not_found_error:
public std::runtime_error {
93 using std::runtime_error::runtime_error;
101 std::unordered_map<std::string, PMakerBase*> m_plugins;
104 #define PLUGIN_UNIQUE_NAME2(x, y) x ## y 105 #define PLUGIN_UNIQUE_NAME(x, y) PLUGIN_UNIQUE_NAME2(x, y)