7
7
8
8
extern bool __qpluginfactory_is_debug ();
9
9
10
+ class StaticPluginInfo : public QPluginFactoryBase ::PluginInfo
11
+ {
12
+ public:
13
+ StaticPluginInfo (const QStaticPlugin &plugin);
14
+
15
+ QJsonObject metaData () const override ;
16
+ QObject *instance () override ;
17
+
18
+ private:
19
+ QStaticPlugin _plugin;
20
+ };
21
+
22
+ class DynamicPluginInfo : public QPluginFactoryBase ::PluginInfo
23
+ {
24
+ public:
25
+ DynamicPluginInfo (QScopedPointer<QPluginLoader, QScopedPointerDeleteLater> &loader);
26
+
27
+ QJsonObject metaData () const override ;
28
+ QObject *instance () override ;
29
+
30
+ private:
31
+ QScopedPointer<QPluginLoader, QScopedPointerDeleteLater> _loader;
32
+ };
33
+
34
+
35
+
10
36
QPluginFactoryBase::QPluginFactoryBase (const QString &pluginType, QObject *parent) :
11
37
QPluginFactoryBase(pluginType, QByteArray(), parent)
12
38
{}
@@ -17,8 +43,9 @@ QPluginFactoryBase::QPluginFactoryBase(const QString &pluginType, const QByteArr
17
43
_pluginIid(pluginIid),
18
44
_extraDirs(),
19
45
_loaderMutex(),
20
- _loaders ()
46
+ _plugins ()
21
47
{
48
+ // setup dynamic plugins
22
49
reloadPlugins ();
23
50
}
24
51
@@ -35,28 +62,26 @@ void QPluginFactoryBase::addSearchDir(const QDir &dir, bool isTopLevel)
35
62
QStringList QPluginFactoryBase::allKeys () const
36
63
{
37
64
QMutexLocker _ (&_loaderMutex);
38
- return _loaders .keys ();
65
+ return _plugins .keys ();
39
66
}
40
67
41
68
QJsonObject QPluginFactoryBase::metaData (const QString &key) const
42
69
{
43
70
QMutexLocker _ (&_loaderMutex);
44
- auto loader = _loaders .value (key);
45
- if (loader )
46
- return loader ->metaData ()[QStringLiteral (" MetaData" )].toObject ();
71
+ auto info = _plugins .value (key);
72
+ if (info )
73
+ return info ->metaData ()[QStringLiteral (" MetaData" )].toObject ();
47
74
else
48
75
return {};
49
76
}
50
77
51
78
QObject *QPluginFactoryBase::plugin (const QString &key) const
52
79
{
53
80
QMutexLocker _ (&_loaderMutex);
54
- auto loader = _loaders.value (key);
55
- if (loader) {
56
- if (!loader->isLoaded () && !loader->load ())
57
- throw QPluginLoadException (loader);
58
- return loader->instance ();
59
- } else
81
+ auto info = _plugins.value (key);
82
+ if (info)
83
+ return info->instance ();
84
+ else
60
85
return nullptr ;
61
86
}
62
87
@@ -81,7 +106,7 @@ void QPluginFactoryBase::reloadPlugins()
81
106
QMutexLocker _ (&_loaderMutex);
82
107
83
108
// find the plugin dir
84
- auto oldKeys = _loaders .keys ();
109
+ auto oldKeys = _plugins .keys ();
85
110
86
111
QList<QDir> allDirs;
87
112
// first: dirs in path
@@ -107,45 +132,61 @@ void QPluginFactoryBase::reloadPlugins()
107
132
if (pluginMainDir.cd (_pluginType))
108
133
allDirs.append (pluginMainDir);
109
134
135
+ // setup dynamic plugins
110
136
foreach (auto pluginDir, allDirs) {
111
137
foreach (auto info, pluginDir.entryInfoList (QDir::Files | QDir::Readable | QDir::Executable | QDir::NoDotAndDotDot)) {
112
- QSharedPointer<QPluginLoader> plugin (new QPluginLoader (info.absoluteFilePath ()), &QObject::deleteLater);
113
- auto metaData = plugin->metaData ();
114
-
115
- // skip non-matching types
116
- if (metaData[QStringLiteral (" debug" )].toBool () != __qpluginfactory_is_debug ())
117
- continue ;
118
-
119
- auto iid = plugin->metaData ().value (QStringLiteral (" IID" )).toString ().toUtf8 ();
120
- if (!_pluginIid.isNull () && iid != _pluginIid) {
121
- qWarning ().noquote () << " File" << plugin->fileName () << " is no plugin of type" << _pluginIid;
122
- continue ;
123
- }
124
-
125
- auto data = metaData[QStringLiteral (" MetaData" )].toObject ();
126
- auto keys = data[QStringLiteral (" Keys" )].toArray ();
127
- if (keys.isEmpty ()) {
128
- qWarning ().noquote () << " Plugin" << plugin->fileName () << " is does not provide any Keys" ;
129
- continue ;
130
- }
131
-
138
+ QScopedPointer<QPluginLoader, QScopedPointerDeleteLater> loader (new QPluginLoader (info.absoluteFilePath ()));
139
+ auto metaData = loader->metaData ();
140
+ auto keys = checkMeta (metaData, loader->fileName ());
132
141
foreach (auto key, keys) {
133
142
auto k = key.toString ();
134
- if (!_loaders .contains (k))
135
- _loaders .insert (k, plugin );
143
+ if (!_plugins .contains (k))
144
+ _plugins .insert (k, QSharedPointer<DynamicPluginInfo>:: create (loader) );
136
145
oldKeys.removeOne (k);
137
146
}
147
+ }
148
+ }
138
149
150
+ // setup static plugins
151
+ foreach (auto info, QPluginLoader::staticPlugins ()) {
152
+ auto keys = checkMeta (info.metaData (), QString ());
153
+ foreach (auto key, keys) {
154
+ auto k = key.toString ();
155
+ if (!_plugins.contains (k))
156
+ _plugins.insert (k, QSharedPointer<StaticPluginInfo>::create (info));
157
+ oldKeys.removeOne (k);
139
158
}
140
159
}
141
160
161
+ // remove old, now unused plugins
142
162
foreach (auto key, oldKeys)
143
- _loaders .remove (key);
163
+ _plugins .remove (key);
144
164
}
145
165
166
+ QJsonArray QPluginFactoryBase::checkMeta (const QJsonObject &metaData, const QString &filename) const
167
+ {
168
+ if (metaData[QStringLiteral (" debug" )].toBool () != __qpluginfactory_is_debug ())
169
+ return {};
146
170
171
+ auto iid = metaData.value (QStringLiteral (" IID" )).toString ().toUtf8 ();
172
+ if (!_pluginIid.isNull () && iid != _pluginIid) {
173
+ qWarning ().noquote () << " File" << filename << " is no plugin of type" << _pluginIid;
174
+ return {};
175
+ }
147
176
148
- QPluginLoadException::QPluginLoadException (QSharedPointer<QPluginLoader> loader) :
177
+ auto data = metaData[QStringLiteral (" MetaData" )].toObject ();
178
+ auto keys = data[QStringLiteral (" Keys" )].toArray ();
179
+ if (keys.isEmpty ()) {
180
+ qWarning ().noquote () << " Plugin" << filename << " is does not provide any Keys" ;
181
+ return {};
182
+ }
183
+
184
+ return keys;
185
+ }
186
+
187
+
188
+
189
+ QPluginLoadException::QPluginLoadException (QPluginLoader *loader) :
149
190
QPluginLoadException(QStringLiteral(" Failed to load plugin \" %1\" with error: %2" )
150
191
.arg(loader->fileName ())
151
192
.arg(loader->errorString ())
@@ -171,3 +212,37 @@ QPluginLoadException::QPluginLoadException(const QByteArray &error) :
171
212
QException(),
172
213
_what(error)
173
214
{}
215
+
216
+
217
+
218
+ StaticPluginInfo::StaticPluginInfo (const QStaticPlugin &plugin) :
219
+ _plugin(plugin)
220
+ {}
221
+
222
+ QJsonObject StaticPluginInfo::metaData () const
223
+ {
224
+ return _plugin.metaData ();
225
+ }
226
+
227
+ QObject *StaticPluginInfo::instance ()
228
+ {
229
+ return _plugin.instance ();
230
+ }
231
+
232
+ DynamicPluginInfo::DynamicPluginInfo (QScopedPointer<QPluginLoader, QScopedPointerDeleteLater> &loader) :
233
+ _loader()
234
+ {
235
+ _loader.swap (loader);
236
+ }
237
+
238
+ QJsonObject DynamicPluginInfo::metaData () const
239
+ {
240
+ return _loader->metaData ();
241
+ }
242
+
243
+ QObject *DynamicPluginInfo::instance ()
244
+ {
245
+ if (!_loader->isLoaded () && !_loader->load ())
246
+ throw QPluginLoadException (_loader.data ());
247
+ return _loader->instance ();
248
+ }
0 commit comments