aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrei Golubev <andrei.golubev@qt.io>2021-07-13 16:05:27 +0200
committerAndrei Golubev <andrei.golubev@qt.io>2021-07-19 15:48:54 +0200
commitebae5e826785304ae2b90207da3a304149792afc (patch)
tree085daa8cd7785801d381049e854a846f117ea3d0
parentb17df800dee7347e8e74089137a86dd83e6dbecc (diff)
Make tst_qmlcompiler_manual into a QML module
Turns out not to be as easy as it might seem: * C++ classes with QML_ELEMENT entries had to move to a separate header * qt_add_qml_module uses URI as part of the resource path, so "qrc:/myFile.qml" becomes "qrc:/URI/myFile.qml" (important for the signalHandlers_qmlcachegen test) Change-Id: I084541575c11003b07f2ef63809eeab439f2151f Reviewed-by: Ulf Hermann <ulf.hermann@qt.io> (cherry picked from commit e4eabbbb10d446ba44413f6db9abeb8115bc515f) Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
-rw-r--r--tests/auto/qml/qmlcompiler_manual/CMakeLists.txt16
-rw-r--r--tests/auto/qml/qmlcompiler_manual/testclasses.h318
-rw-r--r--tests/auto/qml/qmlcompiler_manual/tst_qmlcompiler_manual.cpp810
3 files changed, 620 insertions, 524 deletions
diff --git a/tests/auto/qml/qmlcompiler_manual/CMakeLists.txt b/tests/auto/qml/qmlcompiler_manual/CMakeLists.txt
index 0afe49e760..ebd207e94b 100644
--- a/tests/auto/qml/qmlcompiler_manual/CMakeLists.txt
+++ b/tests/auto/qml/qmlcompiler_manual/CMakeLists.txt
@@ -7,23 +7,21 @@ list(APPEND test_data ${test_data_glob})
qt_internal_add_test(tst_qmlcompiler_manual
SOURCES
../../shared/util.cpp ../../shared/util.h
+ testclasses.h
tst_qmlcompiler_manual.cpp
INCLUDE_DIRECTORIES
../../shared
LIBRARIES
Qt::CorePrivate
Qt::QmlPrivate
- TESTDATA ${test_data}
)
-## Scopes:
-#####################################################################
-
-qt_add_resources(tst_qmlcompiler_manual "qmlcompiler"
- PREFIX
- "/"
- FILES
- "data/signalHandlers.qml"
+qt6_add_qml_module(tst_qmlcompiler_manual
+ VERSION 1.0
+ URI "QmltcManualTests"
+ NO_CREATE_PLUGIN_TARGET
+ QML_FILES
+ ${test_data}
)
qt_internal_extend_target(tst_qmlcompiler_manual CONDITION ANDROID OR IOS
diff --git a/tests/auto/qml/qmlcompiler_manual/testclasses.h b/tests/auto/qml/qmlcompiler_manual/testclasses.h
new file mode 100644
index 0000000000..a56f85460d
--- /dev/null
+++ b/tests/auto/qml/qmlcompiler_manual/testclasses.h
@@ -0,0 +1,318 @@
+/****************************************************************************
+**
+** Copyright (C) 2021 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** 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 The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef TESTCLASSES_H
+#define TESTCLASSES_H
+
+#include <QtCore/qobject.h>
+#include <QtCore/qproperty.h>
+#include <QtQml/qqmlregistration.h>
+#include <QtQml/qqml.h>
+#include <QtQml/qqmlengine.h>
+#include <QtQml/qqmlcomponent.h>
+#include <QtQuick/qquickitem.h>
+
+#include <private/qqmlrefcount_p.h>
+#include <private/qqmlcontextdata_p.h>
+
+// utility class that sets up QQmlContext for passed QObject. can be used as a
+// base class to ensure that qmlEngine(object) is valid during initializer list
+// evaluation
+struct ContextRegistrator
+{
+ ContextRegistrator(QQmlEngine *engine, QObject *This);
+};
+
+class HelloWorld : public QObject, public ContextRegistrator
+{
+ Q_OBJECT
+ QML_NAMED_ELEMENT(HelloWorld);
+ Q_PROPERTY(QString hello READ getHello WRITE setHello BINDABLE bindableHello)
+ Q_PROPERTY(QString greeting READ getGreeting WRITE setGreeting BINDABLE bindableGreeting)
+
+public:
+ // test workaround: the url is resolved by the test base class, so use
+ // member variable to store the resolved url used as argument in engine
+ // evaluation of runtime functions
+ static QUrl url;
+
+ HelloWorld(QQmlEngine *e, QObject *parent = nullptr);
+ virtual ~HelloWorld() { }
+
+ QString getHello() { return hello.value(); }
+ QString getGreeting() { return greeting.value(); }
+
+ void setHello(const QString &hello_) { hello.setValue(hello_); }
+ void setGreeting(const QString &greeting_) { greeting.setValue(greeting_); }
+
+ QBindable<QString> bindableHello() { return QBindable<QString>(&hello); }
+ QBindable<QString> bindableGreeting() { return QBindable<QString>(&greeting); }
+
+ Q_OBJECT_BINDABLE_PROPERTY(HelloWorld, QString, hello);
+ Q_OBJECT_BINDABLE_PROPERTY(HelloWorld, QString, greeting);
+};
+
+class ANON_signalHandlers : public QObject, public ContextRegistrator
+{
+ Q_OBJECT
+ QML_ANONYMOUS
+ Q_PROPERTY(int signal1P READ getSignal1P WRITE setSignal1P BINDABLE bindableSignal1P)
+ Q_PROPERTY(QString signal2P1 READ getSignal2P1 WRITE setSignal2P1 BINDABLE bindableSignal2P1)
+ Q_PROPERTY(int signal2P2 READ getSignal2P2 WRITE setSignal2P2 BINDABLE bindableSignal2P2)
+ Q_PROPERTY(QString signal2P3 READ getSignal2P3 WRITE setSignal2P3 BINDABLE bindableSignal2P3)
+
+public:
+ // test workaround: the url is resolved by the test base class, so use
+ // member variable to store the resolved url used as argument in engine
+ // evaluation of runtime functions
+ static QUrl url;
+
+ ANON_signalHandlers(QQmlEngine *e, QObject *parent = nullptr);
+
+ int getSignal1P() { return signal1P.value(); }
+ QString getSignal2P1() { return signal2P1.value(); }
+ int getSignal2P2() { return signal2P2.value(); }
+ QString getSignal2P3() { return signal2P3.value(); }
+
+ void setSignal1P(const int &signal1P_) { signal1P.setValue(signal1P_); }
+ void setSignal2P1(const QString &signal2P1_) { signal2P1.setValue(signal2P1_); }
+ void setSignal2P2(const int &signal2P2_) { signal2P2.setValue(signal2P2_); }
+ void setSignal2P3(const QString &signal2P3_) { signal2P3.setValue(signal2P3_); }
+
+ QBindable<int> bindableSignal1P() { return QBindable<int>(&signal1P); }
+ QBindable<QString> bindableSignal2P1() { return QBindable<QString>(&signal2P1); }
+ QBindable<int> bindableSignal2P2() { return QBindable<int>(&signal2P2); }
+ QBindable<QString> bindableSignal2P3() { return QBindable<QString>(&signal2P3); }
+
+ Q_OBJECT_BINDABLE_PROPERTY(ANON_signalHandlers, int, signal1P);
+ Q_OBJECT_BINDABLE_PROPERTY(ANON_signalHandlers, QString, signal2P1);
+ Q_OBJECT_BINDABLE_PROPERTY(ANON_signalHandlers, int, signal2P2);
+ Q_OBJECT_BINDABLE_PROPERTY(ANON_signalHandlers, QString, signal2P3);
+
+Q_SIGNALS:
+ void signal1();
+ void signal2(QString x, int y);
+
+public slots:
+ void onSignal1();
+ void onSignal2(QString x, int y);
+
+public:
+ void qmlEmitSignal1();
+ void qmlEmitSignal2();
+ void qmlEmitSignal2WithArgs(QString x, int y);
+};
+
+class ANON_javaScriptFunctions : public QObject, public ContextRegistrator
+{
+ Q_OBJECT
+ QML_ANONYMOUS
+ Q_PROPERTY(int func1P READ getFunc1P WRITE setFunc1P)
+ Q_PROPERTY(QString func2P READ getFunc2P WRITE setFunc2P)
+ Q_PROPERTY(bool func3P READ getFunc3P WRITE setFunc3P)
+
+public:
+ // test workaround: the url is resolved by the test base class, so use
+ // member variable to store the resolved url used as argument in engine
+ // evaluation of runtime functions
+ static QUrl url;
+
+ ANON_javaScriptFunctions(QQmlEngine *e, QObject *parent = nullptr);
+
+ int getFunc1P() { return func1P.value(); }
+ QString getFunc2P() { return func2P.value(); }
+ bool getFunc3P() { return func3P.value(); }
+
+ void setFunc1P(const int &func1P_) { func1P.setValue(func1P_); }
+ void setFunc2P(const QString &func2P_) { func2P.setValue(func2P_); }
+ void setFunc3P(const bool &func3P_) { func3P.setValue(func3P_); }
+
+ // try if just QProperty works
+ QProperty<int> func1P;
+ QProperty<QString> func2P;
+ QProperty<bool> func3P;
+
+ void func1();
+ void func2(QString x);
+ bool func3();
+};
+
+class ANON_changingBindings : public QObject, public ContextRegistrator
+{
+ Q_OBJECT
+ QML_ANONYMOUS
+ Q_PROPERTY(int p1 READ getP1 WRITE setP1 BINDABLE bindableP1)
+ Q_PROPERTY(int p2 READ getP2 WRITE setP2 BINDABLE bindableP2)
+
+public:
+ // test workaround: the url is resolved by the test base class, so use
+ // member variable to store the resolved url used as argument in engine
+ // evaluation of runtime functions
+ static QUrl url;
+ // test util to monitor binding execution
+ int initialBindingCallCount = 0;
+ // test util: allows to set C++ binding multiple times
+ void resetToInitialBinding();
+
+ ANON_changingBindings(QQmlEngine *e, QObject *parent = nullptr);
+
+ int getP1() { return p1.value(); }
+ int getP2() { return p2.value(); }
+
+ void setP1(int p1_) { p1.setValue(p1_); }
+ void setP2(int p2_) { p2.setValue(p2_); }
+
+ QBindable<int> bindableP1() { return QBindable<int>(&p1); }
+ QBindable<int> bindableP2() { return QBindable<int>(&p2); }
+
+ Q_OBJECT_BINDABLE_PROPERTY(ANON_changingBindings, int, p1);
+ Q_OBJECT_BINDABLE_PROPERTY(ANON_changingBindings, int, p2);
+
+ void resetToConstant();
+ void resetToNewBinding();
+};
+
+class ANON_propertyAlias : public QObject, public ContextRegistrator
+{
+ Q_OBJECT
+ QML_ANONYMOUS
+ Q_PROPERTY(int dummy READ getDummy WRITE setDummy NOTIFY dummyChanged)
+ Q_PROPERTY(int origin READ getOrigin WRITE setOrigin BINDABLE bindableOrigin)
+ Q_PROPERTY(int aliasToOrigin READ getAliasToOrigin WRITE setAliasToOrigin BINDABLE
+ bindableAliasToOrigin)
+
+public:
+ // test workaround: the url is resolved by the test base class, so use
+ // member variable to store the resolved url used as argument in engine
+ // evaluation of runtime functions
+ static QUrl url;
+ // test util: allows to set C++ binding multiple times
+ void resetToInitialBinding();
+
+ ANON_propertyAlias(QQmlEngine *e, QObject *parent = nullptr);
+
+ int getDummy() { return dummy.value(); }
+ int getOrigin() { return origin.value(); }
+ int getAliasToOrigin() { return getOrigin(); }
+
+ void setDummy(int dummy_)
+ {
+ dummy.setValue(dummy_);
+ // emit is essential for Qt.binding() to work correctly
+ emit dummyChanged();
+ }
+ void setOrigin(int origin_) { origin.setValue(origin_); }
+ void setAliasToOrigin(int aliasToOrigin_) { setOrigin(aliasToOrigin_); }
+
+ QBindable<int> bindableOrigin() { return QBindable<int>(&origin); }
+ QBindable<int> bindableAliasToOrigin() { return bindableOrigin(); }
+
+ QProperty<int> dummy;
+ QProperty<int> origin;
+
+ void resetAliasToConstant();
+ void resetOriginToConstant();
+ void resetAliasToNewBinding();
+ void resetOriginToNewBinding();
+ int getAliasValue();
+
+Q_SIGNALS:
+ void dummyChanged();
+};
+
+class ANON_propertyChangeHandler : public QObject, public ContextRegistrator
+{
+ Q_OBJECT
+ QML_ANONYMOUS
+ Q_PROPERTY(int dummy READ getDummy WRITE setDummy)
+ Q_PROPERTY(int p READ getP WRITE setP BINDABLE bindableP)
+ Q_PROPERTY(int watcher READ getWatcher WRITE setWatcher)
+
+public:
+ // test workaround: the url is resolved by the test base class, so use
+ // member variable to store the resolved url used as argument in engine
+ // evaluation of runtime functions
+ static QUrl url;
+
+ ANON_propertyChangeHandler(QQmlEngine *e, QObject *parent = nullptr);
+
+ int getDummy() { return dummy.value(); }
+ int getP() { return p.value(); }
+ int getWatcher() { return watcher.value(); }
+
+ void setDummy(int dummy_) { dummy.setValue(dummy_); }
+ void setP(int p_) { p.setValue(p_); }
+ void setWatcher(int watcher_) { watcher.setValue(watcher_); }
+
+ QBindable<int> bindableP() { return QBindable<int>(&p); }
+
+ QProperty<int> dummy;
+ QProperty<int> p;
+ QProperty<int> watcher;
+
+ // property change handler:
+ struct ANON_propertyChangeHandler_p_changeHandler
+ {
+ ANON_propertyChangeHandler *This = nullptr;
+ ANON_propertyChangeHandler_p_changeHandler(ANON_propertyChangeHandler *obj);
+
+ void operator()();
+ };
+ // the handler object has to be alive as long as the object
+ std::unique_ptr<QPropertyChangeHandler<ANON_propertyChangeHandler_p_changeHandler>>
+ pChangeHandler;
+};
+
+class ANON_propertyReturningFunction : public QObject, public ContextRegistrator
+{
+ Q_OBJECT
+ QML_ANONYMOUS
+ Q_PROPERTY(int counter READ getCounter WRITE setCounter)
+ Q_PROPERTY(QVariant f READ getF WRITE setF BINDABLE bindableF)
+
+public:
+ // test workaround: the url is resolved by the test base class, so use
+ // member variable to store the resolved url used as argument in engine
+ // evaluation of runtime functions
+ static QUrl url;
+
+ ANON_propertyReturningFunction(QQmlEngine *e, QObject *parent = nullptr);
+
+ int getCounter() { return counter.value(); }
+ QVariant getF() { return f.value(); }
+
+ void setCounter(int counter_) { counter.setValue(counter_); }
+ void setF(QVariant f_) { f.setValue(f_); }
+
+ QBindable<QVariant> bindableF() { return QBindable<QVariant>(&f); }
+
+ QProperty<int> counter;
+ QProperty<QVariant> f;
+};
+
+#endif // TESTCLASSES_H
diff --git a/tests/auto/qml/qmlcompiler_manual/tst_qmlcompiler_manual.cpp b/tests/auto/qml/qmlcompiler_manual/tst_qmlcompiler_manual.cpp
index db1cd7132c..ae90aaa34d 100644
--- a/tests/auto/qml/qmlcompiler_manual/tst_qmlcompiler_manual.cpp
+++ b/tests/auto/qml/qmlcompiler_manual/tst_qmlcompiler_manual.cpp
@@ -29,6 +29,8 @@
#include <qtest.h>
#include <QDebug>
+#include "testclasses.h"
+
#include <QtCore/qscopedpointer.h>
#include <QtQml/qqmlengine.h>
#include <QtQml/qqmlcomponent.h>
@@ -119,78 +121,46 @@ static void typeEraseArguments(std::array<void *, Size> &a, std::array<QMetaType
t = { /* types */ QMetaType::fromType<std::decay_t<IOArgs>>()... };
}
-// utility class that sets up QQmlContext for passed QObject. can be used as a
-// base class to ensure that qmlEngine(object) is valid during initializer list
-// evaluation
-struct ContextRegistrator
-{
- ContextRegistrator(QQmlEngine *engine, QObject *This)
- {
- Q_ASSERT(engine && This);
- // if This object has a parent, it's not considered to be a root object,
- // so it must instead have a dedicated context, but what to do when we
- // reparent the root item to e.g. QQuickWindow::contentItem()?
- Q_ASSERT(!This->parent() || engine->contextForObject(This->parent())
- || engine->rootContext());
- QQmlContext *context = engine->rootContext();
- if (This->parent()) {
- QQmlContext *parentContext = engine->contextForObject(This->parent());
- if (parentContext)
- context = new QQmlContext(parentContext, This);
- }
- Q_ASSERT(context);
- // NB: not only sets the context, but also seeds engine into This, so
- // that qmlEngine(This) works
- engine->setContextForObject(This, context);
- Q_ASSERT(qmlEngine(This));
- }
-};
+ContextRegistrator::ContextRegistrator(QQmlEngine *engine, QObject *This)
+{
+ Q_ASSERT(engine && This);
+ if (engine->contextForObject(This)) // already set
+ return;
+
+ // use simple form of the logic done in create() and set(). this code
+ // shouldn't actually be used in real generated classes. it just exists
+ // here for convenience
+ Q_ASSERT(!This->parent() || engine->contextForObject(This->parent()) || engine->rootContext());
+ QQmlContext *parentContext = engine->contextForObject(This->parent());
+ QQmlContext *context =
+ parentContext ? parentContext : new QQmlContext(engine->rootContext(), This);
+ Q_ASSERT(context);
+ // NB: not only sets the context, but also seeds engine into This, so
+ // that qmlEngine(This) works
+ engine->setContextForObject(This, context);
+ Q_ASSERT(qmlEngine(This));
+}
-class HelloWorld : public QObject, public ContextRegistrator
+HelloWorld::HelloWorld(QQmlEngine *e, QObject *parent)
+ : QObject(parent), ContextRegistrator(e, this)
{
- Q_OBJECT
- QML_NAMED_ELEMENT(HelloWorld);
- Q_PROPERTY(QString hello READ getHello WRITE setHello BINDABLE bindableHello)
- Q_PROPERTY(QString greeting READ getGreeting WRITE setGreeting BINDABLE bindableGreeting)
-
-public:
- // test workaround: the url is resolved by the test base class, so use
- // member variable to store the resolved url used as argument in engine
- // evaluation of runtime functions
- static QUrl url;
-
- HelloWorld(QQmlEngine *e, QObject *parent = nullptr)
- : QObject(parent), ContextRegistrator(e, this)
- {
- hello = QStringLiteral("Hello, World");
- QPropertyBinding<QString> HelloWorldCpp_greeting_binding(
- [&]() {
- QQmlEnginePrivate *e = QQmlEnginePrivate::get(qmlEngine(this));
- const auto index = FunctionIndices::HELLO_WORLD_GREETING_BINDING;
- constexpr int argc = 0;
- QString ret {};
- std::array<void *, argc + 1> a {};
- std::array<QMetaType, argc + 1> t {};
- typeEraseArguments(a, t, ret);
- e->executeRuntimeFunction(url, index, this, argc, a.data(), t.data());
- return ret;
- },
- QT_PROPERTY_DEFAULT_BINDING_LOCATION);
- bindableGreeting().setBinding(HelloWorldCpp_greeting_binding);
- }
-
- QString getHello() { return hello.value(); }
- QString getGreeting() { return greeting.value(); }
-
- void setHello(const QString &hello_) { hello.setValue(hello_); }
- void setGreeting(const QString &greeting_) { greeting.setValue(greeting_); }
-
- QBindable<QString> bindableHello() { return QBindable<QString>(&hello); }
- QBindable<QString> bindableGreeting() { return QBindable<QString>(&greeting); }
-
- Q_OBJECT_BINDABLE_PROPERTY(HelloWorld, QString, hello);
- Q_OBJECT_BINDABLE_PROPERTY(HelloWorld, QString, greeting);
-};
+ hello = QStringLiteral("Hello, World");
+ QPropertyBinding<QString> HelloWorldCpp_greeting_binding(
+ [&]() {
+ QQmlEnginePrivate *e = QQmlEnginePrivate::get(qmlEngine(this));
+ const auto index = FunctionIndices::HELLO_WORLD_GREETING_BINDING;
+ constexpr int argc = 0;
+ QString ret {};
+ std::array<void *, argc + 1> a {};
+ std::array<QMetaType, argc + 1> t {};
+ typeEraseArguments(a, t, ret);
+ e->executeRuntimeFunction(url, index, this, argc, a.data(), t.data());
+ return ret;
+ },
+ QT_PROPERTY_DEFAULT_BINDING_LOCATION);
+ bindableGreeting().setBinding(HelloWorldCpp_greeting_binding);
+}
+
QUrl HelloWorld::url = QUrl(); // workaround
void tst_qmlcompiler_manual::cppBinding()
@@ -210,106 +180,63 @@ void tst_qmlcompiler_manual::cppBinding()
QCOMPARE(created.getGreeting(), QStringLiteral("Hello, Qml!"));
}
-class ANON_signalHandlers : public QObject, public ContextRegistrator
+ANON_signalHandlers::ANON_signalHandlers(QQmlEngine *e, QObject *parent)
+ : QObject(parent), ContextRegistrator(e, this)
{
- Q_OBJECT
- QML_ANONYMOUS
- Q_PROPERTY(int signal1P READ getSignal1P WRITE setSignal1P BINDABLE bindableSignal1P)
- Q_PROPERTY(QString signal2P1 READ getSignal2P1 WRITE setSignal2P1 BINDABLE bindableSignal2P1)
- Q_PROPERTY(int signal2P2 READ getSignal2P2 WRITE setSignal2P2 BINDABLE bindableSignal2P2)
- Q_PROPERTY(QString signal2P3 READ getSignal2P3 WRITE setSignal2P3 BINDABLE bindableSignal2P3)
-
-public:
- // test workaround: the url is resolved by the test base class, so use
- // member variable to store the resolved url used as argument in engine
- // evaluation of runtime functions
- static QUrl url;
-
- ANON_signalHandlers(QQmlEngine *e, QObject *parent = nullptr)
- : QObject(parent), ContextRegistrator(e, this)
- {
- signal1P = 0;
- signal2P1 = QStringLiteral("");
- signal2P2 = 0;
- signal2P3 = QStringLiteral("");
-
- QObject::connect(this, &ANON_signalHandlers::signal1, this,
- &ANON_signalHandlers::onSignal1);
- QObject::connect(this, &ANON_signalHandlers::signal2, this,
- &ANON_signalHandlers::onSignal2);
- }
-
- int getSignal1P() { return signal1P.value(); }
- QString getSignal2P1() { return signal2P1.value(); }
- int getSignal2P2() { return signal2P2.value(); }
- QString getSignal2P3() { return signal2P3.value(); }
-
- void setSignal1P(const int &signal1P_) { signal1P.setValue(signal1P_); }
- void setSignal2P1(const QString &signal2P1_) { signal2P1.setValue(signal2P1_); }
- void setSignal2P2(const int &signal2P2_) { signal2P2.setValue(signal2P2_); }
- void setSignal2P3(const QString &signal2P3_) { signal2P3.setValue(signal2P3_); }
-
- QBindable<int> bindableSignal1P() { return QBindable<int>(&signal1P); }
- QBindable<QString> bindableSignal2P1() { return QBindable<QString>(&signal2P1); }
- QBindable<int> bindableSignal2P2() { return QBindable<int>(&signal2P2); }
- QBindable<QString> bindableSignal2P3() { return QBindable<QString>(&signal2P3); }
-
- Q_OBJECT_BINDABLE_PROPERTY(ANON_signalHandlers, int, signal1P);
- Q_OBJECT_BINDABLE_PROPERTY(ANON_signalHandlers, QString, signal2P1);
- Q_OBJECT_BINDABLE_PROPERTY(ANON_signalHandlers, int, signal2P2);
- Q_OBJECT_BINDABLE_PROPERTY(ANON_signalHandlers, QString, signal2P3);
-
-signals:
- void signal1();
- void signal2(QString x, int y);
-
-public slots:
- void onSignal1()
- {
- QQmlEnginePrivate *e = QQmlEnginePrivate::get(qmlEngine(this));
- const auto index = FunctionIndices::SIGNAL_HANDLERS_ON_SIGNAL1;
- e->executeRuntimeFunction(url, index, this);
- }
-
- void onSignal2(QString x, int y)
- {
- constexpr int argc = 2;
- std::array<void *, argc+1> a {};
- std::array<QMetaType, argc + 1> t {};
- typeEraseArguments(a, t, nullptr, x, y);
-
- QQmlEnginePrivate *e = QQmlEnginePrivate::get(qmlEngine(this));
- const qsizetype index = FunctionIndices::SIGNAL_HANDLERS_ON_SIGNAL2;
- e->executeRuntimeFunction(url, index, this, argc, a.data(), t.data());
- }
-
-public:
- void qmlEmitSignal1()
- {
- QQmlEnginePrivate *e = QQmlEnginePrivate::get(qmlEngine(this));
- const auto index = FunctionIndices::SIGNAL_HANDLERS_QML_EMIT_SIGNAL1;
- e->executeRuntimeFunction(url, index, this);
- }
-
- void qmlEmitSignal2()
- {
- QQmlEnginePrivate *e = QQmlEnginePrivate::get(qmlEngine(this));
- const auto index = FunctionIndices::SIGNAL_HANDLERS_QML_EMIT_SIGNAL2;
- e->executeRuntimeFunction(url, index, this);
- }
-
- void qmlEmitSignal2WithArgs(QString x, int y)
- {
- constexpr int argc = 2;
- std::array<void *, argc+1> a {};
- std::array<QMetaType, argc + 1> t {};
- typeEraseArguments(a, t, nullptr, x, y);
-
- QQmlEnginePrivate *e = QQmlEnginePrivate::get(qmlEngine(this));
- const auto index = FunctionIndices::SIGNAL_HANDLERS_QML_EMIT_SIGNAL2_WITH_ARGS;
- e->executeRuntimeFunction(url, index, this, argc, a.data(), t.data());
- }
-};
+ signal1P = 0;
+ signal2P1 = QStringLiteral("");
+ signal2P2 = 0;
+ signal2P3 = QStringLiteral("");
+
+ QObject::connect(this, &ANON_signalHandlers::signal1, this, &ANON_signalHandlers::onSignal1);
+ QObject::connect(this, &ANON_signalHandlers::signal2, this, &ANON_signalHandlers::onSignal2);
+}
+
+void ANON_signalHandlers::onSignal1()
+{
+ QQmlEnginePrivate *e = QQmlEnginePrivate::get(qmlEngine(this));
+ const auto index = FunctionIndices::SIGNAL_HANDLERS_ON_SIGNAL1;
+ e->executeRuntimeFunction(url, index, this);
+}
+
+void ANON_signalHandlers::onSignal2(QString x, int y)
+{
+ constexpr int argc = 2;
+ std::array<void *, argc + 1> a {};
+ std::array<QMetaType, argc + 1> t {};
+ typeEraseArguments(a, t, nullptr, x, y);
+
+ QQmlEnginePrivate *e = QQmlEnginePrivate::get(qmlEngine(this));
+ const qsizetype index = FunctionIndices::SIGNAL_HANDLERS_ON_SIGNAL2;
+ e->executeRuntimeFunction(url, index, this, argc, a.data(), t.data());
+}
+
+void ANON_signalHandlers::qmlEmitSignal1()
+{
+ QQmlEnginePrivate *e = QQmlEnginePrivate::get(qmlEngine(this));
+ const auto index = FunctionIndices::SIGNAL_HANDLERS_QML_EMIT_SIGNAL1;
+ e->executeRuntimeFunction(url, index, this);
+}
+
+void ANON_signalHandlers::qmlEmitSignal2()
+{
+ QQmlEnginePrivate *e = QQmlEnginePrivate::get(qmlEngine(this));
+ const auto index = FunctionIndices::SIGNAL_HANDLERS_QML_EMIT_SIGNAL2;
+ e->executeRuntimeFunction(url, index, this);
+}
+
+void ANON_signalHandlers::qmlEmitSignal2WithArgs(QString x, int y)
+{
+ constexpr int argc = 2;
+ std::array<void *, argc + 1> a {};
+ std::array<QMetaType, argc + 1> t {};
+ typeEraseArguments(a, t, nullptr, x, y);
+
+ QQmlEnginePrivate *e = QQmlEnginePrivate::get(qmlEngine(this));
+ const auto index = FunctionIndices::SIGNAL_HANDLERS_QML_EMIT_SIGNAL2_WITH_ARGS;
+ e->executeRuntimeFunction(url, index, this, argc, a.data(), t.data());
+}
+
QUrl ANON_signalHandlers::url = QUrl(); // workaround
void tst_qmlcompiler_manual::signalHandlers_impl(const QUrl &url)
@@ -361,76 +288,49 @@ void tst_qmlcompiler_manual::signalHandlers()
void tst_qmlcompiler_manual::signalHandlers_qmlcachegen()
{
// use qmlcachegen's compilation unit
- signalHandlers_impl(QUrl("qrc:/data/signalHandlers.qml"));
+ signalHandlers_impl(QUrl("qrc:/QmltcManualTests/data/signalHandlers.qml"));
}
-class ANON_javaScriptFunctions : public QObject, public ContextRegistrator
+ANON_javaScriptFunctions::ANON_javaScriptFunctions(QQmlEngine *e, QObject *parent)
+ : QObject(parent), ContextRegistrator(e, this)
{
- Q_OBJECT
- QML_ANONYMOUS
- Q_PROPERTY(int func1P READ getFunc1P WRITE setFunc1P)
- Q_PROPERTY(QString func2P READ getFunc2P WRITE setFunc2P)
- Q_PROPERTY(bool func3P READ getFunc3P WRITE setFunc3P)
-
-public:
- // test workaround: the url is resolved by the test base class, so use
- // member variable to store the resolved url used as argument in engine
- // evaluation of runtime functions
- static QUrl url;
-
- ANON_javaScriptFunctions(QQmlEngine *e, QObject *parent = nullptr)
- : QObject(parent), ContextRegistrator(e, this)
- {
- func1P = 0;
- func2P = QStringLiteral("");
- func3P = false;
- }
-
- int getFunc1P() { return func1P.value(); }
- QString getFunc2P() { return func2P.value(); }
- bool getFunc3P() { return func3P.value(); }
-
- void setFunc1P(const int &func1P_) { func1P.setValue(func1P_); }
- void setFunc2P(const QString &func2P_) { func2P.setValue(func2P_); }
- void setFunc3P(const bool &func3P_) { func3P.setValue(func3P_); }
-
- // try if just QProperty works
- QProperty<int> func1P;
- QProperty<QString> func2P;
- QProperty<bool> func3P;
-
- void func1()
- {
- QQmlEnginePrivate *e = QQmlEnginePrivate::get(qmlEngine(this));
- const auto index = FunctionIndices::JS_FUNCTIONS_FUNC1;
- e->executeRuntimeFunction(url, index, this);
- }
-
- void func2(QString x)
- {
- constexpr int argc = 1;
- std::array<void *, argc+1> a {};
- std::array<QMetaType, argc + 1> t {};
- typeEraseArguments(a, t, nullptr, x);
-
- QQmlEnginePrivate *e = QQmlEnginePrivate::get(qmlEngine(this));
- const auto index = FunctionIndices::JS_FUNCTIONS_FUNC2;
- e->executeRuntimeFunction(url, index, this, argc, a.data(), t.data());
- }
-
- bool func3()
- {
- QQmlEnginePrivate *e = QQmlEnginePrivate::get(qmlEngine(this));
- const auto index = FunctionIndices::JS_FUNCTIONS_FUNC3;
- constexpr int argc = 0;
- bool ret {};
- std::array<void *, argc + 1> a {};
- std::array<QMetaType, argc + 1> t {};
- typeEraseArguments(a, t, ret);
- e->executeRuntimeFunction(url, index, this, argc, a.data(), t.data());
- return ret;
- }
-};
+ func1P = 0;
+ func2P = QStringLiteral("");
+ func3P = false;
+}
+
+void ANON_javaScriptFunctions::func1()
+{
+ QQmlEnginePrivate *e = QQmlEnginePrivate::get(qmlEngine(this));
+ const auto index = FunctionIndices::JS_FUNCTIONS_FUNC1;
+ e->executeRuntimeFunction(url, index, this);
+}
+
+void ANON_javaScriptFunctions::func2(QString x)
+{
+ constexpr int argc = 1;
+ std::array<void *, argc + 1> a {};
+ std::array<QMetaType, argc + 1> t {};
+ typeEraseArguments(a, t, nullptr, x);
+
+ QQmlEnginePrivate *e = QQmlEnginePrivate::get(qmlEngine(this));
+ const auto index = FunctionIndices::JS_FUNCTIONS_FUNC2;
+ e->executeRuntimeFunction(url, index, this, argc, a.data(), t.data());
+}
+
+bool ANON_javaScriptFunctions::func3()
+{
+ QQmlEnginePrivate *e = QQmlEnginePrivate::get(qmlEngine(this));
+ const auto index = FunctionIndices::JS_FUNCTIONS_FUNC3;
+ constexpr int argc = 0;
+ bool ret {};
+ std::array<void *, argc + 1> a {};
+ std::array<QMetaType, argc + 1> t {};
+ typeEraseArguments(a, t, ret);
+ e->executeRuntimeFunction(url, index, this, argc, a.data(), t.data());
+ return ret;
+}
+
QUrl ANON_javaScriptFunctions::url = QUrl(); // workaround
void tst_qmlcompiler_manual::jsFunctions()
@@ -450,74 +350,47 @@ void tst_qmlcompiler_manual::jsFunctions()
QCOMPARE(created.func3(), true);
}
-class ANON_changingBindings : public QObject, public ContextRegistrator
+void ANON_changingBindings::resetToInitialBinding()
{
- Q_OBJECT
- QML_ANONYMOUS
- Q_PROPERTY(int p1 READ getP1 WRITE setP1 BINDABLE bindableP1)
- Q_PROPERTY(int p2 READ getP2 WRITE setP2 BINDABLE bindableP2)
-
-public:
- // test workaround: the url is resolved by the test base class, so use
- // member variable to store the resolved url used as argument in engine
- // evaluation of runtime functions
- static QUrl url;
- // test util to monitor binding execution
- int initialBindingCallCount = 0;
- // test util: allows to set C++ binding multiple times
- void resetToInitialBinding()
- {
- QPropertyBinding<int> ANON_changingBindings_p2_binding(
- [&]() {
- initialBindingCallCount++;
-
- QQmlEnginePrivate *e = QQmlEnginePrivate::get(qmlEngine(this));
- const auto index = FunctionIndices::CHANGING_BINDINGS_P2_BINDING;
- constexpr int argc = 0;
- int ret {};
- std::array<void *, argc + 1> a {};
- std::array<QMetaType, argc + 1> t {};
- typeEraseArguments(a, t, ret);
- e->executeRuntimeFunction(url, index, this, argc, a.data(), t.data());
- return ret;
- },
- QT_PROPERTY_DEFAULT_BINDING_LOCATION);
- bindableP2().setBinding(ANON_changingBindings_p2_binding);
- }
-
- ANON_changingBindings(QQmlEngine *e, QObject *parent = nullptr)
- : QObject(parent), ContextRegistrator(e, this)
- {
- p1 = 1;
- resetToInitialBinding();
- }
-
- int getP1() { return p1.value(); }
- int getP2() { return p2.value(); }
-
- void setP1(int p1_) { p1.setValue(p1_); }
- void setP2(int p2_) { p2.setValue(p2_); }
-
- QBindable<int> bindableP1() { return QBindable<int>(&p1); }
- QBindable<int> bindableP2() { return QBindable<int>(&p2); }
-
- Q_OBJECT_BINDABLE_PROPERTY(ANON_changingBindings, int, p1);
- Q_OBJECT_BINDABLE_PROPERTY(ANON_changingBindings, int, p2);
-
- void resetToConstant()
- {
- QQmlEnginePrivate *e = QQmlEnginePrivate::get(qmlEngine(this));
- const auto index = FunctionIndices::CHANGING_BINDINGS_RESET_TO_CONSTANT;
- e->executeRuntimeFunction(url, index, this);
- }
-
- void resetToNewBinding()
- {
- QQmlEnginePrivate *e = QQmlEnginePrivate::get(qmlEngine(this));
- const auto index = FunctionIndices::CHANGING_BINDINGS_RESET_TO_NEW_BINDING;
- e->executeRuntimeFunction(url, index, this);
- }
-};
+ QPropertyBinding<int> ANON_changingBindings_p2_binding(
+ [&]() {
+ initialBindingCallCount++;
+
+ QQmlEnginePrivate *e = QQmlEnginePrivate::get(qmlEngine(this));
+ const auto index = FunctionIndices::CHANGING_BINDINGS_P2_BINDING;
+ constexpr int argc = 0;
+ int ret {};
+ std::array<void *, argc + 1> a {};
+ std::array<QMetaType, argc + 1> t {};
+ typeEraseArguments(a, t, ret);
+ e->executeRuntimeFunction(url, index, this, argc, a.data(), t.data());
+ return ret;
+ },
+ QT_PROPERTY_DEFAULT_BINDING_LOCATION);
+ bindableP2().setBinding(ANON_changingBindings_p2_binding);
+}
+
+ANON_changingBindings::ANON_changingBindings(QQmlEngine *e, QObject *parent)
+ : QObject(parent), ContextRegistrator(e, this)
+{
+ p1 = 1;
+ resetToInitialBinding();
+}
+
+void ANON_changingBindings::resetToConstant()
+{
+ QQmlEnginePrivate *e = QQmlEnginePrivate::get(qmlEngine(this));
+ const auto index = FunctionIndices::CHANGING_BINDINGS_RESET_TO_CONSTANT;
+ e->executeRuntimeFunction(url, index, this);
+}
+
+void ANON_changingBindings::resetToNewBinding()
+{
+ QQmlEnginePrivate *e = QQmlEnginePrivate::get(qmlEngine(this));
+ const auto index = FunctionIndices::CHANGING_BINDINGS_RESET_TO_NEW_BINDING;
+ e->executeRuntimeFunction(url, index, this);
+}
+
QUrl ANON_changingBindings::url = QUrl(); // workaround
void tst_qmlcompiler_manual::changingBindings()
@@ -566,106 +439,69 @@ void tst_qmlcompiler_manual::changingBindings()
QCOMPARE(created.initialBindingCallCount, 2);
}
-class ANON_propertyAlias : public QObject, public ContextRegistrator
+void ANON_propertyAlias::resetToInitialBinding()
{
- Q_OBJECT
- QML_ANONYMOUS
- Q_PROPERTY(int dummy READ getDummy WRITE setDummy NOTIFY dummyChanged)
- Q_PROPERTY(int origin READ getOrigin WRITE setOrigin BINDABLE bindableOrigin)
- Q_PROPERTY(int aliasToOrigin READ getAliasToOrigin WRITE setAliasToOrigin BINDABLE
- bindableAliasToOrigin)
-
-public:
- // test workaround: the url is resolved by the test base class, so use
- // member variable to store the resolved url used as argument in engine
- // evaluation of runtime functions
- static QUrl url;
- // test util: allows to set C++ binding multiple times
- void resetToInitialBinding()
- {
- QPropertyBinding<int> ANON_propertyAlias_origin_binding(
- [&]() {
- QQmlEnginePrivate *e = QQmlEnginePrivate::get(qmlEngine(this));
- const auto index = FunctionIndices::PROPERTY_ALIAS_ORIGIN_BINDING;
- constexpr int argc = 0;
- int ret {};
- std::array<void *, argc + 1> a {};
- std::array<QMetaType, argc + 1> t {};
- typeEraseArguments(a, t, ret);
- e->executeRuntimeFunction(url, index, this, argc, a.data(), t.data());
- return ret;
- },
- QT_PROPERTY_DEFAULT_BINDING_LOCATION);
- bindableOrigin().setBinding(ANON_propertyAlias_origin_binding);
- }
-
- ANON_propertyAlias(QQmlEngine *e, QObject *parent = nullptr)
- : QObject(parent), ContextRegistrator(e, this)
- {
- dummy = 12;
- resetToInitialBinding();
- }
-
- int getDummy() { return dummy.value(); }
- int getOrigin() { return origin.value(); }
- int getAliasToOrigin() { return getOrigin(); }
-
- void setDummy(int dummy_)
- {
- dummy.setValue(dummy_);
- // emit is essential for Qt.binding() to work correctly
- emit dummyChanged();
- }
- void setOrigin(int origin_) { origin.setValue(origin_); }
- void setAliasToOrigin(int aliasToOrigin_) { setOrigin(aliasToOrigin_); }
-
- QBindable<int> bindableOrigin() { return QBindable<int>(&origin); }
- QBindable<int> bindableAliasToOrigin() { return bindableOrigin(); }
-
- QProperty<int> dummy;
- QProperty<int> origin;
-
- void resetAliasToConstant()
- {
- QQmlEnginePrivate *e = QQmlEnginePrivate::get(qmlEngine(this));
- const auto index = FunctionIndices::PROPERTY_ALIAS_RESET_ALIAS_TO_CONSTANT;
- e->executeRuntimeFunction(url, index, this);
- }
- void resetOriginToConstant()
- {
- QQmlEnginePrivate *e = QQmlEnginePrivate::get(qmlEngine(this));
- const auto index = FunctionIndices::PROPERTY_ALIAS_RESET_ORIGIN_TO_CONSTANT;
- e->executeRuntimeFunction(url, index, this);
- }
- void resetAliasToNewBinding()
- {
- QQmlEnginePrivate *e = QQmlEnginePrivate::get(qmlEngine(this));
- const auto index = FunctionIndices::PROPERTY_ALIAS_RESET_ALIAS_TO_NEW_BINDING;
- e->executeRuntimeFunction(url, index, this);
- }
- void resetOriginToNewBinding()
- {
- QQmlEnginePrivate *e = QQmlEnginePrivate::get(qmlEngine(this));
- const auto index = FunctionIndices::PROPERTY_ALIAS_RESET_ORIGIN_TO_NEW_BINDING;
- e->executeRuntimeFunction(url, index, this);
- }
-
- int getAliasValue()
- {
- QQmlEnginePrivate *e = QQmlEnginePrivate::get(qmlEngine(this));
- const auto index = FunctionIndices::PROPERTY_ALIAS_GET_ALIAS_VALUE;
- constexpr int argc = 0;
- int ret {};
- std::array<void *, argc + 1> a {};
- std::array<QMetaType, argc + 1> t {};
- typeEraseArguments(a, t, ret);
- e->executeRuntimeFunction(url, index, this, argc, a.data(), t.data());
- return ret;
- }
-
-signals:
- void dummyChanged();
-};
+ QPropertyBinding<int> ANON_propertyAlias_origin_binding(
+ [&]() {
+ QQmlEnginePrivate *e = QQmlEnginePrivate::get(qmlEngine(this));
+ const auto index = FunctionIndices::PROPERTY_ALIAS_ORIGIN_BINDING;
+ constexpr int argc = 0;
+ int ret {};
+ std::array<void *, argc + 1> a {};
+ std::array<QMetaType, argc + 1> t {};
+ typeEraseArguments(a, t, ret);
+ e->executeRuntimeFunction(url, index, this, argc, a.data(), t.data());
+ return ret;
+ },
+ QT_PROPERTY_DEFAULT_BINDING_LOCATION);
+ bindableOrigin().setBinding(ANON_propertyAlias_origin_binding);
+}
+
+ANON_propertyAlias::ANON_propertyAlias(QQmlEngine *e, QObject *parent)
+ : QObject(parent), ContextRegistrator(e, this)
+{
+ dummy = 12;
+ resetToInitialBinding();
+}
+
+void ANON_propertyAlias::resetAliasToConstant()
+{
+ QQmlEnginePrivate *e = QQmlEnginePrivate::get(qmlEngine(this));
+ const auto index = FunctionIndices::PROPERTY_ALIAS_RESET_ALIAS_TO_CONSTANT;
+ e->executeRuntimeFunction(url, index, this);
+}
+void ANON_propertyAlias::resetOriginToConstant()
+{
+ QQmlEnginePrivate *e = QQmlEnginePrivate::get(qmlEngine(this));
+ const auto index = FunctionIndices::PROPERTY_ALIAS_RESET_ORIGIN_TO_CONSTANT;
+ e->executeRuntimeFunction(url, index, this);
+}
+void ANON_propertyAlias::resetAliasToNewBinding()
+{
+ QQmlEnginePrivate *e = QQmlEnginePrivate::get(qmlEngine(this));
+ const auto index = FunctionIndices::PROPERTY_ALIAS_RESET_ALIAS_TO_NEW_BINDING;
+ e->executeRuntimeFunction(url, index, this);
+}
+void ANON_propertyAlias::resetOriginToNewBinding()
+{
+ QQmlEnginePrivate *e = QQmlEnginePrivate::get(qmlEngine(this));
+ const auto index = FunctionIndices::PROPERTY_ALIAS_RESET_ORIGIN_TO_NEW_BINDING;
+ e->executeRuntimeFunction(url, index, this);
+}
+
+int ANON_propertyAlias::getAliasValue()
+{
+ QQmlEnginePrivate *e = QQmlEnginePrivate::get(qmlEngine(this));
+ const auto index = FunctionIndices::PROPERTY_ALIAS_GET_ALIAS_VALUE;
+ constexpr int argc = 0;
+ int ret {};
+ std::array<void *, argc + 1> a {};
+ std::array<QMetaType, argc + 1> t {};
+ typeEraseArguments(a, t, ret);
+ e->executeRuntimeFunction(url, index, this, argc, a.data(), t.data());
+ return ret;
+}
+
QUrl ANON_propertyAlias::url = QUrl(); // workaround
void tst_qmlcompiler_manual::propertyAlias()
@@ -729,78 +565,46 @@ void tst_qmlcompiler_manual::propertyAlias()
QCOMPARE(created.getAliasToOrigin(), -24);
}
-class ANON_propertyChangeHandler : public QObject, public ContextRegistrator
+ANON_propertyChangeHandler::ANON_propertyChangeHandler(QQmlEngine *e, QObject *parent)
+ : QObject(parent), ContextRegistrator(e, this)
{
- Q_OBJECT
- QML_ANONYMOUS
- Q_PROPERTY(int dummy READ getDummy WRITE setDummy)
- Q_PROPERTY(int p READ getP WRITE setP BINDABLE bindableP)
- Q_PROPERTY(int watcher READ getWatcher WRITE setWatcher)
-
-public:
- // test workaround: the url is resolved by the test base class, so use
- // member variable to store the resolved url used as argument in engine
- // evaluation of runtime functions
- static QUrl url;
-
- ANON_propertyChangeHandler(QQmlEngine *e, QObject *parent = nullptr)
- : QObject(parent), ContextRegistrator(e, this)
- {
- dummy = 42;
- QPropertyBinding<int> ANON_propertyChangeHandler_p_binding(
- [&]() {
- QQmlEnginePrivate *e = QQmlEnginePrivate::get(qmlEngine(this));
- const auto index = FunctionIndices::PROPERTY_CHANGE_HANDLER_P_BINDING;
- constexpr int argc = 0;
- int ret {};
- std::array<void *, argc + 1> a {};
- std::array<QMetaType, argc + 1> t {};
- typeEraseArguments(a, t, ret);
- e->executeRuntimeFunction(url, index, this, argc, a.data(), t.data());
- return ret;
- },
- QT_PROPERTY_DEFAULT_BINDING_LOCATION);
- bindableP().setBinding(ANON_propertyChangeHandler_p_binding);
- watcher = 0;
-
- // NB: make sure property change handler appears after setBinding().
- // this prevents preliminary binding evaluation (which would fail as
- // this object doesn't yet know about qmlEngine(this))
- pChangeHandler.reset(new QPropertyChangeHandler<ANON_propertyChangeHandler_p_changeHandler>(
- bindableP().onValueChanged(ANON_propertyChangeHandler_p_changeHandler(this))));
- }
-
- int getDummy() { return dummy.value(); }
- int getP() { return p.value(); }
- int getWatcher() { return watcher.value(); }
-
- void setDummy(int dummy_) { dummy.setValue(dummy_); }
- void setP(int p_) { p.setValue(p_); }
- void setWatcher(int watcher_) { watcher.setValue(watcher_); }
-
- QBindable<int> bindableP() { return QBindable<int>(&p); }
-
- QProperty<int> dummy;
- QProperty<int> p;
- QProperty<int> watcher;
-
- // property change handler:
- struct ANON_propertyChangeHandler_p_changeHandler
- {
- ANON_propertyChangeHandler *This = nullptr;
- ANON_propertyChangeHandler_p_changeHandler(ANON_propertyChangeHandler *obj) : This(obj) { }
-
- void operator()()
- {
- QQmlEnginePrivate *e = QQmlEnginePrivate::get(qmlEngine(This));
- const auto index = FunctionIndices::PROPERTY_CHANGE_HANDLER_ON_P_CHANGED;
- e->executeRuntimeFunction(This->url, index, This);
- }
- };
- // the handler object has to be alive as long as the object
- std::unique_ptr<QPropertyChangeHandler<ANON_propertyChangeHandler_p_changeHandler>>
- pChangeHandler;
-};
+ dummy = 42;
+ QPropertyBinding<int> ANON_propertyChangeHandler_p_binding(
+ [&]() {
+ QQmlEnginePrivate *e = QQmlEnginePrivate::get(qmlEngine(this));
+ const auto index = FunctionIndices::PROPERTY_CHANGE_HANDLER_P_BINDING;
+ constexpr int argc = 0;
+ int ret {};
+ std::array<void *, argc + 1> a {};
+ std::array<QMetaType, argc + 1> t {};
+ typeEraseArguments(a, t, ret);
+ e->executeRuntimeFunction(url, index, this, argc, a.data(), t.data());
+ return ret;
+ },
+ QT_PROPERTY_DEFAULT_BINDING_LOCATION);
+ bindableP().setBinding(ANON_propertyChangeHandler_p_binding);
+ watcher = 0;
+
+ // NB: make sure property change handler appears after setBinding().
+ // this prevents preliminary binding evaluation (which would fail as
+ // this object doesn't yet know about qmlEngine(this))
+ pChangeHandler.reset(new QPropertyChangeHandler<ANON_propertyChangeHandler_p_changeHandler>(
+ bindableP().onValueChanged(ANON_propertyChangeHandler_p_changeHandler(this))));
+}
+
+ANON_propertyChangeHandler::ANON_propertyChangeHandler_p_changeHandler::
+ ANON_propertyChangeHandler_p_changeHandler(ANON_propertyChangeHandler *obj)
+ : This(obj)
+{
+}
+
+void ANON_propertyChangeHandler::ANON_propertyChangeHandler_p_changeHandler::operator()()
+{
+ QQmlEnginePrivate *e = QQmlEnginePrivate::get(qmlEngine(This));
+ const auto index = FunctionIndices::PROPERTY_CHANGE_HANDLER_ON_P_CHANGED;
+ e->executeRuntimeFunction(This->url, index, This);
+}
+
QUrl ANON_propertyChangeHandler::url = QUrl(); // workaround
void tst_qmlcompiler_manual::propertyChangeHandler()
@@ -832,49 +636,25 @@ void tst_qmlcompiler_manual::propertyChangeHandler()
QCOMPARE(created.property("watcher").toInt(), 96);
}
-class ANON_propertyReturningFunction : public QObject, public ContextRegistrator
+ANON_propertyReturningFunction::ANON_propertyReturningFunction(QQmlEngine *e, QObject *parent)
+ : QObject(parent), ContextRegistrator(e, this)
{
- Q_OBJECT
- QML_ANONYMOUS
- Q_PROPERTY(int counter READ getCounter WRITE setCounter)
- Q_PROPERTY(QVariant f READ getF WRITE setF BINDABLE bindableF)
-
-public:
- // test workaround: the url is resolved by the test base class, so use
- // member variable to store the resolved url used as argument in engine
- // evaluation of runtime functions
- static QUrl url;
-
- ANON_propertyReturningFunction(QQmlEngine *e, QObject *parent = nullptr)
- : QObject(parent), ContextRegistrator(e, this)
- {
- QPropertyBinding<QVariant> ANON_propertyReturningFunction_f_binding(
- [&]() {
- QQmlEnginePrivate *e = QQmlEnginePrivate::get(qmlEngine(this));
- const auto index = FunctionIndices::PROPERTY_RETURNING_FUNCTION_F_BINDING;
- constexpr int argc = 0;
- QVariant ret {};
- std::array<void *, argc + 1> a {};
- std::array<QMetaType, argc + 1> t {};
- typeEraseArguments(a, t, ret);
- e->executeRuntimeFunction(url, index, this, argc, a.data(), t.data());
- return ret;
- },
- QT_PROPERTY_DEFAULT_BINDING_LOCATION);
- bindableF().setBinding(ANON_propertyReturningFunction_f_binding);
- }
-
- int getCounter() { return counter.value(); }
- QVariant getF() { return f.value(); }
-
- void setCounter(int counter_) { counter.setValue(counter_); }
- void setF(QVariant f_) { f.setValue(f_); }
-
- QBindable<QVariant> bindableF() { return QBindable<QVariant>(&f); }
-
- QProperty<int> counter;
- QProperty<QVariant> f;
-};
+ QPropertyBinding<QVariant> ANON_propertyReturningFunction_f_binding(
+ [&]() {
+ QQmlEnginePrivate *e = QQmlEnginePrivate::get(qmlEngine(this));
+ const auto index = FunctionIndices::PROPERTY_RETURNING_FUNCTION_F_BINDING;
+ constexpr int argc = 0;
+ QVariant ret {};
+ std::array<void *, argc + 1> a {};
+ std::array<QMetaType, argc + 1> t {};
+ typeEraseArguments(a, t, ret);
+ e->executeRuntimeFunction(url, index, this, argc, a.data(), t.data());
+ return ret;
+ },
+ QT_PROPERTY_DEFAULT_BINDING_LOCATION);
+ bindableF().setBinding(ANON_propertyReturningFunction_f_binding);
+}
+
QUrl ANON_propertyReturningFunction::url = QUrl(); // workaround
void tst_qmlcompiler_manual::propertyReturningFunction()