aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/qml/qqmlimport.cpp
diff options
context:
space:
mode:
authorRichard Moe Gustavsen <richard.gustavsen@digia.com>2014-03-11 12:51:15 +0100
committerThe Qt Project <gerrit-noreply@qt-project.org>2014-03-13 10:21:42 +0100
commit6e1851de9595d7e7abe9acdc8c473e792d24c4c2 (patch)
tree9c5e4d2b6b36208b52e2bf7219c870d1c156fcee /src/qml/qml/qqmlimport.cpp
parentb244fc002d4fb97abb8647ed07f6e927cf3de789 (diff)
Static plugins: support loading static plugins from several engines
When loading dynamic plugins, we register them as loaded so that we don't try to register their types several times if using several engines. The same was not done for static plugins. This patch will ensure that we follow the same logic also for static plugins. Task-number: QTBUG-36532 Change-Id: Icc1e089ae5d682c38b2d36bf4808f1c753c122a4 Reviewed-by: Simon Hausmann <simon.hausmann@digia.com> Reviewed-by: Lars Knoll <lars.knoll@digia.com>
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;
}