Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Editor: Plugin management #644 #645

Merged
merged 2 commits into from
Dec 25, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 19 additions & 3 deletions engine/includes/editor/pluginmanager.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,10 @@ class ENGINE_EXPORT PluginManager : public QAbstractItemModel {
PLUGIN_VERSION,
PLUGIN_AUTHOR,
PLUGIN_PATH,
PLUGIN_LAST
PLUGIN_LAST,
PLUGIN_ENABLED,
PLUGIN_TAGS,
PLUGIN_BETA
};

public:
Expand Down Expand Up @@ -66,6 +69,7 @@ class ENGINE_EXPORT PluginManager : public QAbstractItemModel {

signals:
void pluginReloaded();
void listChanged();

public slots:
void reloadPlugin(const QString &path);
Expand All @@ -81,6 +85,8 @@ public slots:

QVariant data(const QModelIndex &index, int role) const override;

bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override;

int rowCount(const QModelIndex &parent = QModelIndex()) const override;

QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override;
Expand All @@ -94,6 +100,8 @@ public slots:

void deserializeComponents(const ComponentBackup &backup);

void syncWhiteList();

private:
typedef QMap<QString, System *> SystemsMap;

Expand All @@ -116,15 +124,20 @@ public slots:

QString path;

QString baseName;

QStringList components;

QStringList tags;

QList<QPair<QString, QString>> objects;

QLibrary *library;

Module *module;

bool enabled = true;

bool beta = false;

};

static PluginManager *m_instance;
Expand All @@ -141,6 +154,9 @@ public slots:

QList<Plugin> m_plugins;

QStringList m_initialWhiteList;
QStringList m_whiteList;

};

