diff --git a/common/include/villas/plugin.hpp b/common/include/villas/plugin.hpp index 68b47bf63..a1f4fa365 100644 --- a/common/include/villas/plugin.hpp +++ b/common/include/villas/plugin.hpp @@ -38,60 +38,70 @@ namespace plugin { /* Forward declarations */ class Plugin; +class Registry; + +extern Registry *registry; template using List = std::list; +class SubRegistry { + +public: + virtual + List<> lookup() = 0; +}; + class Registry { protected: - static List<> *plugins; + List<> plugins; + List registries; public: - static Logger - getLogger() + Logger getLogger() { return logging.get("plugin:registry"); } - static void - add(Plugin *p) + void add(Plugin *p) { - if (plugins == nullptr) - plugins = new List<>; - - plugins->push_back(p); + plugins.push_back(p); } - static void - remove(Plugin *p) + void addSubRegistry(SubRegistry *sr) { - plugins->remove(p); + registries.push_back(sr); } - template - static T * - lookup(const std::string &name) + void remove(Plugin *p) { - for (Plugin *p : *plugins) { - T *t = dynamic_cast(p); - if (!t || t->getName() != name) - continue; + plugins.remove(p); + } - return t; + /// Get all plugins including sub-registries + List<> lookup() { + List<> all; + + all.insert(all.end(), plugins.begin(), plugins.end()); + + for (auto r : registries) { + auto p = r->lookup(); + + all.insert(all.end(), p.begin(), p.end()); } - return nullptr; + return all; } + /// Get all plugins of specific type template - static List - lookup() + List lookup() { List list; - for (Plugin *p : *plugins) { + for (Plugin *p : lookup()) { T *t = dynamic_cast(p); if (t) list.push_back(t); @@ -105,9 +115,22 @@ public: return list; } + /// Get all plugins of specific type and name template - static void - dumpList(); + T * lookup(const std::string &name) + { + for (T *p : lookup()) { + if (p->getName() != name) + continue; + + return p; + } + + return nullptr; + } + + template + void dump(); }; class Plugin { @@ -163,11 +186,11 @@ public: template void -Registry::dumpList() +Registry::dump() { getLogger()->info("Available plugins:"); - for (Plugin *p : *plugins) { + for (Plugin *p : plugins) { T *t = dynamic_cast(p); if (t) getLogger()->info(" - {}: {}", *p, p->getDescription()); diff --git a/common/lib/plugin.cpp b/common/lib/plugin.cpp index efce470ab..11e9de632 100644 --- a/common/lib/plugin.cpp +++ b/common/lib/plugin.cpp @@ -30,21 +30,23 @@ using namespace villas::plugin; -List<> * Registry::plugins; +Registry * villas::plugin::registry = nullptr; Plugin::Plugin() { - Registry::add(this); + if (registry == nullptr) + registry = new Registry(); + + registry->add(this); } Plugin::~Plugin() { - Registry::remove(this); + registry->remove(this); } void Plugin::dump() { - Logger logger = Registry::getLogger(); - logger->info("Name: '{}' Description: '{}'", getName(), getDescription()); + getLogger()->info("Name: '{}' Description: '{}'", getName(), getDescription()); }