From e9be288f7ce6ed7861a5ed381e2e16ae730524ad Mon Sep 17 00:00:00 2001 From: Mikaƫl Capelle Date: Tue, 29 Sep 2020 21:55:44 +0200 Subject: Add topImplementedInterface(). Minor cleaning. --- src/plugincontainer.cpp | 67 +++++++++++++++++++++++++++++++++++++------------ src/plugincontainer.h | 47 +++++++++++++++++++++++++++++++++- 2 files changed, 97 insertions(+), 17 deletions(-) diff --git a/src/plugincontainer.cpp b/src/plugincontainer.cpp index 1af8487f..90a7e95f 100644 --- a/src/plugincontainer.cpp +++ b/src/plugincontainer.cpp @@ -24,7 +24,6 @@ namespace bf = boost::fusion; template struct PluginTypeName; -template <> struct PluginTypeName { static QString value() { return {}; } }; template <> struct PluginTypeName { static QString value() { return QT_TR_NOOP("Plugin"); } }; template <> struct PluginTypeName { static QString value() { return QT_TR_NOOP("Diagnose"); } }; template <> struct PluginTypeName { static QString value() { return QT_TR_NOOP("Game"); } }; @@ -35,28 +34,24 @@ template <> struct PluginTypeName { static QString value() template <> struct PluginTypeName { static QString value() { return QT_TR_NOOP("Proxy"); } }; template <> struct PluginTypeName { static QString value() { return QT_TR_NOOP("File Mapper"); } }; -QStringList PluginContainer::implementedInterfaces(const IPlugin* plugin) const +QStringList PluginContainer::implementedInterfaces(IPlugin* plugin) const { - // Find the correspond QObject - Can this be done safely with a cast? - auto& objects = bf::at_key(m_Plugins); - auto it = std::find_if(std::begin(objects), std::end(objects), [plugin](QObject *obj) { - return qobject_cast(obj) == plugin; - }); + // We need a QObject to be able to qobject_cast<> to the plugin types: + QObject* oPlugin = as_qobject(plugin); - if (it == std::end(objects)) { + if (!oPlugin) { return {}; } - // We need a QObject to be able to qobject_cast<> to the plugin types: - const QObject* oPlugin = *it; - // Find all the names: QStringList names; - bf::for_each(m_Plugins, [oPlugin, &names](auto const& p) { - using key_type = typename std::decay_t::first_type; - auto name = PluginTypeName::value(); - if (!name.isEmpty()) { - names.append(name); + boost::mp11::mp_for_each([oPlugin, &names](const auto *p) { + using plugin_type = std::decay_t; + if (qobject_cast(oPlugin)) { + auto name = PluginTypeName::value(); + if (!name.isEmpty()) { + names.append(name); + } } }); @@ -68,6 +63,30 @@ QStringList PluginContainer::implementedInterfaces(const IPlugin* plugin) const return names; } +QString PluginContainer::topImplementedInterface(IPlugin* plugin) const +{ + // We need a QObject to be able to qobject_cast<> to the plugin types: + QObject* oPlugin = as_qobject(plugin); + + if (!oPlugin) { + return {}; + } + + // Find all the names: + QString name; + boost::mp11::mp_for_each([oPlugin, &name](auto *p) { + using plugin_type = std::decay_t; + if (name.isEmpty() && qobject_cast(oPlugin)) { + auto tname = PluginTypeName::value(); + if (!tname.isEmpty()) { + name = tname; + } + } + }); + + return name; +} + PluginContainer::PluginContainer(OrganizerCore *organizer) : m_Organizer(organizer) , m_UserInterface(nullptr) @@ -79,6 +98,7 @@ PluginContainer::~PluginContainer() { unloadPlugins(); } + void PluginContainer::setUserInterface(IUserInterface *userInterface, QWidget *widget) { for (IPluginProxy *proxy : bf::at_key(m_Plugins)) { @@ -115,6 +135,21 @@ QStringList PluginContainer::pluginFileNames() const } +QObject* PluginContainer::as_qobject(MOBase::IPlugin* plugin) const +{ + // Find the correspond QObject - Can this be done safely with a cast? + auto& objects = bf::at_key(m_Plugins); + auto it = std::find_if(std::begin(objects), std::end(objects), [plugin](QObject* obj) { + return qobject_cast(obj) == plugin; + }); + + if (it == std::end(objects)) { + return nullptr; + } + + return *it; +} + bool PluginContainer::verifyPlugin(IPlugin *plugin) { if (plugin == nullptr) { diff --git a/src/plugincontainer.h b/src/plugincontainer.h index 7eb59a0f..8672606b 100644 --- a/src/plugincontainer.h +++ b/src/plugincontainer.h @@ -19,6 +19,7 @@ class IUserInterface; #ifndef Q_MOC_RUN #include #include +#include #endif // Q_MOC_RUN #include @@ -46,6 +47,28 @@ private: static const unsigned int PROBLEM_PLUGINSNOTLOADED = 1; + /** + * This typedefs defines the order of plugin interface. This is increasing order of + * importance". + * + * @note IPlugin is the less important interface, followed by IPluginDiagnose and + * IPluginFileMapper as those are usually implemented together with another interface. + * Other interfaces are in a alphabetical order since it is unlikely a plugin will + * implement multiple ones. + */ + using PluginTypeOrder = + boost::mp11::mp_transform< + std::add_pointer_t, + boost::mp11::mp_list< + MOBase::IPluginGame, MOBase::IPluginInstaller, MOBase::IPluginModPage, MOBase::IPluginPreview, + MOBase::IPluginProxy, MOBase::IPluginTool, MOBase::IPluginDiagnose, MOBase::IPluginFileMapper, + MOBase::IPlugin + > + >; + + static_assert( + boost::mp11::mp_size::value == boost::mp11::mp_size::value - 1); + public: /** @@ -56,7 +79,19 @@ public: * * @return the (localized) names of interfaces implemented by this plugin. */ - QStringList implementedInterfaces(const MOBase::IPlugin *plugin) const; + QStringList implementedInterfaces(MOBase::IPlugin *plugin) const; + + /** + * @brief Return the (localized) name of the most important interface implemented by + * the given plugin. + * + * The order of interfaces is defined in X. + * + * @param plugin The plugin to retrieve the interface for. + * + * @return the (localized) name of the most important interface implemented by this plugin. + */ + QString topImplementedInterface(MOBase::IPlugin* plugin) const; PluginContainer(OrganizerCore *organizer); virtual ~PluginContainer(); @@ -114,6 +149,16 @@ signals: private: + /** + * @brief Find the QObject* corresponding to the given plugin. + * + * @param plugin The plugin to find the QObject* for. + * + * @return a QObject* for the given plugin. + */ + QObject* as_qobject(MOBase::IPlugin* plugin) const; + + bool verifyPlugin(MOBase::IPlugin *plugin); void registerGame(MOBase::IPluginGame *game); bool registerPlugin(QObject *pluginObj, const QString &fileName); -- cgit v1.3.1