aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@theqtcompany.com>2014-11-10 08:03:08 +0100
committerSimon Hausmann <simon.hausmann@digia.com>2014-12-10 14:52:21 +0100
commitfbcffd48e2face5184b523ff9674c329847ecdd9 (patch)
tree051d0516c6ea0abcf016fd7c2108ac7adf1d8980
parent7a0542d45e9f675f361477927bec1bbb0fa7a88d (diff)
Changed value type property index encoding
We used to encode property index and value type property index in one int with 16 bits each, for example font.pixelSize with index of "font" in the lower 16 bits and "pixelSize" in the upper 16 bits. Detecting if a given encoded index was using value types or not was based on whether the value type index (upper 16 bits) were non-zero. That assumption holds given that all valid property indicies of value types are > 0 because they are all sub-classes of QObject, which provides the first property (objectName). With the introduction of gadgets property index zero will become popular again, and value types are a core use-case for gadgets. Therefore we need to change the encoding to allow for zero to be a valid value type property index. This is implemented by centralizing all decoding call sites to call one function that indicates -1 as non-present value type core index return value. That way we can encode the index with an offset of 1. Change-Id: I266abf140211a4f7204b47b94d07c364f0a8f408 Reviewed-by: Lars Knoll <lars.knoll@digia.com>
-rw-r--r--src/qml/compiler/qqmltypecompiler.cpp2
-rw-r--r--src/qml/qml/qqmlabstractbinding.cpp18
-rw-r--r--src/qml/qml/qqmlobjectcreator.cpp5
-rw-r--r--src/qml/qml/qqmlproperty.cpp18
-rw-r--r--src/qml/qml/qqmlpropertycache_p.h10
-rw-r--r--src/qml/qml/qqmlvaluetypeproxybinding.cpp3
-rw-r--r--src/qml/qml/qqmlvmemetaobject_p.h12
7 files changed, 36 insertions, 32 deletions
diff --git a/src/qml/compiler/qqmltypecompiler.cpp b/src/qml/compiler/qqmltypecompiler.cpp
index 8edf4bbe7c..ada848f31d 100644
--- a/src/qml/compiler/qqmltypecompiler.cpp
+++ b/src/qml/compiler/qqmltypecompiler.cpp
@@ -1646,7 +1646,7 @@ bool QQmlComponentAndAliasResolver::resolveAliases()
}
Q_ASSERT(valueTypeIndex <= 0x0000FFFF);
- propIdx |= (valueTypeIndex << 16);
+ propIdx = QQmlPropertyData::encodeValueTypePropertyIndex(propIdx, valueTypeIndex);
if (valueType->metaObject()->property(valueTypeIndex).isEnumType())
type = QVariant::Int;
else
diff --git a/src/qml/qml/qqmlabstractbinding.cpp b/src/qml/qml/qqmlabstractbinding.cpp
index 71169abc98..51471d3b89 100644
--- a/src/qml/qml/qqmlabstractbinding.cpp
+++ b/src/qml/qml/qqmlabstractbinding.cpp
@@ -75,15 +75,12 @@ void QQmlAbstractBinding::addToObject()
QObject *obj = object();
Q_ASSERT(obj);
- int index = propertyIndex();
-
QQmlData *data = QQmlData::get(obj, true);
- if (index & 0xFFFF0000) {
+ int coreIndex;
+ if (QQmlPropertyData::decodeValueTypePropertyIndex(propertyIndex(), &coreIndex) != -1) {
// Value type
- int coreIndex = index & 0x0000FFFF;
-
// Find the value type proxy (if there is one)
QQmlValueTypeProxyBinding *proxy = 0;
if (data->hasBindingBit(coreIndex)) {
@@ -110,7 +107,7 @@ void QQmlAbstractBinding::addToObject()
setNextBinding(data->bindings);
data->bindings = this;
- data->setBindingBit(obj, index);
+ data->setBindingBit(obj, coreIndex);
}
setAddedToObject(true);
@@ -123,16 +120,15 @@ void QQmlAbstractBinding::removeFromObject()
{
if (isAddedToObject()) {
QObject *obj = object();
- int index = propertyIndex();
-
QQmlData *data = QQmlData::get(obj, false);
Q_ASSERT(data);
- if (index & 0xFFFF0000) {
+ int coreIndex;
+ if (QQmlPropertyData::decodeValueTypePropertyIndex(propertyIndex(), &coreIndex) != -1) {
// Find the value type binding
QQmlAbstractBinding *vtbinding = data->bindings;
- while (vtbinding->propertyIndex() != (index & 0x0000FFFF)) {
+ while (vtbinding->propertyIndex() != coreIndex) {
vtbinding = vtbinding->nextBinding();
Q_ASSERT(vtbinding);
}
@@ -169,7 +165,7 @@ void QQmlAbstractBinding::removeFromObject()
binding->setNextBinding(nextBinding());
}
- data->clearBindingBit(index);
+ data->clearBindingBit(coreIndex);
}
setNextBinding(0);
diff --git a/src/qml/qml/qqmlobjectcreator.cpp b/src/qml/qml/qqmlobjectcreator.cpp
index dcf5f0cee4..6047d62104 100644
--- a/src/qml/qml/qqmlobjectcreator.cpp
+++ b/src/qml/qml/qqmlobjectcreator.cpp
@@ -65,9 +65,8 @@ struct ActiveOCRestorer
static void removeBindingOnProperty(QObject *o, int index)
{
- int coreIndex = index & 0x0000FFFF;
- int valueTypeIndex = (index & 0xFFFF0000 ? index >> 16 : -1);
-
+ int coreIndex;
+ int valueTypeIndex = QQmlPropertyData::decodeValueTypePropertyIndex(index, &coreIndex);
QQmlAbstractBinding *binding = QQmlPropertyPrivate::setBinding(o, coreIndex, valueTypeIndex, 0);
if (binding) binding->destroy();
}
diff --git a/src/qml/qml/qqmlproperty.cpp b/src/qml/qml/qqmlproperty.cpp
index 2a888b7a1e..635e4d4a54 100644
--- a/src/qml/qml/qqmlproperty.cpp
+++ b/src/qml/qml/qqmlproperty.cpp
@@ -734,8 +734,8 @@ QQmlPropertyPrivate::setBinding(const QQmlProperty &that,
QObject *object = newBinding->object();
int pi = newBinding->propertyIndex();
- int core = pi & 0x0000FFFF;
- int vt = (pi & 0xFFFF0000)?(pi >> 16):-1;
+ int core;
+ int vt = QQmlPropertyData::decodeValueTypePropertyIndex(pi, &core);
return setBinding(object, core, vt, newBinding, flags);
} else {
@@ -776,7 +776,7 @@ QQmlPropertyPrivate::binding(QObject *object, int coreIndex, int valueTypeIndex)
if (binding && valueTypeIndex != -1) {
if (binding->bindingType() == QQmlAbstractBinding::ValueTypeProxy) {
- int index = coreIndex | (valueTypeIndex << 16);
+ int index = QQmlPropertyData::encodeValueTypePropertyIndex(coreIndex, valueTypeIndex);
binding = static_cast<QQmlValueTypeProxyBinding *>(binding)->binding(index);
}
}
@@ -787,8 +787,8 @@ QQmlPropertyPrivate::binding(QObject *object, int coreIndex, int valueTypeIndex)
void QQmlPropertyPrivate::findAliasTarget(QObject *object, int bindingIndex,
QObject **targetObject, int *targetBindingIndex)
{
- int coreIndex = bindingIndex & 0x0000FFFF;
- int valueTypeIndex = (bindingIndex & 0xFFFF0000)?(bindingIndex >> 16):-1;
+ int coreIndex;
+ int valueTypeIndex = QQmlPropertyData::decodeValueTypePropertyIndex(bindingIndex, &coreIndex);
QQmlData *data = QQmlData::get(object, false);
if (data) {
@@ -804,9 +804,9 @@ void QQmlPropertyPrivate::findAliasTarget(QObject *object, int bindingIndex,
int aBindingIndex = aCoreIndex;
if (aValueTypeIndex != -1)
- aBindingIndex |= aValueTypeIndex << 16;
+ aBindingIndex = QQmlPropertyData::encodeValueTypePropertyIndex(aBindingIndex, aValueTypeIndex);
else if (valueTypeIndex != -1)
- aBindingIndex |= valueTypeIndex << 16;
+ aBindingIndex = QQmlPropertyData::encodeValueTypePropertyIndex(aBindingIndex, valueTypeIndex);
findAliasTarget(aObject, aBindingIndex, targetObject, targetBindingIndex);
return;
@@ -853,7 +853,7 @@ QQmlPropertyPrivate::setBinding(QObject *object, int coreIndex, int valueTypeInd
int index = coreIndex;
if (valueTypeIndex != -1)
- index |= (valueTypeIndex << 16);
+ index = QQmlPropertyData::encodeValueTypePropertyIndex(index, valueTypeIndex);
if (binding && valueTypeIndex != -1 && binding->bindingType() == QQmlAbstractBinding::ValueTypeProxy)
binding = static_cast<QQmlValueTypeProxyBinding *>(binding)->binding(index);
@@ -912,7 +912,7 @@ QQmlPropertyPrivate::setBindingNoEnable(QObject *object, int coreIndex, int valu
int index = coreIndex;
if (valueTypeIndex != -1)
- index |= (valueTypeIndex << 16);
+ index = QQmlPropertyData::encodeValueTypePropertyIndex(index, valueTypeIndex);
if (binding && valueTypeIndex != -1 && binding->bindingType() == QQmlAbstractBinding::ValueTypeProxy)
binding = static_cast<QQmlValueTypeProxyBinding *>(binding)->binding(index);
diff --git a/src/qml/qml/qqmlpropertycache_p.h b/src/qml/qml/qqmlpropertycache_p.h
index 8bd7cd5f56..524546e737 100644
--- a/src/qml/qml/qqmlpropertycache_p.h
+++ b/src/qml/qml/qqmlpropertycache_p.h
@@ -160,8 +160,14 @@ public:
inline int getValueTypeCoreIndex() const;
// Returns the "encoded" index for use with bindings. Encoding is:
- // coreIndex | (valueTypeCoreIndex << 16)
+ // coreIndex | ((valueTypeCoreIndex + 1) << 16)
inline int encodedIndex() const;
+ static int encodeValueTypePropertyIndex(int coreIndex, int valueTypeCoreIndex)
+ { return coreIndex | ((valueTypeCoreIndex + 1) << 16); }
+ static int decodeValueTypePropertyIndex(int index, int *coreIndex = 0) {
+ if (coreIndex) *coreIndex = index & 0xffff;
+ return (index >> 16) - 1;
+ }
union {
int propType; // When !NotFullyResolved
@@ -464,7 +470,7 @@ int QQmlPropertyRawData::getValueTypeCoreIndex() const
int QQmlPropertyRawData::encodedIndex() const
{
- return isValueTypeVirtual()?(coreIndex | (valueTypeCoreIndex << 16)):coreIndex;
+ return isValueTypeVirtual()?QQmlPropertyData::encodeValueTypePropertyIndex(coreIndex, valueTypeCoreIndex):coreIndex;
}
QQmlPropertyData *
diff --git a/src/qml/qml/qqmlvaluetypeproxybinding.cpp b/src/qml/qml/qqmlvaluetypeproxybinding.cpp
index 9e8d9198ee..875a9382f2 100644
--- a/src/qml/qml/qqmlvaluetypeproxybinding.cpp
+++ b/src/qml/qml/qqmlvaluetypeproxybinding.cpp
@@ -123,7 +123,8 @@ void QQmlValueTypeProxyBinding::removeBindings(quint32 mask)
QQmlAbstractBinding *lastBinding = 0;
while (binding) {
- if (mask & (1 << (binding->propertyIndex() >> 16))) {
+ int valueTypeIndex = QQmlPropertyData::decodeValueTypePropertyIndex(binding->propertyIndex());
+ if (valueTypeIndex != -1 && (mask & (1 << valueTypeIndex))) {
QQmlAbstractBinding *remove = binding;
binding = remove->nextBinding();
diff --git a/src/qml/qml/qqmlvmemetaobject_p.h b/src/qml/qml/qqmlvmemetaobject_p.h
index a8a9a02102..a7df7c6e53 100644
--- a/src/qml/qml/qqmlvmemetaobject_p.h
+++ b/src/qml/qml/qqmlvmemetaobject_p.h
@@ -90,19 +90,21 @@ struct QQmlVMEMetaData
return propertyIdx == -1;
}
bool isPropertyAlias() const {
- return !isObjectAlias() && !(propertyIdx & 0xFFFF0000);
+ return !isObjectAlias() && valueTypeIndex() == -1;
}
bool isValueTypeAlias() const {
- return !isObjectAlias() && (propertyIdx & 0xFFFF0000);
+ return !isObjectAlias() && valueTypeIndex() != -1;
}
int propertyIndex() const {
- return propertyIdx & 0x0000FFFF;
+ int index;
+ QQmlPropertyData::decodeValueTypePropertyIndex(propertyIdx, &index);
+ return index;
}
int valueTypeIndex() const {
- return (propertyIdx & 0xFFFF0000) >> 16;
+ return QQmlPropertyData::decodeValueTypePropertyIndex(propertyIdx);
}
int valueType() const {
- return (propertyIdx & 0xFFFF0000) ? propType : 0;
+ return (valueTypeIndex() != -1) ? propType : 0;
}
};