From 0f634ee3a619b07188975c9fc4f8a0848ec8035b Mon Sep 17 00:00:00 2001 From: Stanislaw Halik Date: Sat, 6 May 2017 13:16:55 +0200 Subject: api/plugins: modernize C++ and Qt --- api/plugin-support.hpp | 128 ++++++++++++++++++++++--------------------------- 1 file changed, 56 insertions(+), 72 deletions(-) (limited to 'api') diff --git a/api/plugin-support.hpp b/api/plugin-support.hpp index 2ec55f0e..1bafd6ff 100644 --- a/api/plugin-support.hpp +++ b/api/plugin-support.hpp @@ -8,25 +8,17 @@ #pragma once #include "plugin-api.hpp" -#include "options/options.hpp" -#include +#include +#include + #include #include #include -#include #include - -#include -#include -#include -#include - -#include -#include #include #include -#include +#include #if defined(__APPLE__) # define OPENTRACK_SOLIB_EXT "dylib" @@ -36,27 +28,25 @@ # define OPENTRACK_SOLIB_EXT "so" #endif -#include - #ifdef _MSC_VER # define OPENTRACK_SOLIB_PREFIX "" #else -# define OPENTRACK_SOLIB_PREFIX "" +# define OPENTRACK_SOLIB_PREFIX "lib" #endif extern "C" typedef void* (*OPENTRACK_CTOR_FUNPTR)(void); extern "C" typedef Metadata* (*OPENTRACK_METADATA_FUNPTR)(void); -struct dylib final { - enum Type : unsigned { Filter, Tracker, Protocol, Invalid = 0xcafebabeU }; +struct dylib final +{ + enum Type { Filter = 0xdeadbabe, Tracker = 0xcafebeef, Protocol = 0xdeadf00d, Invalid = 0xcafebabe }; dylib(const QString& filename, Type t) : type(Invalid), filename(filename), Dialog(nullptr), Constructor(nullptr), - Meta(nullptr), - handle(nullptr) + Meta(nullptr) { // otherwise dlopen opens the calling executable if (filename.size() == 0) @@ -77,7 +67,7 @@ struct dylib final { if (check((Meta = (OPENTRACK_METADATA_FUNPTR) handle.resolve("GetMetadata"), !Meta))) return; - auto m = mem(Meta()); + auto m = std::unique_ptr(Meta()); icon = m->icon(); name = m->name(); @@ -94,38 +84,42 @@ struct dylib final { } } - static QList> enum_libraries(const QString& library_path) + static QList> enum_libraries(const QString& library_path) { - const char* filters_n[] = { OPENTRACK_SOLIB_PREFIX "opentrack-filter-*." OPENTRACK_SOLIB_EXT, - OPENTRACK_SOLIB_PREFIX "opentrack-tracker-*." OPENTRACK_SOLIB_EXT, - OPENTRACK_SOLIB_PREFIX "opentrack-proto-*." OPENTRACK_SOLIB_EXT, - }; - const Type filters_t[] = { Filter, Tracker, Protocol }; - - QDir settingsDir(library_path); - - QList> ret; - - for (int i = 0; i < 3; i++) + QDir module_directory(library_path); + QList> ret; + + static const struct filter_ { + Type type; + QString glob; + } filters[] = { + { Filter, OPENTRACK_SOLIB_PREFIX "opentrack-filter-*." OPENTRACK_SOLIB_EXT, }, + { Tracker, OPENTRACK_SOLIB_PREFIX "opentrack-tracker-*." OPENTRACK_SOLIB_EXT, }, + { Protocol, OPENTRACK_SOLIB_PREFIX "opentrack-proto-*." OPENTRACK_SOLIB_EXT, }, + }; + + for (const filter_& filter : filters) { - QString glob = filters_n[i]; - Type t = filters_t[i]; - QStringList filenames = settingsDir.entryList(QStringList { glob }, QDir::Files, QDir::Name); - - for (const QString& filename : filenames) + for (const QString& filename : module_directory.entryList({ filter.glob }, QDir::Files, QDir::Name)) { - QIcon icon; - QString longName; - auto lib = std::make_shared(library_path + filename, t); - if (!get_metadata(lib, longName, icon)) + std::shared_ptr lib = std::make_shared(QStringLiteral("%1/%2").arg(library_path).arg(filename), filter.type); + + if (lib->type == Invalid) + { + qDebug() << "can't load dylib" << filename; continue; + } + if (std::any_of(ret.cbegin(), ret.cend(), - [&](mem a) {return a->type == lib->type && a->name == lib->name;})) + [&lib](const std::shared_ptr& a) { + return a->type == lib->type && a->name == lib->name; + })) { - qDebug() << "Duplicate lib" << lib->filename; + qDebug() << "duplicate lib" << filename << "ident" << lib->name; continue; } + ret.push_back(lib); } } @@ -161,60 +155,50 @@ private: return fail; } - - static bool get_metadata(mem lib, QString& name, QIcon& icon) - { - Metadata* meta; - if (!lib->Meta || ((meta = lib->Meta()), !meta)) - return false; - name = meta->name(); - icon = meta->icon(); - delete meta; - return true; - } }; struct Modules final { + using dylib_ptr = std::shared_ptr; + using dylib_list = QList; + Modules(const QString& library_path) : module_list(dylib::enum_libraries(library_path)), filter_modules(filter(dylib::Filter)), tracker_modules(filter(dylib::Tracker)), protocol_modules(filter(dylib::Protocol)) {} - QList>& filters() { return filter_modules; } - QList>& trackers() { return tracker_modules; } - QList>& protocols() { return protocol_modules; } + dylib_list& filters() { return filter_modules; } + dylib_list& trackers() { return tracker_modules; } + dylib_list& protocols() { return protocol_modules; } private: - QList> module_list; - QList> filter_modules; - QList> tracker_modules; - QList> protocol_modules; + dylib_list module_list; + dylib_list filter_modules; + dylib_list tracker_modules; + dylib_list protocol_modules; - template - static void sort(QList& xs) + static dylib_list& sorted(dylib_list& xs) { - std::sort(xs.begin(), xs.end(), [&](const t& a, const t& b) { return a->name.toLower() < b->name.toLower(); }); + std::sort(xs.begin(), xs.end(), [&](const dylib_ptr& a, const dylib_ptr& b) { return a->name.toLower() < b->name.toLower(); }); + return xs; } - QList> filter(dylib::Type t) + dylib_list filter(dylib::Type t) { - QList> ret; + QList> ret; for (auto x : module_list) if (x->type == t) ret.push_back(x); - sort(ret); - - return ret; + return sorted(ret); } }; template -mem make_dylib_instance(mem lib) +static inline std::shared_ptr make_dylib_instance(const std::shared_ptr& lib) { - mem ret; + std::shared_ptr ret; if (lib != nullptr && lib->Constructor) - ret = mem(reinterpret_cast(reinterpret_cast(lib->Constructor)())); + ret = std::shared_ptr(reinterpret_cast(reinterpret_cast(lib->Constructor)())); return ret; } -- cgit v1.2.3