threading?
This commit is contained in:
parent
71d6ad8763
commit
911a174006
@ -6,7 +6,7 @@ include(CMakePrintHelpers)
|
||||
set(CMAKE_C_COMPILER clang)
|
||||
set(CMAKE_CXX_COMPILER clang++)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
set(CMAKE_CXX_STANDARD 20)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
|
||||
set(CMAKE_EXPORT_COMPILE_COMMANDS true)
|
||||
|
@ -11,13 +11,13 @@ typedef struct {
|
||||
double x, y;
|
||||
} point_t;
|
||||
|
||||
typedef bool (*start_t)();
|
||||
typedef int (*run_method_t)();
|
||||
typedef void (*destroy_t)();
|
||||
typedef void (*update_callback_t)(unsigned int chartIndex, const char* seriesName, const point_t* points, int count);
|
||||
|
||||
typedef struct {
|
||||
uint32_t version;
|
||||
start_t init_method;
|
||||
run_method_t run_method;
|
||||
destroy_t destroy_method;
|
||||
update_callback_t update_callback;
|
||||
} plugin_t;
|
@ -1,24 +1,31 @@
|
||||
#pragma once
|
||||
|
||||
#include <graph/plugins/plugin.h>
|
||||
#include <QThread>
|
||||
#include <QAbstractListModel>
|
||||
#include <string>
|
||||
|
||||
namespace Graph {
|
||||
|
||||
class Plugin {
|
||||
class Plugin : public QObject {
|
||||
Q_OBJECT
|
||||
|
||||
private:
|
||||
plugin_t* plugin;
|
||||
const std::string path;
|
||||
const void* handle;
|
||||
|
||||
public slots:
|
||||
void run();
|
||||
|
||||
signals:
|
||||
void exited(int code);
|
||||
|
||||
public:
|
||||
Plugin(const std::string& path);
|
||||
Plugin(const std::string& path, update_callback_t callback);
|
||||
~Plugin();
|
||||
|
||||
bool init(update_callback_t callback);
|
||||
|
||||
const std::string& get_path() const { return this->path; }
|
||||
const std::string& getPath() const { return this->path; }
|
||||
};
|
||||
|
||||
class PluginModel : public QAbstractListModel {
|
||||
|
@ -8,9 +8,7 @@
|
||||
|
||||
extern "C" {
|
||||
|
||||
plugin_t plugin = {.version = 1, .init_method = &init, .destroy_method = &destroy};
|
||||
|
||||
bool init() {
|
||||
int run() {
|
||||
std::cout << "init" << std::endl;
|
||||
point_t points[100];
|
||||
for (int i = 0; i < 100; i++) {
|
||||
@ -19,10 +17,12 @@ bool init() {
|
||||
}
|
||||
|
||||
plugin.update_callback(0, "1st", points, 100);
|
||||
return true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void destroy() {
|
||||
std::cout << "destory" << std::endl;
|
||||
}
|
||||
|
||||
plugin_t plugin = {.version = 1, .run_method = &run, .destroy_method = &destroy};
|
||||
}
|
@ -4,7 +4,8 @@
|
||||
#include <graph/server/plugin.h>
|
||||
#include <graph/server/spec.h>
|
||||
#include <graph/server/ui_mainwindow.h>
|
||||
#include <qfiledialog.h>
|
||||
#include <qobject.h>
|
||||
#include <qthread.h>
|
||||
#include <QFileDialog>
|
||||
#include <QMessageBox>
|
||||
#include <iostream>
|
||||
@ -126,9 +127,16 @@ void MainWindow::on_action_Load_triggered() {
|
||||
|
||||
for (QString file : fileDialog->selectedFiles()) {
|
||||
try {
|
||||
Plugin* plugin = new Plugin(file.toStdString());
|
||||
plugin->init(&Graph::GUI::addData);
|
||||
Plugin* plugin = new Plugin(file.toStdString(), &Graph::GUI::addData);
|
||||
pluginModel->add(plugin);
|
||||
|
||||
QThread* thread = new QThread();
|
||||
plugin->moveToThread(thread);
|
||||
connect(plugin, &Plugin::exited, this, [](int code) { std::cout << "plugin exited: " << code << std::endl; });
|
||||
connect(thread, &QThread::started, plugin, &Plugin::run);
|
||||
connect(plugin, &Plugin::exited, thread, &QThread::quit);
|
||||
connect(thread, &QThread::finished, thread, &QThread::deleteLater);
|
||||
thread->start();
|
||||
} catch (std::runtime_error e) {
|
||||
std::cout << e.what() << std::endl;
|
||||
QMessageBox::critical(this, "Error", "Failed to load plugin:\n" + file, QMessageBox::StandardButton::Ignore);
|
||||
|
@ -1,42 +1,43 @@
|
||||
#include <dlfcn.h>
|
||||
#include <graph/server/plugin.h>
|
||||
#include <qthread.h>
|
||||
#include <iostream>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
|
||||
namespace Graph {
|
||||
Plugin::Plugin(const std::string& path) : path(path) {
|
||||
this->handle = dlopen(path.c_str(), RTLD_LAZY);
|
||||
if (!this->handle)
|
||||
Plugin::Plugin(const std::string& path, update_callback_t callback) : path(path) {
|
||||
handle = dlopen(path.c_str(), RTLD_LAZY);
|
||||
if (!handle)
|
||||
throw std::runtime_error(dlerror());
|
||||
|
||||
this->plugin = (plugin_t*)dlsym((void*)this->handle, "plugin");
|
||||
if (!this->plugin)
|
||||
plugin = (plugin_t*)dlsym((void*)this->handle, "plugin");
|
||||
if (!plugin)
|
||||
throw std::runtime_error(dlerror());
|
||||
|
||||
this->plugin->update_callback = nullptr;
|
||||
plugin->update_callback = callback;
|
||||
}
|
||||
|
||||
void Plugin::run() {
|
||||
emit exited(plugin->run_method());
|
||||
}
|
||||
|
||||
Plugin::~Plugin() {
|
||||
if (this->plugin->destroy_method)
|
||||
this->plugin->destroy_method();
|
||||
if (plugin->destroy_method)
|
||||
plugin->destroy_method();
|
||||
|
||||
if (handle)
|
||||
dlclose((void*)this->handle);
|
||||
}
|
||||
|
||||
bool Plugin::init(update_callback_t callback) {
|
||||
this->plugin->update_callback = callback;
|
||||
return this->plugin->init_method();
|
||||
dlclose((void*)handle);
|
||||
}
|
||||
|
||||
PluginModel::~PluginModel() {
|
||||
for (Plugin* plugin : this->plugins) {
|
||||
for (Plugin* plugin : plugins) {
|
||||
delete plugin;
|
||||
}
|
||||
}
|
||||
|
||||
int PluginModel::rowCount(const QModelIndex& parent) const {
|
||||
return this->plugins.size();
|
||||
return plugins.size();
|
||||
}
|
||||
|
||||
QVariant PluginModel::data(const QModelIndex& index, int role) const {
|
||||
@ -44,7 +45,7 @@ QVariant PluginModel::data(const QModelIndex& index, int role) const {
|
||||
return QVariant();
|
||||
|
||||
if (role == Qt::DisplayRole) {
|
||||
return QString(plugins[index.row()]->get_path().c_str());
|
||||
return QString(plugins[index.row()]->getPath().c_str());
|
||||
}
|
||||
|
||||
return QVariant();
|
||||
|
Loading…
Reference in New Issue
Block a user