plugin loading gui
This commit is contained in:
parent
1fb3e98146
commit
679b2d3eca
9
.clang-format
Normal file
9
.clang-format
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
BasedOnStyle: Chromium
|
||||||
|
IndentWidth: 2
|
||||||
|
ColumnLimit: 160
|
||||||
|
SpaceAfterCStyleCast: false
|
||||||
|
UseTab: Never
|
||||||
|
AllowShortIfStatementsOnASingleLine: false
|
||||||
|
AlignTrailingComments: false
|
||||||
|
SpacesBeforeTrailingComments: 1
|
||||||
|
AlignConsecutiveMacros: Consecutive
|
@ -4,6 +4,7 @@
|
|||||||
#include <QMenuBar>
|
#include <QMenuBar>
|
||||||
#include <QStatusBar>
|
#include <QStatusBar>
|
||||||
#include <QToolBar>
|
#include <QToolBar>
|
||||||
|
#include <graph/server/plugin.h>
|
||||||
|
|
||||||
namespace Ui {
|
namespace Ui {
|
||||||
class MainWindow;
|
class MainWindow;
|
||||||
@ -17,9 +18,12 @@ public:
|
|||||||
~MainWindow();
|
~MainWindow();
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void on_actionExit_triggered();
|
void on_action_Add_triggered();
|
||||||
|
void on_action_Load_triggered();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Ui::MainWindow *ui;
|
Ui::MainWindow *ui;
|
||||||
|
|
||||||
|
PluginModel* pluginsModel;
|
||||||
};
|
};
|
||||||
} // namespace Graph::GUI
|
} // namespace Graph::GUI
|
||||||
|
@ -1,18 +1,39 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <graph/plugins/plugin.h>
|
#include <graph/plugins/plugin.h>
|
||||||
|
#include <QAbstractListModel>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
namespace Graph {
|
namespace Graph {
|
||||||
|
|
||||||
class Plugin {
|
class Plugin {
|
||||||
private:
|
private:
|
||||||
plugin_t *plugin;
|
plugin_t* plugin;
|
||||||
|
const std::string path;
|
||||||
const void* handle;
|
const void* handle;
|
||||||
public:
|
|
||||||
|
public:
|
||||||
Plugin(const std::string& path);
|
Plugin(const std::string& path);
|
||||||
~Plugin();
|
~Plugin();
|
||||||
|
|
||||||
bool init(update_callback_t callback);
|
bool init(update_callback_t callback);
|
||||||
|
|
||||||
|
const std::string& get_path() const { return this->path; }
|
||||||
|
};
|
||||||
|
|
||||||
|
class PluginModel : public QAbstractListModel {
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
PluginModel(QObject* parent) : QAbstractListModel(parent) {}
|
||||||
|
~PluginModel();
|
||||||
|
|
||||||
|
int rowCount(const QModelIndex& parent = QModelIndex()) const override;
|
||||||
|
QVariant data(const QModelIndex& index, int role) const override;
|
||||||
|
|
||||||
|
void add(Plugin* plugin);
|
||||||
|
void remove(int index);
|
||||||
|
|
||||||
|
private:
|
||||||
|
QList<Plugin*> plugins;
|
||||||
};
|
};
|
||||||
} // namespace Graph
|
} // namespace Graph
|
||||||
|
@ -1,15 +1,52 @@
|
|||||||
#include <graph/server/gui/mainwindow.h>
|
#include <graph/server/gui/mainwindow.h>
|
||||||
|
#include <graph/server/plugin.h>
|
||||||
#include <graph/server/ui_mainwindow.h>
|
#include <graph/server/ui_mainwindow.h>
|
||||||
|
#include <QFileDialog>
|
||||||
|
#include <QMessageBox>
|
||||||
|
#include <iostream>
|
||||||
|
#include <stdexcept>
|
||||||
|
|
||||||
namespace Graph::GUI {
|
namespace Graph::GUI {
|
||||||
MainWindow::MainWindow(QWidget *parent)
|
MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent), ui(new Ui::MainWindow) {
|
||||||
: QMainWindow(parent), ui(new Ui::MainWindow) {
|
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
|
|
||||||
|
// plugins
|
||||||
|
pluginsModel = new PluginModel(this);
|
||||||
|
ui->pluginsListView->setModel(pluginsModel);
|
||||||
|
|
||||||
|
// unload plugin
|
||||||
|
connect(ui->pluginsListView, &QListView::doubleClicked, [&](const QModelIndex& index) {
|
||||||
|
pluginsModel->removeRow(index.row());
|
||||||
|
pluginsModel->remove(index.row());
|
||||||
|
ui->pluginsListView->doItemsLayout();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
MainWindow::~MainWindow() { delete ui; }
|
MainWindow::~MainWindow() {
|
||||||
|
delete ui;
|
||||||
void MainWindow::on_actionExit_triggered() {
|
delete pluginsModel;
|
||||||
this->close();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MainWindow::on_action_Add_triggered() {}
|
||||||
|
|
||||||
|
void MainWindow::on_action_Load_triggered() {
|
||||||
|
QString file = QFileDialog::getOpenFileName(this, "Load plugin", ".", "Plugins (*.so *.dll *.dylib)");
|
||||||
|
|
||||||
|
if (file.isEmpty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
try {
|
||||||
|
pluginsModel->add(new Plugin(file.toStdString()));
|
||||||
|
} catch (std::runtime_error e) {
|
||||||
|
std::cout << e.what() << std::endl;
|
||||||
|
QMessageBox::critical(this, "Error", "Failed to load plugin.", QMessageBox::StandardButton::Ignore);
|
||||||
|
}
|
||||||
|
|
||||||
|
int row = pluginsModel->rowCount();
|
||||||
|
pluginsModel->insertRow(row);
|
||||||
|
QModelIndex index = pluginsModel->index(row);
|
||||||
|
ui->pluginsListView->doItemsLayout();
|
||||||
|
ui->pluginsListView->setCurrentIndex(index);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Graph::GUI
|
} // namespace Graph::GUI
|
||||||
|
@ -29,7 +29,7 @@
|
|||||||
</attribute>
|
</attribute>
|
||||||
<layout class="QVBoxLayout" name="graphsVerticalLayout">
|
<layout class="QVBoxLayout" name="graphsVerticalLayout">
|
||||||
<item>
|
<item>
|
||||||
<widget class="QListView" name="graphsListView"/>
|
<widget class="QListWidget" name="graphsListWidget"/>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
|
@ -1,16 +1,16 @@
|
|||||||
|
#include <dlfcn.h>
|
||||||
#include <graph/server/gui/mainwindow.h>
|
#include <graph/server/gui/mainwindow.h>
|
||||||
#include <graph/server/plugin.h>
|
#include <graph/server/plugin.h>
|
||||||
#include <dlfcn.h>
|
|
||||||
#include <iostream>
|
|
||||||
#include <QtWidgets/QApplication>
|
#include <QtWidgets/QApplication>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
int main(int argc, char** argv) {
|
int main(int argc, char** argv) {
|
||||||
Graph::Plugin plugin("plugins/libhttp.so");
|
// Graph::Plugin plugin("plugins/libhttp.so");
|
||||||
plugin.init((update_callback_t)1);
|
// plugin.init((update_callback_t)1);
|
||||||
|
|
||||||
QApplication app(argc, argv);
|
QApplication app(argc, argv);
|
||||||
Graph::GUI::MainWindow window;
|
Graph::GUI::MainWindow window;
|
||||||
window.show();
|
window.show();
|
||||||
|
|
||||||
return app.exec();
|
return app.exec();
|
||||||
}
|
}
|
@ -1,31 +1,65 @@
|
|||||||
#include <dlfcn.h>
|
#include <dlfcn.h>
|
||||||
#include <graph/server/plugin.h>
|
#include <graph/server/plugin.h>
|
||||||
|
#include <qnamespace.h>
|
||||||
|
#include <qobject.h>
|
||||||
|
#include <qvariant.h>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
namespace Graph {
|
namespace Graph {
|
||||||
Plugin::Plugin(const std::string &path) {
|
Plugin::Plugin(const std::string& path) : path(path) {
|
||||||
this->handle = dlopen(path.c_str(), RTLD_LAZY);
|
this->handle = dlopen(path.c_str(), RTLD_LAZY);
|
||||||
if (!this->handle)
|
if (!this->handle)
|
||||||
throw std::runtime_error(dlerror());
|
throw std::runtime_error(dlerror());
|
||||||
|
|
||||||
this->plugin = (plugin_t*)dlsym((void*)this->handle, "plugin");
|
this->plugin = (plugin_t*)dlsym((void*)this->handle, "plugin");
|
||||||
if (!this->plugin)
|
if (!this->plugin)
|
||||||
throw std::runtime_error(dlerror());
|
throw std::runtime_error(dlerror());
|
||||||
|
|
||||||
this->plugin->update_callback = nullptr;
|
this->plugin->update_callback = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
Plugin::~Plugin() {
|
Plugin::~Plugin() {
|
||||||
if (this->plugin->update_callback)
|
if (this->plugin->update_callback)
|
||||||
this->plugin->destroy_method();
|
this->plugin->destroy_method();
|
||||||
|
|
||||||
if (this->handle)
|
if (this->handle)
|
||||||
dlclose((void*)this->handle);
|
dlclose((void*)this->handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Plugin::init(update_callback_t callback) {
|
bool Plugin::init(update_callback_t callback) {
|
||||||
this->plugin->update_callback = callback;
|
this->plugin->update_callback = callback;
|
||||||
return this->plugin->init_method();
|
return this->plugin->init_method();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PluginModel::~PluginModel() {
|
||||||
|
for (Plugin* plugin : this->plugins) {
|
||||||
|
delete plugin;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int PluginModel::rowCount(const QModelIndex& parent) const {
|
||||||
|
return this->plugins.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant PluginModel::data(const QModelIndex& index, int role) const {
|
||||||
|
if (!index.isValid())
|
||||||
|
return QVariant();
|
||||||
|
|
||||||
|
if (role == Qt::DisplayRole) {
|
||||||
|
return QString(plugins[index.row()]->get_path().c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
return QVariant();
|
||||||
|
}
|
||||||
|
|
||||||
|
void PluginModel::add(Plugin* plugin) {
|
||||||
|
plugins << plugin;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PluginModel::remove(int index) {
|
||||||
|
delete plugins[index];
|
||||||
|
plugins.removeAt(index);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Graph
|
} // namespace Graph
|
Loading…
Reference in New Issue
Block a user