diff --git a/CMakeLists.txt b/CMakeLists.txt index 79d1650..b1d31c1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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) diff --git a/inc/graph/plugins/plugin.h b/inc/graph/plugins/plugin.h index ea40369..2077b6a 100644 --- a/inc/graph/plugins/plugin.h +++ b/inc/graph/plugins/plugin.h @@ -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; \ No newline at end of file diff --git a/inc/graph/server/plugin.h b/inc/graph/server/plugin.h index 4caefef..30479a6 100644 --- a/inc/graph/server/plugin.h +++ b/inc/graph/server/plugin.h @@ -1,24 +1,31 @@ #pragma once #include +#include #include #include 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 { diff --git a/src/graph/plugins/http/http.cpp b/src/graph/plugins/http/http.cpp index 9cc92a0..a838a9e 100644 --- a/src/graph/plugins/http/http.cpp +++ b/src/graph/plugins/http/http.cpp @@ -3,14 +3,12 @@ #include #include -#define PI 3.1415 -#define to_rad(x) (x/180/3.1415) +#define PI 3.1415 +#define to_rad(x) (x / 180 / 3.1415) 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}; } \ No newline at end of file diff --git a/src/graph/server/gui/mainwindow.cpp b/src/graph/server/gui/mainwindow.cpp index c6659f2..92fa61e 100644 --- a/src/graph/server/gui/mainwindow.cpp +++ b/src/graph/server/gui/mainwindow.cpp @@ -4,7 +4,8 @@ #include #include #include -#include +#include +#include #include #include #include @@ -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); diff --git a/src/graph/server/plugin.cpp b/src/graph/server/plugin.cpp index e8f4a01..0cc0372 100644 --- a/src/graph/server/plugin.cpp +++ b/src/graph/server/plugin.cpp @@ -1,42 +1,43 @@ #include #include +#include +#include #include #include 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();