diff options
| author | Mikaël Capelle <capelle.mikael@gmail.com> | 2020-09-29 21:55:44 +0200 |
|---|---|---|
| committer | Mikaël Capelle <capelle.mikael@gmail.com> | 2020-09-29 21:55:44 +0200 |
| commit | e9be288f7ce6ed7861a5ed381e2e16ae730524ad (patch) | |
| tree | 91c1f248fd9e8595ee5be33ee8e1d93aa3f08eb3 | |
| parent | cf828cd77b41e75b6adb3dc79908aa27142fa0af (diff) | |
Add topImplementedInterface(). Minor cleaning.
| -rw-r--r-- | src/plugincontainer.cpp | 67 | ||||
| -rw-r--r-- | 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 <class T>
struct PluginTypeName;
-template <> struct PluginTypeName<QObject> { static QString value() { return {}; } };
template <> struct PluginTypeName<MOBase::IPlugin> { static QString value() { return QT_TR_NOOP("Plugin"); } };
template <> struct PluginTypeName<MOBase::IPluginDiagnose> { static QString value() { return QT_TR_NOOP("Diagnose"); } };
template <> struct PluginTypeName<MOBase::IPluginGame> { static QString value() { return QT_TR_NOOP("Game"); } };
@@ -35,28 +34,24 @@ template <> struct PluginTypeName<MOBase::IPluginTool> { static QString value() template <> struct PluginTypeName<MOBase::IPluginProxy> { static QString value() { return QT_TR_NOOP("Proxy"); } };
template <> struct PluginTypeName<MOBase::IPluginFileMapper> { 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<QObject>(m_Plugins);
- auto it = std::find_if(std::begin(objects), std::end(objects), [plugin](QObject *obj) {
- return qobject_cast<IPlugin*>(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<decltype(p)>::first_type;
- auto name = PluginTypeName<key_type>::value();
- if (!name.isEmpty()) {
- names.append(name);
+ boost::mp11::mp_for_each<PluginTypeOrder>([oPlugin, &names](const auto *p) {
+ using plugin_type = std::decay_t<decltype(*p)>;
+ if (qobject_cast<plugin_type*>(oPlugin)) {
+ auto name = PluginTypeName<plugin_type>::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<PluginTypeOrder>([oPlugin, &name](auto *p) {
+ using plugin_type = std::decay_t<decltype(*p)>;
+ if (name.isEmpty() && qobject_cast<plugin_type*>(oPlugin)) {
+ auto tname = PluginTypeName<plugin_type>::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<IPluginProxy>(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<QObject>(m_Plugins);
+ auto it = std::find_if(std::begin(objects), std::end(objects), [plugin](QObject* obj) {
+ return qobject_cast<IPlugin*>(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 <boost/fusion/container.hpp>
#include <boost/fusion/include/at_key.hpp>
+#include <boost/mp11.hpp>
#endif // Q_MOC_RUN
#include <vector>
@@ -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<PluginTypeOrder>::value == boost::mp11::mp_size<PluginContainer::PluginMap>::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);
|
