Add qmlClearRegisteredTypes Function
authorAlan Alpert <aalpert@rim.com>
Thu, 24 Jan 2013 22:07:29 +0000 (14:07 -0800)
committerThe Qt Project <gerrit-noreply@qt-project.org>
Tue, 7 May 2013 17:41:28 +0000 (19:41 +0200)
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>
20 files changed:
src/qml/doc/src/qmlfunctions.qdoc
src/qml/qml/qqml.h
src/qml/qml/qqmlengine.cpp
src/qml/qml/qqmlengine_p.h
src/qml/qml/qqmlimport.cpp
src/qml/qml/qqmlimport_p.h
src/qml/qml/qqmlmetatype.cpp
src/qml/qml/qqmlmetatype_p.h
tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp
tests/manual/qmltypememory/README [new file with mode: 0644]
tests/manual/qmltypememory/TestPlugin/plugin.cpp [new file with mode: 0644]
tests/manual/qmltypememory/TestPlugin/plugin.pro [new file with mode: 0644]
tests/manual/qmltypememory/TestPlugin/qmldir [new file with mode: 0644]
tests/manual/qmltypememory/TestType.qml [new file with mode: 0644]
tests/manual/qmltypememory/main.cpp [new file with mode: 0644]
tests/manual/qmltypememory/main.qml [new file with mode: 0644]
tests/manual/qmltypememory/qmldir [new file with mode: 0644]
tests/manual/qmltypememory/qmltypememory.pro [new file with mode: 0644]
tests/manual/qmltypememory/testdriver.cpp [new file with mode: 0644]
tests/manual/qmltypememory/testdriver.h [new file with mode: 0644]

index 976403a..386f9f4 100644 (file)
   #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)
index 7e6e0d1..f04cf7d 100644 (file)
@@ -102,6 +102,8 @@ class QQmlPropertyValueInterceptor;
     listName[listLen+nameLen] = '>'; \
     listName[listLen+nameLen+1] = '\0';
 
