mirror of
https://github.com/Chatterino/chatterino2.git
synced 2024-11-21 22:24:07 +01:00
Add support for reloading plugins
This commit is contained in:
parent
03de6869c4
commit
56c7e78f48
5 changed files with 75 additions and 33 deletions
|
@ -3233,6 +3233,11 @@ bool CommandController::registerPluginCommand(const QString &commandName)
|
|||
};
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CommandController::unregisterPluginCommand(const QString &commandName)
|
||||
{
|
||||
return this->commands_.erase(commandName) != 0;
|
||||
}
|
||||
void CommandController::registerCommand(const QString &commandName,
|
||||
CommandFunctionVariants commandFunction)
|
||||
{
|
||||
|
|
|
@ -44,6 +44,7 @@ public:
|
|||
std::unordered_map<QString, QString> context = {});
|
||||
|
||||
bool registerPluginCommand(const QString &commandName);
|
||||
bool unregisterPluginCommand(const QString &commandName);
|
||||
|
||||
private:
|
||||
void load(Paths &paths);
|
||||
|
|
|
@ -34,41 +34,45 @@ void PluginController::initialize(Settings &settings, Paths &paths)
|
|||
{
|
||||
if (info.isDir())
|
||||
{
|
||||
// look for index.lua
|
||||
auto pluginDir = QDir(info.absoluteFilePath());
|
||||
auto index = QFileInfo(pluginDir.filePath("index.lua"));
|
||||
qCDebug(chatterinoLua)
|
||||
<< "trying" << info << "," << index << "at" << pluginDir;
|
||||
if (!index.exists())
|
||||
{
|
||||
qCDebug(chatterinoLua)
|
||||
<< "Missing index.lua in plugin directory" << pluginDir;
|
||||
continue;
|
||||
}
|
||||
qCDebug(chatterinoLua)
|
||||
<< "found index.lua, now looking for info.json!";
|
||||
auto info = QFileInfo(pluginDir.filePath("info.json"));
|
||||
if (!info.exists())
|
||||
{
|
||||
qCDebug(chatterinoLua)
|
||||
<< "Missing info.json in plugin directory" << pluginDir;
|
||||
continue;
|
||||
}
|
||||
QFile infoFile(info.absoluteFilePath());
|
||||
infoFile.open(QIODevice::ReadOnly);
|
||||
auto everything = infoFile.readAll();
|
||||
auto doc = QJsonDocument::fromJson(everything);
|
||||
if (!doc.isObject())
|
||||
{
|
||||
qCDebug(chatterinoLua)
|
||||
<< "info.json root is not an object" << pluginDir;
|
||||
continue;
|
||||
}
|
||||
|
||||
this->load(index, pluginDir, PluginMeta(doc.object()));
|
||||
this->tryLoadFromDir(pluginDir);
|
||||
}
|
||||
}
|
||||
}
|
||||
bool PluginController::tryLoadFromDir(const QDir &pluginDir)
|
||||
{
|
||||
// look for index.lua
|
||||
auto index = QFileInfo(pluginDir.filePath("index.lua"));
|
||||
qCDebug(chatterinoLua) << "looking for index.lua and info.json in"
|
||||
<< pluginDir.path();
|
||||
if (!index.exists())
|
||||
{
|
||||
qCDebug(chatterinoLua)
|
||||
<< "Missing index.lua in plugin directory" << pluginDir;
|
||||
return false;
|
||||
}
|
||||
qCDebug(chatterinoLua) << "found index.lua, now looking for info.json!";
|
||||
auto infojson = QFileInfo(pluginDir.filePath("info.json"));
|
||||
if (!infojson.exists())
|
||||
{
|
||||
qCDebug(chatterinoLua)
|
||||
<< "Missing info.json in plugin directory" << pluginDir;
|
||||
return false;
|
||||
}
|
||||
QFile infoFile(infojson.absoluteFilePath());
|
||||
infoFile.open(QIODevice::ReadOnly);
|
||||
auto everything = infoFile.readAll();
|
||||
auto doc = QJsonDocument::fromJson(everything);
|
||||
if (!doc.isObject())
|
||||
{
|
||||
qCDebug(chatterinoLua)
|
||||
<< "info.json root is not an object" << pluginDir;
|
||||
return false;
|
||||
}
|
||||
|
||||
this->load(index, pluginDir, PluginMeta(doc.object()));
|
||||
return true;
|
||||
}
|
||||
|
||||
void PluginController::load(QFileInfo index, QDir pluginDir, PluginMeta meta)
|
||||
{
|
||||
|
@ -78,13 +82,31 @@ void PluginController::load(QFileInfo index, QDir pluginDir, PluginMeta meta)
|
|||
this->loadChatterinoLib(l);
|
||||
|
||||
auto pluginName = pluginDir.dirName();
|
||||
auto plugin = std::make_unique<Plugin>(pluginName, l, meta);
|
||||
auto plugin = std::make_unique<Plugin>(pluginName, l, meta, pluginDir);
|
||||
this->plugins_.insert({pluginName, std::move(plugin)});
|
||||
|
||||
luaL_dofile(l, index.absoluteFilePath().toStdString().c_str());
|
||||
qCInfo(chatterinoLua) << "Loaded" << pluginName << "plugin from" << index;
|
||||
}
|
||||
|
||||
bool PluginController::reload(const QString &codename)
|
||||
{
|
||||
auto it = this->plugins_.find(codename);
|
||||
if (it == this->plugins_.end())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
lua_close(it->second->state_);
|
||||
for (const auto &[cmd, _] : it->second->ownedCommands)
|
||||
{
|
||||
getApp()->commands->unregisterPluginCommand(cmd);
|
||||
}
|
||||
QDir loadDir = it->second->loadDirectory_;
|
||||
this->plugins_.erase(codename);
|
||||
this->tryLoadFromDir(loadDir);
|
||||
return true;
|
||||
}
|
||||
|
||||
void PluginController::callEvery(const QString &functionName)
|
||||
{
|
||||
for (const auto &[name, plugin] : this->plugins_)
|
||||
|
|
|
@ -47,9 +47,12 @@ class Plugin
|
|||
public:
|
||||
QString codename;
|
||||
PluginMeta meta;
|
||||
Plugin(QString codename, lua_State *state, PluginMeta meta)
|
||||
|
||||
Plugin(QString codename, lua_State *state, PluginMeta meta,
|
||||
const QDir &loadDirectory)
|
||||
: codename(std::move(codename))
|
||||
, meta(std::move(meta))
|
||||
, loadDirectory_(loadDirectory)
|
||||
, state_(state)
|
||||
{
|
||||
}
|
||||
|
@ -71,6 +74,7 @@ public:
|
|||
}
|
||||
|
||||
private:
|
||||
QDir loadDirectory_;
|
||||
lua_State *state_;
|
||||
|
||||
// maps command name -> function name
|
||||
|
@ -112,9 +116,12 @@ public:
|
|||
return this->plugins_;
|
||||
}
|
||||
|
||||
bool reload(const QString &codename);
|
||||
|
||||
private:
|
||||
void load(QFileInfo index, QDir pluginDir, PluginMeta meta);
|
||||
void loadChatterinoLib(lua_State *l);
|
||||
bool tryLoadFromDir(const QDir &pluginDir);
|
||||
std::map<QString, std::unique_ptr<Plugin>> plugins_;
|
||||
};
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include <QFormLayout>
|
||||
#include <QGroupBox>
|
||||
#include <QLabel>
|
||||
#include <QPushButton>
|
||||
|
||||
namespace chatterino {
|
||||
|
||||
|
@ -47,6 +48,12 @@ PluginsPage::PluginsPage()
|
|||
homepage->setOpenExternalLinks(true);
|
||||
|
||||
pl->addRow("Homepage", homepage);
|
||||
|
||||
auto *reload = new QPushButton("Reload");
|
||||
QObject::connect(reload, &QPushButton::pressed, [=]() {
|
||||
getApp()->plugins->reload(codename);
|
||||
});
|
||||
pl->addRow(reload);
|
||||
}
|
||||
}
|
||||
} // namespace chatterino
|
||||
|
|
Loading…
Reference in a new issue