#endif // PLUGINMANAGER_H
9 changes: 7 additions & 2 deletions engine/includes/editor/projectmanager.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ class ENGINE_EXPORT ProjectManager : public QObject {

void init(const QString &project, const QString &target = QString());

void loadPlatforms();

QString projectName() const { return m_projectName; }
void setProjectName(const QString &value) { if(m_projectName != value) { m_projectName = value; emit updated(); } }

Expand Down Expand Up @@ -68,6 +70,8 @@ class ENGINE_EXPORT ProjectManager : public QObject {

QStringList platforms() const;

QVariantMap &plugins();

void setCurrentPlatform(const QString &platform = QString());
QString currentPlatformName() const;
CodeBuilder *currentBuilder(const QString &platform = QString()) const;
Expand Down Expand Up @@ -99,15 +103,16 @@ public slots:
static ProjectManager *m_pInstance;

private:
QStringList m_platforms;
QVariantMap m_plugins;

QString m_projectId;
QString m_projectName;
QString m_companyName;
QString m_projectVersion;
QString m_projectSdk;

QString m_firstMap;

QStringList m_platforms;
QString m_currentPlatform;

QString m_artifact;
Expand Down
1 change: 1 addition & 0 deletions engine/includes/module.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ class AssetEditor;
#define DESC "description"
#define VERSION "version"
#define AUTHOR "author"
#define BETA "beta"

class ENGINE_EXPORT Module {
public:
Expand Down
167 changes: 125 additions & 42 deletions engine/src/editor/pluginmanager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
#include <components/world.h>
#include <systems/rendersystem.h>

#include "projectmanager.h"

#include <bson.h>
#include <json.h>

Expand All @@ -38,6 +40,12 @@ PluginManager::PluginManager() :
if(qEnvironmentVariableIsSet(qPrintable(gRhi))) {
m_renderName = qEnvironmentVariable(qPrintable(gRhi));
}

m_initialWhiteList << "RenderGL" << "Media" << "Bullet" << "Angel Script";
m_initialWhiteList << "MotionTools" << "ParticleTools" << "PipelineTools" << "QbsTools" << "ShaderTools";
m_initialWhiteList << "TextEditor" << "TextureTools" << "TiledImporter" << "Timeline";

m_whiteList = m_initialWhiteList;
}

PluginManager::~PluginManager() {
Expand Down Expand Up @@ -67,12 +75,14 @@ QVariant PluginManager::data(const QModelIndex &index, int role) const {
case Qt::DisplayRole: {
Plugin plugin = m_plugins.at(index.row());
switch(index.column()) {
case PLUGIN_NAME: return plugin.name;
case PLUGIN_DESCRIPTION: return plugin.description;
case PLUGIN_PATH: return plugin.path;
case PLUGIN_VERSION: return plugin.version;
case PLUGIN_AUTHOR: return plugin.author;
default: break;
case PLUGIN_NAME: return plugin.name;
case PLUGIN_DESCRIPTION: return plugin.description;
case PLUGIN_PATH: return plugin.path;
case PLUGIN_VERSION: return plugin.version;
case PLUGIN_AUTHOR: return plugin.author;
case PLUGIN_ENABLED: return plugin.enabled;
case PLUGIN_TAGS: return plugin.tags;
default: break;
}
} break;
default: break;
Expand All @@ -81,6 +91,31 @@ QVariant PluginManager::data(const QModelIndex &index, int role) const {
return QVariant();
}

bool PluginManager::setData(const QModelIndex &index, const QVariant &value, int role) {
if(!index.isValid()) {
return QAbstractItemModel::setData(index, value, role);
}

switch(index.column()) {
case PLUGIN_ENABLED: {
auto &plugin = m_plugins[index.row()];
plugin.enabled = value.toBool();

auto &plugins = ProjectManager::instance()->plugins();
plugins[plugin.name] = plugin.enabled;

syncWhiteList();

emit listChanged();

return true;
}
default: break;
}

return false;
}

int PluginManager::rowCount(const QModelIndex &parent) const {
Q_UNUSED(parent);
return m_plugins.size();
Expand Down Expand Up @@ -110,6 +145,8 @@ void PluginManager::destroy() {
void PluginManager::init(Engine *engine) {
m_engine = engine;

syncWhiteList();

rescanPath(QString(QCoreApplication::applicationDirPath() + PLUGINS));
}

Expand All @@ -131,50 +168,64 @@ bool PluginManager::loadPlugin(const QString &path, bool reload) {
QFileInfo file(path);

Plugin plug;
plug.name = metaInfo["module"].toString().c_str();
plug.name = metaInfo[MODULE].toString().c_str();
plug.path = file.filePath();
plug.version = metaInfo[VERSION].toString().c_str();
plug.description = metaInfo[DESC].toString().c_str();
plug.author = metaInfo[AUTHOR].toString().c_str();
plug.beta = metaInfo[BETA].toBool();

if(plug.beta) {
plug.tags.push_front("Beta");
}

if(plug.path.contains(ProjectManager::instance()->pluginsPath())) {
plug.tags.push_back("Project");
m_whiteList.push_back(plug.name);
}

plug.library = lib;
plug.module = plugin;
plug.enabled = m_whiteList.contains(plug.name);

if(plug.enabled) {
for(auto &it : metaInfo["objects"].toMap()) {
bool fault = false;
if(it.second == "system") {
if(!registerSystem(plugin, it.first.c_str())) {
fault = true;
}
} else if(it.second == "render") {
if(QString(it.first.c_str()) == m_renderName) {
m_renderFactory = plugin;
Engine::addModule(plugin);
} else {
fault = true;
}

for(auto &it : metaInfo["objects"].toMap()) {
bool fault = false;
if(it.second == "system") {
if(!registerSystem(plugin, it.first.c_str())) {
fault = true;
}
} else if(it.second == "render") {
if(QString(it.first.c_str()) == m_renderName) {
m_renderFactory = plugin;
Engine::addModule(plugin);
} else {
fault = true;
plug.objects.append(qMakePair(it.first.c_str(), it.second.toString().c_str()));
}

} else {
plug.objects.append(qMakePair(it.first.c_str(), it.second.toString().c_str()));
}

if(fault) {
delete plugin;
if(fault) {
delete plugin;

lib->unload();
delete lib;
return true;
lib->unload();
delete lib;
return true;
}
}
}

for(auto &it : metaInfo[gComponents].toList()) {
QString type = QString::fromStdString(it.toString());
plug.components << type;
}
for(auto &it : metaInfo[gComponents].toList()) {
QString type = QString::fromStdString(it.toString());
plug.components << type;
}

if(!plug.components.isEmpty() && reload) {
ComponentBackup result;
serializeComponents(plug.components, result);
deserializeComponents(result);
if(!plug.components.isEmpty() && reload) {
ComponentBackup result;
serializeComponents(plug.components, result);
deserializeComponents(result);
}
}

int index = m_plugins.indexOf(plug);
Expand Down Expand Up @@ -316,6 +367,34 @@ void PluginManager::deserializeComponents(const ComponentBackup &backup) {
emit pluginReloaded();
}

void PluginManager::syncWhiteList() {
QStringList toRemove;

auto &plugins = ProjectManager::instance()->plugins();
for(auto it = plugins.begin(); it != plugins.end(); ++it) {
if(it.value().toBool()) {
if(m_initialWhiteList.contains(it.key())) {
toRemove.push_back(it.key());
} else {
m_whiteList.push_back(it.key());
}
} else {
if(m_initialWhiteList.contains(it.key())) {
m_whiteList.removeOne(it.key());
} else {
toRemove.push_back(it.key());
}
}
}

if(!toRemove.empty()) {
for(auto &it : toRemove) {
plugins.remove(it);
}
}
ProjectManager::instance()->saveSettings();
}

RenderSystem *PluginManager::createRenderer() const {
return reinterpret_cast<RenderSystem *>(m_renderFactory->getObject(qPrintable(m_renderName)));
}
Expand All @@ -334,9 +413,11 @@ QStringList PluginManager::extensions(const QString &type) const {
QStringList result;

for(auto &it : m_plugins) {
for(auto &object : it.objects) {
if(object.second == type) {
result << object.first;
if(it.enabled) {
for(auto &object : it.objects) {
if(object.second == type) {
result << object.first;
}
}
}
}
Expand All @@ -346,9 +427,11 @@ QStringList PluginManager::extensions(const QString &type) const {

void *PluginManager::getPluginObject(const QString &name) {
for(auto &it : m_plugins) {
for(auto &object : it.objects) {
if(object.first == name) {
return it.module->getObject(qPrintable(name));
if(it.enabled) {
for(auto &object : it.objects) {
if(object.first == name) {
return it.module->getObject(qPrintable(name));
}
}
}
}
Expand Down
Loading
Loading