This repository was archived by the owner on Mar 4, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathqpluginfactory.h
161 lines (124 loc) · 4.46 KB
/
qpluginfactory.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
#ifndef QPLUGINFACTORY_H
#define QPLUGINFACTORY_H
#include <QtCore/QDir>
#include <QtCore/QObject>
#include <QtCore/QPluginLoader>
#include <QtCore/QMutex>
#include <qexceptionbase.h>
#if QT_CONFIG(library)
class Q_PLUGIN_FACTORY_EXPORT QPluginLoadException : public QExceptionBase
{
public:
QPluginLoadException(QPluginLoader *loader);
const char *what() const noexcept override;
void raise() const override;
Base *clone() const override;
private:
const QByteArray _what;
};
#else
//dummy class
class Q_PLUGIN_FACTORY_EXPORT QPluginLoadException : public QExceptionBase {};
#endif
#ifdef QT_NO_DEBUG
#define Q_PLUGIN_FACTORY_IS_DEBUG false
#else
#define Q_PLUGIN_FACTORY_IS_DEBUG true
#endif
class Q_PLUGIN_FACTORY_EXPORT QPluginFactoryBase : public QObject
{
Q_OBJECT
Q_PROPERTY(QString pluginType READ pluginType CONSTANT)
Q_PROPERTY(QByteArray pluginIid READ pluginIid WRITE setPluginIid)
public:
class Q_PLUGIN_FACTORY_EXPORT PluginInfo {
Q_DISABLE_COPY(PluginInfo)
public:
inline PluginInfo() = default;
virtual inline ~PluginInfo() = default;
virtual QJsonObject metaData() const = 0;
virtual QObject *instance() = 0;
virtual bool isLoaded() const = 0;
virtual void unload(const QString &key) = 0;
};
QPluginFactoryBase(QString pluginType, QObject *parent = nullptr, bool isDebugBuild = Q_PLUGIN_FACTORY_IS_DEBUG);
QPluginFactoryBase(QString pluginType, QByteArray pluginIid, QObject *parent = nullptr, bool isDebugBuild = Q_PLUGIN_FACTORY_IS_DEBUG);
void addSearchDir(const QDir &dir, bool isTopLevel = false);
QStringList allKeys() const;
QJsonObject metaData(const QString &key) const;
QObject *plugin(const QString &key) const;
QString pluginType() const;
QByteArray pluginIid() const;
public Q_SLOTS:
virtual void setPluginIid(const QByteArray &pluginIid);
void reloadPlugins();
protected:
bool isLoaded(const QString &key) const;
void unload(const QString &key);
private:
const bool _isDebugBuild;
const QString _pluginType;
QByteArray _pluginIid;
QList<QDir> _extraDirs;
mutable QMutex _loaderMutex;
QHash<QString, QSharedPointer<PluginInfo>> _plugins;
QJsonArray checkMeta(const QJsonObject &metaData, const QString &filename) const;
};
template <typename TPlugin>
class QPluginFactory : public QPluginFactoryBase
{
public:
QPluginFactory(const QString &pluginType, QObject *parent = nullptr);
TPlugin *plugin(const QString &key) const;
QObject *pluginObj(const QString &key) const;
void setPluginIid(const QByteArray &) override;
};
template <typename TPlugin, typename TObject>
class QPluginObjectFactory : public QPluginFactory<TPlugin>
{
public:
QPluginObjectFactory(const QString &pluginType, QObject *parent = nullptr);
template <typename... Args>
TObject *createInstance(const QString &key, Args... args) const;
};
//single-line loader method
// ------------- Template Implementations -------------
template<typename TPlugin>
QPluginFactory<TPlugin>::QPluginFactory(const QString &pluginType, QObject *parent) :
QPluginFactoryBase(pluginType, qobject_interface_iid<TPlugin*>(), parent)
{}
template<typename TPlugin>
TPlugin *QPluginFactory<TPlugin>::plugin(const QString &key) const
{
return qobject_cast<TPlugin*>(QPluginFactoryBase::plugin(key));
}
template<typename TPlugin>
QObject *QPluginFactory<TPlugin>::pluginObj(const QString &key) const
{
return QPluginFactoryBase::plugin(key);
}
template<typename TPlugin>
void QPluginFactory<TPlugin>::setPluginIid(const QByteArray &) {}
template<typename TPlugin, typename TObject>
QPluginObjectFactory<TPlugin, TObject>::QPluginObjectFactory(const QString &pluginType, QObject *parent) :
QPluginFactory<TPlugin>(pluginType, parent)
{}
template<typename TPlugin, typename TObject>
template<typename... Args>
TObject *QPluginObjectFactory<TPlugin, TObject>::createInstance(const QString &key, Args... args) const
{
auto plg = this->plugin(key);
if(plg)
return plg->createInstance(key, args...);
else
return nullptr;
}
#define Q_GLOBAL_PLUGIN_FACTORY(PluginType, pluginKey, instName) namespace { \
typedef QPluginFactory<PluginType> __QGPF_ ## PluginType ## _Factory; \
Q_GLOBAL_STATIC_WITH_ARGS(__QGPF_ ## PluginType ## _Factory, instName, (QString::fromUtf8(pluginKey))) \
}
#define Q_GLOBAL_PLUGIN_OBJECT_FACTORY(PluginType, ObjectType, pluginKey, instName) namespace { \
typedef QPluginObjectFactory<PluginType, ObjectType> __QGPF_ ## PluginType ## _Factory; \
Q_GLOBAL_STATIC_WITH_ARGS(__QGPF_ ## PluginType ## _Factory, instName, (QString::fromUtf8(pluginKey))) \
}
#endif // QPLUGINFACTORY_H