##// END OF EJS Templates
Implements method to get the number of plugins loaded
Alexandre Leroux -
r69:0c771d009214
parent child
Show More
@@ -1,119 +1,118
1 #include <Plugin/PluginManager.h>
1 #include <Plugin/PluginManager.h>
2
2
3 #include <Plugin/IPlugin.h>
3 #include <Plugin/IPlugin.h>
4
4
5 #include <QDir>
5 #include <QDir>
6 #include <QLibrary>
6 #include <QLibrary>
7 #include <QPluginLoader>
7 #include <QPluginLoader>
8
8
9 Q_LOGGING_CATEGORY(LOG_PluginManager, "PluginManager")
9 Q_LOGGING_CATEGORY(LOG_PluginManager, "PluginManager")
10
10
11 namespace {
11 namespace {
12
12
13 /// Key for retrieving metadata of the plugin
13 /// Key for retrieving metadata of the plugin
14 const auto PLUGIN_METADATA_KEY = QStringLiteral("MetaData");
14 const auto PLUGIN_METADATA_KEY = QStringLiteral("MetaData");
15
15
16 /// Key for retrieving the name of the plugin in its metadata
16 /// Key for retrieving the name of the plugin in its metadata
17 const auto PLUGIN_NAME_KEY = QStringLiteral("name");
17 const auto PLUGIN_NAME_KEY = QStringLiteral("name");
18
18
19 /// Helper to state the plugin loading operation
19 /// Helper to state the plugin loading operation
20 struct LoadPluginState {
20 struct LoadPluginState {
21 explicit LoadPluginState(const QString &pluginPath)
21 explicit LoadPluginState(const QString &pluginPath)
22 : m_PluginPath{pluginPath}, m_Valid{true}, m_ErrorMessage{}
22 : m_PluginPath{pluginPath}, m_Valid{true}, m_ErrorMessage{}
23 {
23 {
24 }
24 }
25
25
26 void log() const
26 void log() const
27 {
27 {
28 if (m_Valid) {
28 if (m_Valid) {
29 qCDebug(LOG_PluginManager())
29 qCDebug(LOG_PluginManager())
30 << QObject::tr("File '%1' has been loaded as a plugin").arg(m_PluginPath);
30 << QObject::tr("File '%1' has been loaded as a plugin").arg(m_PluginPath);
31 }
31 }
32 else {
32 else {
33 qCWarning(LOG_PluginManager())
33 qCWarning(LOG_PluginManager())
34 << QObject::tr("File '%1' can't be loaded as a plugin: %2")
34 << QObject::tr("File '%1' can't be loaded as a plugin: %2")
35 .arg(m_PluginPath)
35 .arg(m_PluginPath)
36 .arg(m_ErrorMessage);
36 .arg(m_ErrorMessage);
37 }
37 }
38 }
38 }
39
39
40 void setError(const QString &errorMessage)
40 void setError(const QString &errorMessage)
41 {
41 {
42 m_Valid = false;
42 m_Valid = false;
43 m_ErrorMessage = errorMessage;
43 m_ErrorMessage = errorMessage;
44 }
44 }
45
45
46 QString m_PluginPath;
46 QString m_PluginPath;
47 bool m_Valid;
47 bool m_Valid;
48 QString m_ErrorMessage;
48 QString m_ErrorMessage;
49 };
49 };
50
50
51 } // namespace
51 } // namespace
52
52
53 struct PluginManager::PluginManagerPrivate {
53 struct PluginManager::PluginManagerPrivate {
54 /**
54 /**
55 * Loads a single plugin into SciQlop. The method has no effect if the plugin is malformed (e.g.
55 * Loads a single plugin into SciQlop. The method has no effect if the plugin is malformed (e.g.
56 * wrong library type, missing metadata, etc.)
56 * wrong library type, missing metadata, etc.)
57 * @param pluginPath the path to the plugin library.
57 * @param pluginPath the path to the plugin library.
58 */
58 */
59 void loadPlugin(const QString &pluginPath)
59 void loadPlugin(const QString &pluginPath)
60 {
60 {
61 qCDebug(LOG_PluginManager())
61 qCDebug(LOG_PluginManager())
62 << QObject::tr("Attempting to load file '%1' as a plugin").arg(pluginPath);
62 << QObject::tr("Attempting to load file '%1' as a plugin").arg(pluginPath);
63
63
64 LoadPluginState loadState{pluginPath};
64 LoadPluginState loadState{pluginPath};
65
65
66 if (QLibrary::isLibrary(pluginPath)) {
66 if (QLibrary::isLibrary(pluginPath)) {
67 QPluginLoader pluginLoader{pluginPath};
67 QPluginLoader pluginLoader{pluginPath};
68
68
69 // Retrieving the plugin name to check if it can be loaded (i.e. no plugin with the same
69 // Retrieving the plugin name to check if it can be loaded (i.e. no plugin with the same
70 // name has been registered yet)
70 // name has been registered yet)
71 auto metadata = pluginLoader.metaData().value(PLUGIN_METADATA_KEY).toObject();
71 auto metadata = pluginLoader.metaData().value(PLUGIN_METADATA_KEY).toObject();
72 auto pluginName = metadata.value(PLUGIN_NAME_KEY).toString();
72 auto pluginName = metadata.value(PLUGIN_NAME_KEY).toString();
73
73
74 if (pluginName.isEmpty()) {
74 if (pluginName.isEmpty()) {
75 loadState.setError(QObject::tr("empty file name"));
75 loadState.setError(QObject::tr("empty file name"));
76 }
76 }
77 else if (m_RegisteredPlugins.contains(pluginName)) {
77 else if (m_RegisteredPlugins.contains(pluginName)) {
78 loadState.setError(QObject::tr("name '%1' already registered").arg(pluginName));
78 loadState.setError(QObject::tr("name '%1' already registered").arg(pluginName));
79 }
79 }
80 else {
80 else {
81 if (auto pluginInstance = qobject_cast<IPlugin *>(pluginLoader.instance())) {
81 if (auto pluginInstance = qobject_cast<IPlugin *>(pluginLoader.instance())) {
82 pluginInstance->initialize();
82 pluginInstance->initialize();
83 m_RegisteredPlugins.insert(pluginName, pluginPath);
83 m_RegisteredPlugins.insert(pluginName, pluginPath);
84 }
84 }
85 else {
85 else {
86 loadState.setError(QObject::tr("the file is not a Sciqlop plugin"));
86 loadState.setError(QObject::tr("the file is not a Sciqlop plugin"));
87 }
87 }
88 }
88 }
89 }
89 }
90 else {
90 else {
91 loadState.setError(QObject::tr("the file is not a library"));
91 loadState.setError(QObject::tr("the file is not a library"));
92 }
92 }
93
93
94 // Log loading result
94 // Log loading result
95 loadState.log();
95 loadState.log();
96 }
96 }
97
97
98 /// Registered plugins (key: plugin name, value: plugin path)
98 /// Registered plugins (key: plugin name, value: plugin path)
99 QHash<QString, QString> m_RegisteredPlugins;
99 QHash<QString, QString> m_RegisteredPlugins;
100 };
100 };
101
101
102 PluginManager::PluginManager() : impl{spimpl::make_unique_impl<PluginManagerPrivate>()}
102 PluginManager::PluginManager() : impl{spimpl::make_unique_impl<PluginManagerPrivate>()}
103 {
103 {
104 }
104 }
105
105
106 void PluginManager::loadPlugins(const QDir &pluginDir)
106 void PluginManager::loadPlugins(const QDir &pluginDir)
107 {
107 {
108 // Load plugins
108 // Load plugins
109 auto pluginInfoList = pluginDir.entryInfoList(QDir::Files, QDir::Name);
109 auto pluginInfoList = pluginDir.entryInfoList(QDir::Files, QDir::Name);
110 for (auto pluginInfo : qAsConst(pluginInfoList)) {
110 for (auto pluginInfo : qAsConst(pluginInfoList)) {
111 impl->loadPlugin(pluginInfo.absoluteFilePath());
111 impl->loadPlugin(pluginInfo.absoluteFilePath());
112 }
112 }
113 }
113 }
114
114
115 int PluginManager::nbPluginsLoaded() const noexcept
115 int PluginManager::nbPluginsLoaded() const noexcept
116 {
116 {
117 /// @todo ALX
117 return impl->m_RegisteredPlugins.size();
118 return 0;
119 }
118 }
General Comments 5
Under Review
author

Pull request updated. Auto status change to "Under Review"

Changed commits:
  * 1 added
  * 0 removed

Changed files:
  * M core/CMakeLists.txt
Approved
author

Status change > Approved

You need to be logged in to leave comments. Login now