diff options
author | Fabian Kosmale <[email protected]> | 2021-02-26 10:31:48 +0100 |
---|---|---|
committer | Fabian Kosmale <[email protected]> | 2021-03-04 12:53:47 +0100 |
commit | 88464aa5635188b4921f299de2f645086b33a2c7 (patch) | |
tree | 91bfca1e121ff7aa5d92b4001a939381b6bc033c /src/quick | |
parent | 50e984c07229b753d6558610e7fa7c7df733fe50 (diff) |
Use QQmlAnyBinding in QQuickState and related classes
Fixes: QTBUG-91000
Change-Id: I80b54d85ab694f0fbce8a05f55881cc88fefb1da
Reviewed-by: Ulf Hermann <[email protected]>
Diffstat (limited to 'src/quick')
-rw-r--r-- | src/quick/util/qquickglobal.cpp | 7 | ||||
-rw-r--r-- | src/quick/util/qquickpropertychanges.cpp | 84 | ||||
-rw-r--r-- | src/quick/util/qquickstate.cpp | 34 | ||||
-rw-r--r-- | src/quick/util/qquickstate_p.h | 11 | ||||
-rw-r--r-- | src/quick/util/qquickstate_p_p.h | 12 | ||||
-rw-r--r-- | src/quick/util/qquicktransitionmanager.cpp | 8 |
6 files changed, 83 insertions, 73 deletions
diff --git a/src/quick/util/qquickglobal.cpp b/src/quick/util/qquickglobal.cpp index afee2c3878..338ab4b5fa 100644 --- a/src/quick/util/qquickglobal.cpp +++ b/src/quick/util/qquickglobal.cpp @@ -56,6 +56,7 @@ #include <QtQml/private/qqmlglobal_p.h> #include <QtQml/private/qv4engine_p.h> #include <QtQml/private/qv4object_p.h> +#include <QtQml/private/qqmlanybinding_p.h> #include <QtCore/qiterable.h> @@ -140,15 +141,13 @@ void QQmlQtQuick2DebugStatesDelegate::updateBinding(QQmlContext *context, if (state->isStateActive() && state->containsPropertyInRevertList(object, propertyName)) { *inBaseState = false; - QQmlBinding *newBinding = nullptr; + QQmlAnyBinding newBinding; if (!isLiteralValue) { - newBinding = QQmlBinding::create(&QQmlPropertyPrivate::get(property)->core, + newBinding = QQmlAnyBinding::createFromCodeString(property, expression.toString(), object, QQmlContextData::get(context), fileName, line); - newBinding->setTarget(property); } - state->changeBindingInRevertList(object, propertyName, newBinding); if (isLiteralValue) diff --git a/src/quick/util/qquickpropertychanges.cpp b/src/quick/util/qquickpropertychanges.cpp index e0cc66ed35..e7186d349e 100644 --- a/src/quick/util/qquickpropertychanges.cpp +++ b/src/quick/util/qquickpropertychanges.cpp @@ -52,6 +52,7 @@ #include <private/qquickstate_p_p.h> #include <private/qqmlboundsignal_p.h> #include <private/qv4qmlcontext_p.h> +#include <private/qqmlpropertybinding_p.h> #include <QtCore/qdebug.h> @@ -472,29 +473,35 @@ QQuickPropertyChanges::ActionList QQuickPropertyChanges::actions() a.specifiedProperty = property; QQmlRefPointer<QQmlContextData> context = QQmlContextData::get(qmlContext(this)); - - QQmlBinding *newBinding = nullptr; - if (e.binding && e.binding->isTranslationBinding()) { - newBinding = QQmlBinding::createTranslationBinding(d->compilationUnit, e.binding, object(), context); - } else if (e.id != QQmlBinding::Invalid) { - QV4::Scope scope(qmlEngine(this)->handle()); - QV4::Scoped<QV4::QmlContext> qmlContext(scope, QV4::QmlContext::create(scope.engine->rootContext(), context, object())); - newBinding = QQmlBinding::create(&QQmlPropertyPrivate::get(prop)->core, - d->compilationUnit->runtimeFunctions.at(e.id), object(), context, qmlContext); - } - if (!newBinding) - newBinding = QQmlBinding::create(&QQmlPropertyPrivate::get(prop)->core, - e.expression, object(), context, e.url.toString(), e.line); + QV4::Scope scope(qmlEngine(this)->handle()); + QV4::Scoped<QV4::QmlContext> qmlCtxt(scope, QV4::QmlContext::create(scope.engine->rootContext(), context, object())); if (d->isExplicit) { // in this case, we don't want to assign a binding, per se, // so we evaluate the expression and assign the result. // XXX TODO: add a static QQmlJavaScriptExpression::evaluate(QString) // so that we can avoid creating then destroying the binding in this case. + std::unique_ptr<QQmlBinding> newBinding = nullptr; + if (e.binding && e.binding->isTranslationBinding()) { + newBinding.reset(QQmlBinding::createTranslationBinding(d->compilationUnit, e.binding, object(), context)); + } else if (e.id != QQmlBinding::Invalid) { + newBinding.reset(QQmlBinding::create(&QQmlPropertyPrivate::get(prop)->core, d->compilationUnit->runtimeFunctions.at(e.id), object(), context, qmlCtxt)); + } else { + newBinding.reset(QQmlBinding::create(&QQmlPropertyPrivate::get(prop)->core, e.expression, object(), context, e.url.toString(), e.line)); + } a.toValue = newBinding->evaluate(); - delete newBinding; } else { - newBinding->setTarget(prop); + QQmlAnyBinding newBinding = nullptr; + if (e.binding && e.binding->isTranslationBinding()) { + newBinding = QQmlAnyBinding::createTranslationBinding(prop, d->compilationUnit, e.binding, object(), context); + } else if (e.id != QQmlBinding::Invalid) { + newBinding = QQmlAnyBinding::createFromFunction(prop, + d->compilationUnit->runtimeFunctions.at(e.id), + object(), context, qmlCtxt); + } else { + newBinding = QQmlAnyBinding::createFromCodeString(prop, e.expression, object(), context, e.url.toString(), e.line); + } + a.toBinding = newBinding; a.deletableToBinding = true; } @@ -635,11 +642,10 @@ void QQuickPropertyChanges::changeExpression(const QString &name, const QString it->expression = expression; if (state() && state()->isStateActive()) { auto prop = d->property(name); - QQmlBinding *newBinding = QQmlBinding::create( - &QQmlPropertyPrivate::get(prop)->core, expression, object(), - QQmlContextData::get(qmlContext(this))); - newBinding->setTarget(prop); - QQmlPropertyPrivate::setBinding(newBinding, QQmlPropertyPrivate::None, QQmlPropertyData::DontRemoveBinding | QQmlPropertyData::BypassInterceptor); + auto context = QQmlContextData::get(qmlContext(this)); + QString url; + int lineNumber = 0; + QQmlAnyBinding::createFromCodeString(prop, expression, object(), context, url, lineNumber).installOn(prop); } return; } @@ -648,20 +654,16 @@ void QQuickPropertyChanges::changeExpression(const QString &name, const QString // adding a new expression. d->expressions.append(ExpressionEntry(name, nullptr, QQmlBinding::Invalid, expression, QUrl(), -1, -1)); + const QString url; + const quint16 lineNumber = 0; if (state() && state()->isStateActive()) { if (hadValue) { - QQmlAbstractBinding *oldBinding = QQmlPropertyPrivate::binding(d->property(name)); - if (oldBinding) { - oldBinding->setEnabled(false, QQmlPropertyData::DontRemoveBinding | QQmlPropertyData::BypassInterceptor); + auto prop = d->property(name); + QQmlAnyBinding oldBinding = QQmlAnyBinding::takeFrom(prop); + if (oldBinding) state()->changeBindingInRevertList(object(), name, oldBinding); - } - auto prop = d->property(name); - QQmlBinding *newBinding = QQmlBinding::create( - &QQmlPropertyPrivate::get(prop)->core, expression, object(), - QQmlContextData::get(qmlContext(this))); - newBinding->setTarget(prop); - QQmlPropertyPrivate::setBinding(newBinding, QQmlPropertyPrivate::None, QQmlPropertyData::DontRemoveBinding | QQmlPropertyData::BypassInterceptor); + QQmlAnyBinding::createFromCodeString(prop, expression, object(), QQmlContextData::get(qmlContext(this)), url, lineNumber).installOn(prop); } else { QQuickStateAction action; action.restore = restoreEntryValues(); @@ -670,26 +672,28 @@ void QQuickPropertyChanges::changeExpression(const QString &name, const QString action.specifiedObject = object(); action.specifiedProperty = name; - QQmlBinding *newBinding = QQmlBinding::create( + QQmlAnyBinding newBinding; + if (d->isExplicit) { + newBinding = QQmlBinding::create( &QQmlPropertyPrivate::get(action.property)->core, expression, object(), QQmlContextData::get(qmlContext(this))); + } else { + const auto prop = action.property; + const auto context = QQmlContextData::get(qmlContext(this)); + newBinding = QQmlAnyBinding::createFromCodeString(prop, expression, object(), context, url, lineNumber); + } if (d->isExplicit) { // don't assign the binding, merely evaluate the expression. // XXX TODO: add a static QQmlJavaScriptExpression::evaluate(QString) // so that we can avoid creating then destroying the binding in this case. - action.toValue = newBinding->evaluate(); - delete newBinding; + action.toValue = static_cast<QQmlBinding *>(newBinding.asAbstractBinding())->evaluate(); } else { - newBinding->setTarget(action.property); + // TODO: replace binding would be more efficient for new-style properties + QQmlAnyBinding::removeBindingFrom(action.property); + newBinding.installOn(action.property); action.toBinding = newBinding; action.deletableToBinding = true; - state()->addEntryToRevertList(action); - QQmlAbstractBinding *oldBinding = QQmlPropertyPrivate::binding(action.property); - if (oldBinding) - oldBinding->setEnabled(false, QQmlPropertyData::DontRemoveBinding | QQmlPropertyData::BypassInterceptor); - - QQmlPropertyPrivate::setBinding(newBinding, QQmlPropertyPrivate::None, QQmlPropertyData::DontRemoveBinding | QQmlPropertyData::BypassInterceptor); } } } diff --git a/src/quick/util/qquickstate.cpp b/src/quick/util/qquickstate.cpp index 6a72754bde..b67de72105 100644 --- a/src/quick/util/qquickstate.cpp +++ b/src/quick/util/qquickstate.cpp @@ -366,8 +366,10 @@ void QQuickState::cancel() void QQuickStateAction::deleteFromBinding() { if (fromBinding) { - QQmlPropertyPrivate::removeBinding(property); - fromBinding = nullptr; + if (fromBinding.isAbstractPropertyBinding()) { + QQmlPropertyPrivate::removeBinding(property); + fromBinding = nullptr; + } } } @@ -401,7 +403,7 @@ bool QQuickState::changeValueInRevertList(QObject *target, const QString &name, return false; } -bool QQuickState::changeBindingInRevertList(QObject *target, const QString &name, QQmlAbstractBinding *binding) +bool QQuickState::changeBindingInRevertList(QObject *target, const QString &name, QQmlAnyBinding binding) { Q_D(QQuickState); @@ -428,8 +430,10 @@ bool QQuickState::removeEntryFromRevertList(QObject *target, const QString &name QQmlPropertyPrivate::removeBinding(simpleAction.property()); simpleAction.property().write(simpleAction.value()); - if (simpleAction.binding()) - QQmlPropertyPrivate::setBinding(simpleAction.binding()); + if (auto binding = simpleAction.binding(); binding) { + QQmlProperty prop = simpleAction.property(); + binding.installOn(prop); + } d->revertList.erase(it); return true; @@ -457,10 +461,11 @@ void QQuickState::removeAllEntriesFromRevertList(QObject *target) const auto actionMatchesTarget = [target](QQuickSimpleAction &simpleAction) { if (simpleAction.property().object() == target) { QQmlPropertyPrivate::removeBinding(simpleAction.property()); - simpleAction.property().write(simpleAction.value()); - if (simpleAction.binding()) - QQmlPropertyPrivate::setBinding(simpleAction.binding()); + if (auto binding = simpleAction.binding()) { + QQmlProperty prop = simpleAction.property(); + binding.installOn(prop); + } return true; } @@ -483,8 +488,8 @@ void QQuickState::addEntriesToRevertList(const QList<QQuickStateAction> &actionL for (const QQuickStateAction &action : actionList) { QQuickSimpleAction simpleAction(action); action.property.write(action.toValue); - if (action.toBinding) - QQmlPropertyPrivate::setBinding(action.toBinding.data()); + if (auto binding = action.toBinding; binding) + binding.installOn(action.property); simpleActionList.append(simpleAction); } @@ -507,7 +512,7 @@ QVariant QQuickState::valueInRevertList(QObject *target, const QString &name) co return QVariant(); } -QQmlAbstractBinding *QQuickState::bindingInRevertList(QObject *target, const QString &name) const +QQmlAnyBinding QQuickState::bindingInRevertList(QObject *target, const QString &name) const { Q_D(const QQuickState); @@ -587,12 +592,12 @@ void QQuickState::apply(QQuickTransition *trans, QQuickState *revert) } } else { bool found = false; - action.fromBinding = QQmlPropertyPrivate::binding(action.property); + action.fromBinding = QQmlAnyBinding::ofProperty(action.property); for (int jj = 0; jj < d->revertList.count(); ++jj) { if (d->revertList.at(jj).property() == action.property) { found = true; - if (d->revertList.at(jj).binding() != action.fromBinding.data()) { + if (d->revertList.at(jj).binding() != action.fromBinding) { action.deleteFromBinding(); } break; @@ -641,7 +646,8 @@ void QQuickState::apply(QQuickTransition *trans, QQuickState *revert) continue; } QVariant cur = d->revertList.at(ii).property().read(); - QQmlPropertyPrivate::removeBinding(d->revertList.at(ii).property()); + QQmlProperty prop = d->revertList.at(ii).property(); + QQmlAnyBinding::removeBindingFrom(prop); QQuickStateAction a; a.property = d->revertList.at(ii).property(); diff --git a/src/quick/util/qquickstate_p.h b/src/quick/util/qquickstate_p.h index ee9aa92bbd..a6c3f68bb1 100644 --- a/src/quick/util/qquickstate_p.h +++ b/src/quick/util/qquickstate_p.h @@ -57,6 +57,9 @@ #include <QtCore/qsharedpointer.h> #include <private/qtquickglobal_p.h> #include <private/qqmlabstractbinding_p.h> +#include <private/qqmlanybinding_p.h> + +#include <QtCore/private/qproperty_p.h> QT_BEGIN_NAMESPACE @@ -81,8 +84,8 @@ public: QVariant fromValue; QVariant toValue; - QQmlAbstractBinding::Ptr fromBinding; - QQmlAbstractBinding::Ptr toBinding; + QQmlAnyBinding fromBinding; + QQmlAnyBinding toBinding; QQuickStateActionEvent *event; //strictly for matching @@ -191,13 +194,13 @@ public: bool containsPropertyInRevertList(QObject *target, const QString &name) const; bool changeValueInRevertList(QObject *target, const QString &name, const QVariant &revertValue); - bool changeBindingInRevertList(QObject *target, const QString &name, QQmlAbstractBinding *binding); + bool changeBindingInRevertList(QObject *target, const QString &name, QQmlAnyBinding binding); bool removeEntryFromRevertList(QObject *target, const QString &name); void addEntryToRevertList(const QQuickStateAction &action); void removeAllEntriesFromRevertList(QObject *target); void addEntriesToRevertList(const QList<QQuickStateAction> &actions); QVariant valueInRevertList(QObject *target, const QString &name) const; - QQmlAbstractBinding *bindingInRevertList(QObject *target, const QString &name) const; + QQmlAnyBinding bindingInRevertList(QObject *target, const QString &name) const; bool isStateActive() const; diff --git a/src/quick/util/qquickstate_p_p.h b/src/quick/util/qquickstate_p_p.h index 6f9bb180bc..d75cfc32ee 100644 --- a/src/quick/util/qquickstate_p_p.h +++ b/src/quick/util/qquickstate_p_p.h @@ -76,9 +76,7 @@ public: m_event = a.event; if (state == StartState) { m_value = a.fromValue; - if (QQmlPropertyPrivate::binding(m_property)) { - m_binding = QQmlPropertyPrivate::binding(m_property); - } + m_binding = QQmlAnyBinding::ofProperty(m_property); m_reverseEvent = true; } else { m_value = a.toValue; @@ -135,14 +133,14 @@ public: return m_value; } - void setBinding(QQmlAbstractBinding *binding) + void setBinding(QQmlAnyBinding binding) { m_binding = binding; } - QQmlAbstractBinding *binding() const + QQmlAnyBinding binding() const { - return m_binding.data(); + return m_binding; } QObject *specifiedObject() const @@ -168,7 +166,7 @@ public: private: QQmlProperty m_property; QVariant m_value; - QQmlAbstractBinding::Ptr m_binding; + QQmlAnyBinding m_binding; QObject *m_specifiedObject; QString m_specifiedProperty; QQuickStateActionEvent *m_event; diff --git a/src/quick/util/qquicktransitionmanager.cpp b/src/quick/util/qquicktransitionmanager.cpp index 0ee7e57997..97c1fcd045 100644 --- a/src/quick/util/qquicktransitionmanager.cpp +++ b/src/quick/util/qquicktransitionmanager.cpp @@ -109,8 +109,8 @@ void QQuickTransitionManager::complete() void QQuickTransitionManagerPrivate::applyBindings() { for (const QQuickStateAction &action : qAsConst(bindingsList)) { - if (action.toBinding) { - QQmlPropertyPrivate::setBinding(action.toBinding.data()); + if (auto binding = action.toBinding; binding) { + binding.installOn(action.property, QQmlAnyBinding::RespectInterceptors); } else if (action.event) { if (action.reverseEvent) action.event->reverse(); @@ -160,8 +160,8 @@ void QQuickTransitionManager::transition(const QList<QQuickStateAction> &list, // Apply all the property and binding changes for (const QQuickStateAction &action : qAsConst(applyList)) { - if (action.toBinding) { - QQmlPropertyPrivate::setBinding(action.toBinding.data(), QQmlPropertyPrivate::None, QQmlPropertyData::BypassInterceptor | QQmlPropertyData::DontRemoveBinding); + if (auto binding = action.toBinding; binding) { + binding.installOn(action.property); } else if (!action.event) { QQmlPropertyPrivate::write(action.property, action.toValue, QQmlPropertyData::BypassInterceptor | QQmlPropertyData::DontRemoveBinding); } else if (action.event->isReversable()) { |