diff options
Diffstat (limited to 'src/qml/qml/qqmlimport.cpp')
-rw-r--r-- | src/qml/qml/qqmlimport.cpp | 64 |
1 files changed, 52 insertions, 12 deletions
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; } |