+void Q_QML_EXPORT qmlClearTypeRegistrations();
+
 template<typename T>
 int qmlRegisterType()
 {
index 9d2ad8c..34ebe0a 100644 (file)
@@ -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>();
index b745d6a..0d852c1 100644 (file)
@@ -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:
index f793ca9..2fbb614 100644 (file)
@@ -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
 {
index 140ca66..06b50c0 100644 (file)
@@ -182,6 +182,8 @@ private:
     QQmlEngine *engine;
 };
 
+void qmlClearEnginePlugins();// For internal use by qmlClearRegisteredProperties
+
 QT_END_NAMESPACE
 
 #endif // QQMLIMPORT_P_H
index 0f3a27a..b29df4d 100644 (file)
@@ -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)
 {
index 497afff..12901e8 100644 (file)
@@ -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();
index 5a924a9..47a9f39 100644 (file)
@@ -242,6 +242,7 @@ private:
 void tst_qqmllanguage::cleanupTestCase()
 {
     QVERIFY(QFile::remove(testFile(QString::fromUtf8("I18nType\303\201\303\242\303\243\303\244\303\245.qml"))));
+    qmlClearTypeRegistrations(); // Should not crash
 }
 
 void tst_qqmllanguage::insertedSemicolon_data()
diff --git a/tests/manual/qmltypememory/README b/tests/manual/qmltypememory/README
new file mode 100644 (file)
index 0000000..b1237a1
--- /dev/null
@@ -0,0 +1,3 @@
+This test just continually builds up and tears down a QML scene. Watch over a long period to see if the memory usage goes up.
+
+This test specifically is targeting the QQmlType cache which is a global static.
diff --git a/tests/manual/qmltypememory/TestPlugin/plugin.cpp b/tests/manual/qmltypememory/TestPlugin/plugin.cpp
new file mode 100644 (file)
index 0000000..40c2af2
--- /dev/null
@@ -0,0 +1,63 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Research In Motion.
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the tests of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+**   * Redistributions of source code must retain the above copyright
+**     notice, this list of conditions and the following disclaimer.
+**   * Redistributions in binary form must reproduce the above copyright
+**     notice, this list of conditions and the following disclaimer in
+**     the documentation and/or other materials provided with the
+**     distribution.
+**   * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
+**     of its contributors may be used to endorse or promote products derived
+**     from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtQml/QQmlExtensionPlugin>
+#include <QtQml/qqml.h>
+#include <qdebug.h>
+
+class TestType : public QObject
+{
+    Q_OBJECT
+};
+
+class TestPlugin : public QQmlExtensionPlugin
+{
+    Q_OBJECT
+    Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface")
+
+public:
+    void registerTypes(const char *uri)
+    {
+        Q_ASSERT(uri == QLatin1String("TestPlugin"));
+        qmlRegisterType<TestType>(uri, 1, 0, "TestTypePlugin");
+    }
+};
+
+#include "plugin.moc"
diff --git a/tests/manual/qmltypememory/TestPlugin/plugin.pro b/tests/manual/qmltypememory/TestPlugin/plugin.pro
new file mode 100644 (file)
index 0000000..7575442
--- /dev/null
@@ -0,0 +1,7 @@
+TEMPLATE = lib
+CONFIG += plugin
+QT += qml
+
+TARGET  = testplugin
+
+SOURCES += plugin.cpp
diff --git a/tests/manual/qmltypememory/TestPlugin/qmldir b/tests/manual/qmltypememory/TestPlugin/qmldir
new file mode 100644 (file)
index 0000000..f0624df
--- /dev/null
@@ -0,0 +1,2 @@
+module TestPlugin
+plugin testplugin
diff --git a/tests/manual/qmltypememory/TestType.qml b/tests/manual/qmltypememory/TestType.qml
new file mode 100644 (file)
index 0000000..59e0bcf
--- /dev/null
@@ -0,0 +1,43 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Research In Motion.
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the manual tests of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.  For licensing terms and
+** conditions see http://qt.digia.com/licensing.  For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights.  These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQml 2.0
+QtObject{property int notJustAStandardQtObject: 10 }
diff --git a/tests/manual/qmltypememory/main.cpp b/tests/manual/qmltypememory/main.cpp
new file mode 100644 (file)
index 0000000..da086ec
--- /dev/null
@@ -0,0 +1,56 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Research In Motion.
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the manual tests of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.  For licensing terms and
+** conditions see http://qt.digia.com/licensing.  For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights.  These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtQml>
+#include <QGuiApplication>
+#include "testdriver.h"
+
+int main (int argc, char* argv[])
+{
+    QGuiApplication app(argc, argv);
+    int i = -1;
+    if (argc > 1)
+        i = atoi(argv[1]);
+    if (i < 1)
+        i = -1;
+    TestDriver td(QUrl::fromLocalFile("main.qml"), i);
+    return app.exec();
+}
diff --git a/tests/manual/qmltypememory/main.qml b/tests/manual/qmltypememory/main.qml
new file mode 100644 (file)
index 0000000..7bc9006
--- /dev/null
@@ -0,0 +1,54 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Research In Motion.
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the manual tests of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.  For licensing terms and
+** conditions see http://qt.digia.com/licensing.  For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights.  These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQml 2.0
+import QtQuick 2.0
+import QtQuick.Window 2.0
+import QtQuick.LocalStorage 2.0
+import Test 2.0
+import TestPlugin 1.0
+import "."
+
+QtObject {
+    property TestType tt //No object, although it should be properly parented if there were one
+    property TestTypeCpp tt2 //No object, although it should be properly parented if there were one
+    property TestTypePlugin tt3
+}
diff --git a/tests/manual/qmltypememory/qmldir b/tests/manual/qmltypememory/qmldir
new file mode 100644 (file)
index 0000000..edb8c89
--- /dev/null
@@ -0,0 +1,2 @@
+TestFromDir 2.0 TestType.qml
+internal TestFromDirInt TestType.qml
diff --git a/tests/manual/qmltypememory/qmltypememory.pro b/tests/manual/qmltypememory/qmltypememory.pro
new file mode 100644 (file)
index 0000000..2bd873d
--- /dev/null
@@ -0,0 +1,8 @@
+TEMPLATE = app
+TARGET = qmltypememory
+INCLUDEPATH += .
+QT += qml
+
+# Input
+HEADERS += testdriver.h
+SOURCES += main.cpp testdriver.cpp
diff --git a/tests/manual/qmltypememory/testdriver.cpp b/tests/manual/qmltypememory/testdriver.cpp
new file mode 100644 (file)
index 0000000..42de18c
--- /dev/null
@@ -0,0 +1,105 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Research In Motion.
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the manual tests of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.  For licensing terms and
+** conditions see http://qt.digia.com/licensing.  For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights.  These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "testdriver.h"
+#include <QCoreApplication>
+const int interval = 0;
+
+QObject* singleFactory(QQmlEngine *, QJSEngine*)
+{
+    QObject* ret = new QObject; //NOTE: No parent - but also shouldn't need to be created
+    return ret;
+}
+
+TestDriver::TestDriver(const QUrl &componentUrl, int maxIter)
+    : QObject(0), e(0), c(0), i(maxIter)
+{
+    testFile = componentUrl;
+    QTimer::singleShot(interval, this, SLOT(setUp()));
+}
+
+void TestDriver::setUp()
+{
+    qmlRegisterType<TestType>("Test", 2, 0, "TestTypeCpp");
+    for (int j=2; j<1000; j++) {
+        qmlRegisterType<TestType>("Test", j, 0, "TestType");
+        qmlRegisterType<TestType>("Test", j, 1, "TestType");
+        qmlRegisterType<TestType>("Test", j, 2, "TestType");
+        qmlRegisterType<TestType>("Test", j, 3, "TestType");
+        qmlRegisterType<TestType>("Test", j, 4, "TestType");
+        qmlRegisterType<TestType>("Test", j, 5, "TestType");
+        qmlRegisterType<TestType>("Test", j, 6, "TestType");
+        qmlRegisterType<TestType>("Test", j, 7, "TestType");
+        qmlRegisterType<TestType>("Test", j, 8, "TestType");
+        qmlRegisterType<TestType>("Test", j, 9, "TestType");
+    }
+    qmlRegisterType<TestType>("Test2", 1, 0, "TestType");
+    qmlRegisterType<TestType>("Test2", 3, 0, "TestType");
+    qmlRegisterType<TestType>("Test3", 9, 0, "TestType");
+    qmlRegisterType(QUrl::fromLocalFile(QDir::currentPath() + QLatin1String("TestType.qml")), "Test", 2, 0, "TestType2");
+    qmlRegisterUncreatableType<TestType2>("Test", 2, 0, "CannotDoThis", QLatin1String("Just don't"));
+    qmlRegisterType<TestType3>();
+    qmlRegisterSingletonType<QObject>("Test", 2, 0, "Singlet", singleFactory);
+
+    e = new QQmlEngine(this);
+    c = new QQmlComponent(e, testFile);
+    QObject* unused = c->create();
+    if (!unused) {
+        qDebug() << "Creation failure" << c->errorString();
+        exit(1);
+    }
+    unused->setParent(c); //Not testing leaky objects in the tree
+    QTimer::singleShot(interval, this, SLOT(tearDown()));
+}
+
+void TestDriver::tearDown()
+{
+    delete c;
+    e->collectGarbage();
+    delete e;
+    qmlClearTypeRegistrations();
+    //Note that i < 0 will effectively never terminate. This is deliberate as a prime use is to run indefinitely and watch the memory *not* grow
+    i--;
+    if (!i)
+        qApp->quit();
+    else
+        QTimer::singleShot(interval, this, SLOT(setUp()));
+}
diff --git a/tests/manual/qmltypememory/testdriver.h b/tests/manual/qmltypememory/testdriver.h
new file mode 100644 (file)
index 0000000..711a725
--- /dev/null
@@ -0,0 +1,65 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Research In Motion.
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the manual tests of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.  For licensing terms and
+** conditions see http://qt.digia.com/licensing.  For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights.  These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef TESTDRIVER_H
+#define TESTDRIVER_H
+#include <QtCore>
+#include <QtQml>
+
+class TestDriver : public QObject
+{
+    Q_OBJECT
+public:
+    TestDriver(const QUrl &componentUrl, int maxIter = -1);
+public slots:
+    void setUp();
+    void tearDown();
+private:
+    QUrl testFile;
+    QQmlEngine* e;
+    QQmlComponent* c;
+    signed long int i;
+};
+
+class TestType : public QObject { Q_OBJECT };
+class TestType2 : public QObject { Q_OBJECT };
+class TestType3 : public QObject { Q_OBJECT };
+#endif