aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml
diff options
context:
space:
mode:
authorAlan Alpert <aalpert@rim.com>2013-01-24 14:07:29 -0800
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-05-07 19:41:28 +0200
commit9b5a55101d7c519446c1cf3706a235dea81ad4de (patch)
tree8f7201f04f8e593c8e00fd4d293d2d28e1a655ab /src/qml
parent223313479bf8ec80158ba0f6cba4dd5e74d92718 (diff)
Add qmlClearRegisteredTypes Function
Registered types are stored in a global static variable, not on an engine instance. For applications managing multiple engines over their lifetime, there needs to be a way to clear the existing types so they can register new ones and avoid memory leaks. Task-Number: QTBUG-28572 Change-Id: Ic70a4dd1e29d99399b21fb42eaf10d4a52bf2adf Reviewed-by: Christopher Adams <chris.adams@jollamobile.com>
Diffstat (limited to 'src/qml')
-rw-r--r--src/qml/doc/src/qmlfunctions.qdoc14
-rw-r--r--src/qml/qml/qqml.h2
-rw-r--r--src/qml/qml/qqmlengine.cpp6
-rw-r--r--src/qml/qml/qqmlengine_p.h3
-rw-r--r--src/qml/qml/qqmlimport.cpp8
-rw-r--r--src/qml/qml/qqmlimport_p.h2
-rw-r--r--src/qml/qml/qqmlmetatype.cpp24
-rw-r--r--src/qml/qml/qqmlmetatype_p.h2
8 files changed, 58 insertions, 3 deletions
diff --git a/src/qml/doc/src/qmlfunctions.qdoc b/src/qml/doc/src/qmlfunctions.qdoc
index 976403adea..386f9f49df 100644
--- a/src/qml/doc/src/qmlfunctions.qdoc
+++ b/src/qml/doc/src/qmlfunctions.qdoc
@@ -47,6 +47,20 @@
#include <QtQml> to use this macro.
*/
+/*!
+ \fn void qmlClearTypeRegistrations()
+ \relates QQmlEngine
+
+ Clears all stored type registrations, such as those produced with \l qmlRegisterType.
+
+ Do not call this function while a QQmlEngine exists or behavior will be undefined.
+ Any existing QQmlEngines must be deleted before calling this function. This function
+ only affects the application global cache. Delete the QQmlEngine to clear all cached
+ data relating to that engine.
+
+ #include <QtQml> to use this method.
+*/
+
/*!
\fn int qmlRegisterType(const char *uri, int versionMajor, int versionMinor, const char *qmlName)
diff --git a/src/qml/qml/qqml.h b/src/qml/qml/qqml.h
index 7e6e0d1d36..f04cf7d6fa 100644
--- a/src/qml/qml/qqml.h
+++ b/src/qml/qml/qqml.h
@@ -102,6 +102,8 @@ class QQmlPropertyValueInterceptor;
listName[listLen+nameLen] = '>'; \
listName[listLen+nameLen+1] = '\0';
+void Q_QML_EXPORT qmlClearTypeRegistrations();
+
template<typename T>
int qmlRegisterType()
{
diff --git a/src/qml/qml/qqmlengine.cpp b/src/qml/qml/qqmlengine.cpp
index 9d2ad8c4c3..34ebe0a9e2 100644
--- a/src/qml/qml/qqmlengine.cpp
+++ b/src/qml/qml/qqmlengine.cpp
@@ -722,17 +722,17 @@ void QQmlData::flushPendingBindingImpl(int coreIndex)
}
}
+bool QQmlEnginePrivate::baseModulesUninitialized = true;
void QQmlEnginePrivate::init()
{
Q_Q(QQmlEngine);
- static bool firstTime = true;
- if (firstTime) {
+ if (baseModulesUninitialized) {
qmlRegisterType<QQmlComponent>("QML", 1, 0, "Component"); // required for the Compiler.
registerBaseTypes("QtQml", 2, 0); // import which provides language building blocks.
QQmlData::init();
- firstTime = false;
+ baseModulesUninitialized = false;
}
qRegisterMetaType<QVariant>();
diff --git a/src/qml/qml/qqmlengine_p.h b/src/qml/qml/qqmlengine_p.h
index b745d6a963..0d852c1c1b 100644
--- a/src/qml/qml/qqmlengine_p.h
+++ b/src/qml/qml/qqmlengine_p.h
@@ -125,6 +125,9 @@ public:
~QQmlEnginePrivate();
void init();
+ // No mutex protecting baseModulesUninitialized, because use outside QQmlEngine
+ // is just qmlClearTypeRegistrations (which can't be called while an engine exists)
+ static bool baseModulesUninitialized;
class PropertyCapture {
public:
diff --git a/src/qml/qml/qqmlimport.cpp b/src/qml/qml/qqmlimport.cpp
index f793ca9604..2fbb614605 100644
--- a/src/qml/qml/qqmlimport.cpp
+++ b/src/qml/qml/qqmlimport.cpp
@@ -163,6 +163,14 @@ QQmlType *getTypeForUrl(const QString &urlString, const QHashedStringRef& typeNa
typedef QMap<QString, QString> StringStringMap;
Q_GLOBAL_STATIC(StringStringMap, qmlEnginePluginsWithRegisteredTypes); // stores the uri
+void qmlClearEnginePlugins()
+{
+ foreach (const QString &s, qmlEnginePluginsWithRegisteredTypes()->values()) {
+ QPluginLoader loader(s);
+ loader.unload(); // ### Always returns false, worth doing?
+ }
+ qmlEnginePluginsWithRegisteredTypes()->clear();
+}
class QQmlImportNamespace
{
diff --git a/src/qml/qml/qqmlimport_p.h b/src/qml/qml/qqmlimport_p.h
index 140ca6695e..06b50c09e9 100644
--- a/src/qml/qml/qqmlimport_p.h
+++ b/src/qml/qml/qqmlimport_p.h
@@ -182,6 +182,8 @@ private:
QQmlEngine *engine;
};
+void qmlClearEnginePlugins();// For internal use by qmlClearRegisteredProperties
+
QT_END_NAMESPACE
#endif // QQMLIMPORT_P_H
diff --git a/src/qml/qml/qqmlmetatype.cpp b/src/qml/qml/qqmlmetatype.cpp
index 0f3a27aeff..b29df4d252 100644
--- a/src/qml/qml/qqmlmetatype.cpp
+++ b/src/qml/qml/qqmlmetatype.cpp
@@ -46,6 +46,7 @@
#include <private/qqmlcustomparser_p.h>
#include <private/qqmlguard_p.h>
#include <private/qhashedstring_p.h>
+#include <private/qqmlimport_p.h>
#include <QtCore/qdebug.h>
#include <QtCore/qstringlist.h>
@@ -1068,6 +1069,29 @@ QQmlType *QQmlTypeModuleVersion::type(const QHashedV8String &name) const
else return 0;
}
+void qmlClearTypeRegistrations() // Declared in qqml.h
+{
+ //Only cleans global static, assumed no running engine
+ QWriteLocker lock(metaTypeDataLock());
+ QQmlMetaTypeData *data = metaTypeData();
+
+ for (int i = 0; i < data->types.count(); ++i)
+ delete data->types.at(i);
+
+ QQmlMetaTypeData::TypeModules::const_iterator i = data->uriToModule.constBegin();
+ for (; i != data->uriToModule.constEnd(); ++i)
+ delete *i;
+
+ data->types.clear();
+ data->idToType.clear();
+ data->nameToType.clear();
+ data->urlToType.clear();
+ data->metaObjectToType.clear();
+ data->uriToModule.clear();
+
+ QQmlEnginePrivate::baseModulesUninitialized = true; //So the engine re-registers its types
+ qmlClearEnginePlugins();
+}
int registerAutoParentFunction(QQmlPrivate::RegisterAutoParent &autoparent)
{
diff --git a/src/qml/qml/qqmlmetatype_p.h b/src/qml/qml/qqmlmetatype_p.h
index 497afffb5d..12901e8c58 100644
--- a/src/qml/qml/qqmlmetatype_p.h
+++ b/src/qml/qml/qqmlmetatype_p.h
@@ -231,6 +231,7 @@ private:
friend int registerSingletonType(const QQmlPrivate::RegisterSingletonType &);
friend int registerInterface(const QQmlPrivate::RegisterInterface &);
friend int registerCompositeType(const QQmlPrivate::RegisterCompositeType &);
+ friend void qmlClearTypeRegistrations();
QQmlType(int, const QQmlPrivate::RegisterInterface &);
QQmlType(int, const QString &, const QQmlPrivate::RegisterSingletonType &);
QQmlType(int, const QString &, const QQmlPrivate::RegisterType &);
@@ -259,6 +260,7 @@ private:
//Used by register functions and creates the QQmlTypeModule for them
friend void addTypeToData(QQmlType* type, QQmlMetaTypeData *data);
friend struct QQmlMetaTypeData;
+ friend void qmlClearTypeRegistrations();
QQmlTypeModule();
~QQmlTypeModule();