xybrid/xybrid/config/pluginregistry.cpp

60 lines
1.5 KiB
C++

#include "pluginregistry.h"
using namespace Xybrid::Config;
#include <list>
#include <map>
#include <unordered_map>
#include <QMenu>
#include "data/node.h"
using namespace Xybrid::Data;
namespace {
typedef std::list<std::function<void()>> fqueue; // typedef so QtCreator's auto indent doesn't completely break :|
fqueue& regQueue() {
static fqueue q;
return q;
}
bool& initialized() { static bool b = false; return b; }
std::unordered_map<std::string, std::shared_ptr<PluginInfo>> plugins;
}
bool PluginRegistry::enqueueRegistration(std::function<void ()> f) {
auto& queue = regQueue();
queue.push_back(f);
if (initialized()) f();
return true;
}
void PluginRegistry::init() {
if (initialized()) return;
for (auto& f : regQueue()) f();
initialized() = true;
}
void PluginRegistry::registerPlugin(std::shared_ptr<PluginInfo> pi) {
if (pi->id.empty()) return;
if (plugins.find(pi->id) != plugins.end()) return;
plugins[pi->id] = pi;
}
std::shared_ptr<Node> PluginRegistry::createInstance(const std::string& id) {
auto f = plugins.find(id);
if (f == plugins.end()) return nullptr;
auto n = f->second->createInstance();
n->plugin = f->second;
return n;
}
void PluginRegistry::populatePluginMenu(QMenu* m, std::function<void (std::shared_ptr<Node>)> f) {
for (auto& i : plugins) m->addAction(QString::fromStdString(i.second->displayName), [f, pi = i.second] {
auto n = pi->createInstance();
n->plugin = pi;
f(n);
});
}