diff options
author | Juha Vuolle <juha.vuolle@insta.fi> | 2021-03-01 14:41:06 +0200 |
---|---|---|
committer | Juha Vuolle <juha.vuolle@insta.fi> | 2021-05-03 13:51:56 +0300 |
commit | 28c1702e69800dc89748c184d449b775a049968f (patch) | |
tree | 34a849d89ac7d09359aa4bdd4d8a6f06f5adb0b8 /src | |
parent | 00f3ec2b5c11aa399d72f8daaf0a45150905123e (diff) |
QtStateMachine QML-facing properties' bindable support part 2
This commit covers these QML-facing classes:
SignalTransition
Task-number: QTBUG-91375
Change-Id: I58bca7b4599b420aa99492233f9d88ea4af7e877
Reviewed-by: Ivan Solovev <ivan.solovev@qt.io>
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
Diffstat (limited to 'src')
-rw-r--r-- | src/statemachineqml/CMakeLists.txt | 2 | ||||
-rw-r--r-- | src/statemachineqml/signaltransition.cpp | 35 | ||||
-rw-r--r-- | src/statemachineqml/signaltransition_p.h | 16 |
3 files changed, 36 insertions, 17 deletions
diff --git a/src/statemachineqml/CMakeLists.txt b/src/statemachineqml/CMakeLists.txt index cd3331f..a30d76a 100644 --- a/src/statemachineqml/CMakeLists.txt +++ b/src/statemachineqml/CMakeLists.txt @@ -14,6 +14,8 @@ qt_internal_add_module(StateMachineQml Qt::Core Qt::Qml Qt::StateMachine + LIBRARIES + Qt::QmlPrivate ) set_target_properties(StateMachineQml PROPERTIES diff --git a/src/statemachineqml/signaltransition.cpp b/src/statemachineqml/signaltransition.cpp index 16c2e0c..f082b0a 100644 --- a/src/statemachineqml/signaltransition.cpp +++ b/src/statemachineqml/signaltransition.cpp @@ -54,7 +54,7 @@ SignalTransition::SignalTransition(QState *parent) : QSignalTransition(this, SIGNAL(invokeYourself()), parent), m_complete(false), m_signalExpression(nullptr) { - connect(this, SIGNAL(signalChanged()), SIGNAL(qmlSignalChanged())); + connect(this, &SignalTransition::signalChanged, [this](){ m_signal.notify(); }); } bool SignalTransition::eventTest(QEvent *event) @@ -63,7 +63,7 @@ bool SignalTransition::eventTest(QEvent *event) if (!QSignalTransition::eventTest(event)) return false; - if (m_guard.isEmpty()) + if (m_guard.value().isEmpty()) return true; QQmlContext *outerContext = QQmlEngine::contextForObject(this); @@ -79,7 +79,7 @@ bool SignalTransition::eventTest(QEvent *event) for (int i = 0; i < count; i++) context.setContextProperty(QString::fromUtf8(parameterNames[i]), QVariant::fromValue(e->arguments().at(i))); - QQmlExpression expr(m_guard, &context, this); + QQmlExpression expr(m_guard.value(), &context, this); QVariant result = expr.evaluate(); return result.toBool(); @@ -101,8 +101,10 @@ const QJSValue& SignalTransition::signal() void SignalTransition::setSignal(const QJSValue &signal) { - if (m_signal.strictlyEquals(signal)) + if (m_signal.value().strictlyEquals(signal)) { + m_signal.removeBindingUnlessInWrapper(); return; + } QV4::ExecutionEngine *jsEngine = QQmlEngine::contextForObject(this)->engine()->handle(); QV4::Scope scope(jsEngine); @@ -111,16 +113,15 @@ void SignalTransition::setSignal(const QJSValue &signal) QMetaMethod signalMethod; m_signal = signal; - QJSValuePrivate::manageStringOnV4Heap(jsEngine, &m_signal); - - QV4::ScopedValue value(scope, QJSValuePrivate::asReturnedValue(&m_signal)); + QV4::ScopedValue value(scope, QJSValuePrivate::asReturnedValue(&signal)); // Did we get the "slot" that can be used to invoke the signal? if (QV4::QObjectMethod *signalSlot = value->as<QV4::QObjectMethod>()) { sender = signalSlot->object(); Q_ASSERT(sender); signalMethod = sender->metaObject()->method(signalSlot->methodIndex()); - } else if (QV4::QmlSignalHandler *signalObject = value->as<QV4::QmlSignalHandler>()) { // or did we get the signal object (the one with the connect()/disconnect() functions) ? + } else if (QV4::QmlSignalHandler *signalObject = value->as<QV4::QmlSignalHandler>()) { + // or did we get the signal object (the one with the connect()/disconnect() functions) ? sender = signalObject->object(); Q_ASSERT(sender); signalMethod = sender->metaObject()->method(signalObject->signalIndex()); @@ -130,11 +131,17 @@ void SignalTransition::setSignal(const QJSValue &signal) } QSignalTransition::setSenderObject(sender); + // the call below will emit change signal, and the interceptor lambda in ctor will notify() QSignalTransition::setSignal(signalMethod.methodSignature()); connectTriggered(); } +QBindable<QJSValue> SignalTransition::bindableSignal() +{ + return &m_signal; +} + QQmlScriptString SignalTransition::guard() const { return m_guard; @@ -142,11 +149,12 @@ QQmlScriptString SignalTransition::guard() const void SignalTransition::setGuard(const QQmlScriptString &guard) { - if (m_guard == guard) - return; - m_guard = guard; - emit guardChanged(); +} + +QBindable<QQmlScriptString> SignalTransition::bindableGuard() +{ + return &m_guard; } void SignalTransition::invoke() @@ -169,7 +177,8 @@ void SignalTransition::connectTriggered() QV4::ExecutionEngine *jsEngine = QQmlEngine::contextForObject(this)->engine()->handle(); QV4::Scope scope(jsEngine); - QV4::Scoped<QV4::QObjectMethod> qobjectSignal(scope, QJSValuePrivate::asReturnedValue(&m_signal)); + QV4::Scoped<QV4::QObjectMethod> qobjectSignal( + scope, QJSValuePrivate::asReturnedValue(&m_signal.value())); Q_ASSERT(qobjectSignal); QMetaMethod metaMethod = target->metaObject()->method(qobjectSignal->methodIndex()); int signalIndex = QMetaObjectPrivate::signalIndex(metaMethod); diff --git a/src/statemachineqml/signaltransition_p.h b/src/statemachineqml/signaltransition_p.h index b8b3346..03e3b1b 100644 --- a/src/statemachineqml/signaltransition_p.h +++ b/src/statemachineqml/signaltransition_p.h @@ -62,6 +62,7 @@ #include <private/qqmlcustomparser_p.h> #include <private/qqmlrefcount_p.h> #include <private/qqmlboundsignal_p.h> +#include <QtCore/private/qproperty_p.h> QT_BEGIN_NAMESPACE @@ -69,8 +70,10 @@ class Q_STATEMACHINEQML_PRIVATE_EXPORT SignalTransition : public QSignalTransiti { Q_OBJECT Q_INTERFACES(QQmlParserStatus) - Q_PROPERTY(QJSValue signal READ signal WRITE setSignal NOTIFY qmlSignalChanged) - Q_PROPERTY(QQmlScriptString guard READ guard WRITE setGuard NOTIFY guardChanged) + Q_PROPERTY(QJSValue signal READ signal WRITE setSignal + NOTIFY qmlSignalChanged BINDABLE bindableSignal) + Q_PROPERTY(QQmlScriptString guard READ guard WRITE setGuard + NOTIFY guardChanged BINDABLE bindableGuard) QML_ELEMENT QML_ADDED_IN_VERSION(1, 0) QML_CUSTOMPARSER @@ -80,12 +83,14 @@ public: QQmlScriptString guard() const; void setGuard(const QQmlScriptString &guard); + QBindable<QQmlScriptString> bindableGuard(); bool eventTest(QEvent *event) override; void onTransition(QEvent *event) override; const QJSValue &signal(); void setSignal(const QJSValue &signal); + QBindable<QJSValue> bindableSignal(); Q_INVOKABLE void invoke(); @@ -103,8 +108,11 @@ private: void connectTriggered(); friend class SignalTransitionParser; - QJSValue m_signal; - QQmlScriptString m_guard; + + Q_OBJECT_COMPAT_PROPERTY(SignalTransition, QJSValue, m_signal, &SignalTransition::setSignal, + &SignalTransition::qmlSignalChanged); + Q_OBJECT_BINDABLE_PROPERTY(SignalTransition, QQmlScriptString, + m_guard, &SignalTransition::guardChanged); bool m_complete; QQmlRefPointer<QV4::ExecutableCompilationUnit> m_compilationUnit; QList<const QV4::CompiledData::Binding *> m_bindings; |