aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/qml/qqmlimport.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/qml/qml/qqmlimport.cpp')
-rw-r--r--src/qml/qml/qqmlimport.cpp64
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;
}