aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/qml/qml/qqmlengine.cpp2
-rw-r--r--src/qml/qml/qqmlimport.cpp64
-rw-r--r--src/qml/qml/qqmlimport_p.h8
3 files changed, 58 insertions, 16 deletions
diff --git a/src/qml/qml/qqmlengine.cpp b/src/qml/qml/qqmlengine.cpp
index 72de9845c8..d927a8c628 100644
--- a/src/qml/qml/qqmlengine.cpp
+++ b/src/qml/qml/qqmlengine.cpp
@@ -1983,7 +1983,7 @@ void QQmlEngine::setPluginPathList(const QStringList &paths)
bool QQmlEngine::importPlugin(const QString &filePath, const QString &uri, QList<QQmlError> *errors)
{
Q_D(QQmlEngine);
- return d->importDatabase.importPlugin(filePath, uri, QString(), errors);
+ return d->importDatabase.importDynamicPlugin(filePath, uri, QString(), errors);
}
/*!
diff --git a/src/qml/qml/qqmlimport.cpp b/src/qml/qml/qqmlimport.cpp
index 97f82a2e8d..cae8365598 100644
--- a/src/qml/qml/qqmlimport.cpp
+++ b/src/qml/qml/qqmlimport.cpp
@@ -191,7 +191,7 @@ void qmlClearEnginePlugins()
QMutexLocker lock(&plugins->mutex);
foreach (RegisteredPlugin plugin, plugins->values()) {
QPluginLoader* loader = plugin.loader;
- if (!loader->unload())
+ if (loader && !loader->unload())
qWarning("Unloading %s failed: %s", qPrintable(plugin.uri), qPrintable(loader->errorString()));
delete loader;
}
@@ -911,7 +911,7 @@ bool QQmlImportsPrivate::importExtension(const QString &qmldirFilePath,
QString resolvedFilePath = database->resolvePlugin(typeLoader, qmldirPath, plugin.path, plugin.name);
if (!resolvedFilePath.isEmpty()) {
dynamicPluginsFound++;
- if (!database->importPlugin(resolvedFilePath, uri, typeNamespace, errors)) {
+ if (!database->importDynamicPlugin(resolvedFilePath, uri, typeNamespace, errors)) {
if (errors) {
// XXX TODO: should we leave the import plugin error alone?
// Here, we pop it off the top and coalesce it into this error's message.
@@ -947,7 +947,7 @@ bool QQmlImportsPrivate::importExtension(const QString &qmldirFilePath,
if (versionUri == metaTagUri.toString()) {
staticPluginsFound++;
QObject *instance = pair.first.instance();
- if (!database->importPlugin(instance, basePath, uri, typeNamespace, true, errors)) {
+ if (!database->importStaticPlugin(instance, basePath, uri, typeNamespace, errors)) {
if (errors) {
QQmlError poppedError = errors->takeFirst();
QQmlError error;
@@ -1820,12 +1820,11 @@ void QQmlImportDatabase::setImportPathList(const QStringList &paths)
/*!
\internal
*/
-bool QQmlImportDatabase::importPlugin(QObject *instance, const QString &basePath,
- const QString &uri, const QString &typeNamespace,
- bool initEngine, QList<QQmlError> *errors)
+bool QQmlImportDatabase::registerPluginTypes(QObject *instance, const QString &basePath,
+ const QString &uri, const QString &typeNamespace, QList<QQmlError> *errors)
{
if (qmlImportTrace())
- qDebug().nospace() << "QQmlImportDatabase::importPluginInstance: " << uri << " from " << basePath;
+ qDebug().nospace() << "QQmlImportDatabase::registerPluginTypes: " << uri << " from " << basePath;
QQmlTypesExtensionInterface *iface = qobject_cast<QQmlTypesExtensionInterface *>(instance);
if (!iface) {
@@ -1894,20 +1893,61 @@ bool QQmlImportDatabase::importPlugin(QObject *instance, const QString &basePath
return false;
}
- if (initEngine) {
+ return true;
+}
+
+/*!
+ \internal
+*/
+bool QQmlImportDatabase::importStaticPlugin(QObject *instance, const QString &basePath,
+ const QString &uri, const QString &typeNamespace, QList<QQmlError> *errors)
+{
+#ifndef QT_NO_LIBRARY
+ // Dynamic plugins are differentiated by their filepath. For static plugins we
+ // don't have that information so we use their address as key instead.
+ QString uniquePluginID = QString().sprintf("%p", instance);
+ StringRegisteredPluginMap *plugins = qmlEnginePluginsWithRegisteredTypes();
+ QMutexLocker lock(&plugins->mutex);
+
+ // Plugin types are global across all engines and should only be
+ // registered once. But each engine still needs to be initialized.
+ bool typesRegistered = plugins->contains(uniquePluginID);
+ bool engineInitialized = initializedPlugins.contains(uniquePluginID);
+
+ if (typesRegistered) {
+ Q_ASSERT_X(plugins->value(uniquePluginID).uri == uri,
+ "QQmlImportDatabase::importStaticPlugin",
+ "Internal error: Static plugin imported previously with different uri");
+ } else {
+ RegisteredPlugin plugin;
+ plugin.uri = uri;
+ plugin.loader = 0;
+ plugins->insert(uniquePluginID, plugin);
+
+ if (!registerPluginTypes(instance, basePath, uri, typeNamespace, errors))
+ return false;
+ }
+
+ if (!engineInitialized) {
+ initializedPlugins.insert(uniquePluginID);
+
if (QQmlExtensionInterface *eiface = qobject_cast<QQmlExtensionInterface *>(instance)) {
QQmlEnginePrivate *ep = QQmlEnginePrivate::get(engine);
- ep->typeLoader.initializeEngine(eiface, moduleId);
+ ep->typeLoader.initializeEngine(eiface, uri.toUtf8().constData());
}
}
return true;
+#else
+ return false;
+#endif
}
/*!
\internal
*/
-bool QQmlImportDatabase::importPlugin(const QString &filePath, const QString &uri, const QString &typeNamespace, QList<QQmlError> *errors)
+bool QQmlImportDatabase::importDynamicPlugin(const QString &filePath, const QString &uri,
+ const QString &typeNamespace, QList<QQmlError> *errors)
{
#ifndef QT_NO_LIBRARY
QFileInfo fileInfo(filePath);
@@ -1920,7 +1960,7 @@ bool QQmlImportDatabase::importPlugin(const QString &filePath, const QString &ur
if (typesRegistered) {
Q_ASSERT_X(plugins->value(absoluteFilePath).uri == uri,
- "QQmlImportDatabase::importPlugin",
+ "QQmlImportDatabase::importDynamicPlugin",
"Internal error: Plugin imported previously with different uri");
}
@@ -1961,7 +2001,7 @@ bool QQmlImportDatabase::importPlugin(const QString &filePath, const QString &ur
plugins->insert(absoluteFilePath, plugin);
// Continue with shared code path for dynamic and static plugins:
- if (!importPlugin(instance, fileInfo.absolutePath(), uri, typeNamespace, false, errors))
+ if (!registerPluginTypes(instance, fileInfo.absolutePath(), uri, typeNamespace, errors))
return false;
}
diff --git a/src/qml/qml/qqmlimport_p.h b/src/qml/qml/qqmlimport_p.h
index f19f5d4f34..b19e777852 100644
--- a/src/qml/qml/qqmlimport_p.h
+++ b/src/qml/qml/qqmlimport_p.h
@@ -151,7 +151,7 @@ public:
QQmlImportDatabase(QQmlEngine *);
~QQmlImportDatabase();
- bool importPlugin(const QString &filePath, const QString &uri, const QString &importNamespace, QList<QQmlError> *errors);
+ bool importDynamicPlugin(const QString &filePath, const QString &uri, const QString &importNamespace, QList<QQmlError> *errors);
QStringList importPathList(PathType type = LocalOrRemote) const;
void setImportPathList(const QStringList &paths);
@@ -170,8 +170,10 @@ private:
QString resolvePlugin(QQmlTypeLoader *typeLoader,
const QString &qmldirPath, const QString &qmldirPluginPath,
const QString &baseName);
- bool importPlugin(QObject *instance, const QString &basePath, const QString &uri,
- const QString &typeNamespace, bool initEngine, QList<QQmlError> *errors);
+ bool importStaticPlugin(QObject *instance, const QString &basePath, const QString &uri,
+ const QString &typeNamespace, QList<QQmlError> *errors);
+ bool registerPluginTypes(QObject *instance, const QString &basePath,
+ const QString &uri, const QString &typeNamespace, QList<QQmlError> *errors);
struct QmldirCache {
int versionMajor;