aboutsummaryrefslogtreecommitdiffstats
path: root/src/quick
diff options
context:
space:
mode:
authorFabian Kosmale <[email protected]>2021-02-26 10:31:48 +0100
committerFabian Kosmale <[email protected]>2021-03-04 12:53:47 +0100
commit88464aa5635188b4921f299de2f645086b33a2c7 (patch)
tree91bfca1e121ff7aa5d92b4001a939381b6bc033c /src/quick
parent50e984c07229b753d6558610e7fa7c7df733fe50 (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.cpp7
-rw-r--r--src/quick/util/qquickpropertychanges.cpp84
-rw-r--r--src/quick/util/qquickstate.cpp34
-rw-r--r--src/quick/util/qquickstate_p.h11
-rw-r--r--src/quick/util/qquickstate_p_p.h12
-rw-r--r--src/quick/util/qquicktransitionmanager.cpp8
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()) {