diff options
author | Aaron Kennedy <aaron.kennedy@nokia.com> | 2012-05-23 16:01:21 +0100 |
---|---|---|
committer | Qt by Nokia <qt-info@nokia.com> | 2012-05-24 17:50:13 +0200 |
commit | d12c9306ee2355a76e3e037877ee445b31f66a23 (patch) | |
tree | 324f6b5979ae334358bf71474348a7e3700a68da /src/qml/qml/qqmlabstractbinding_p.h | |
parent | 6ff8aa4b83e801acadd45cc32759ea77cf4532c8 (diff) |
Use static dispatch tables for QQmlAbstractBinding
This saves us the space of the virtual table pointer, but does
somewhat limit us to the 4 QQmlAbstractBinding types that we
have today.
Change-Id: I03d06ef2ec0c51271c28e7a5aab6dc689d369da4
Reviewed-by: Roberto Raggi <roberto.raggi@nokia.com>
Diffstat (limited to 'src/qml/qml/qqmlabstractbinding_p.h')
-rw-r--r-- | src/qml/qml/qqmlabstractbinding_p.h | 75 |
1 files changed, 62 insertions, 13 deletions
diff --git a/src/qml/qml/qqmlabstractbinding_p.h b/src/qml/qml/qqmlabstractbinding_p.h index f3071cf8bf..b9f8ecda5d 100644 --- a/src/qml/qml/qqmlabstractbinding_p.h +++ b/src/qml/qml/qqmlabstractbinding_p.h @@ -63,28 +63,41 @@ QT_BEGIN_NAMESPACE class Q_QML_PRIVATE_EXPORT QQmlAbstractBinding { public: - typedef QWeakPointer<QQmlAbstractBinding> Pointer; + struct VTable { + void (*destroy)(QQmlAbstractBinding *); + QString (*expression)(const QQmlAbstractBinding *); + int (*propertyIndex)(const QQmlAbstractBinding *); + QObject *(*object)(const QQmlAbstractBinding *); + void (*setEnabled)(QQmlAbstractBinding *, bool, QQmlPropertyPrivate::WriteFlags); + void (*update)(QQmlAbstractBinding *, QQmlPropertyPrivate::WriteFlags); + void (*retargetBinding)(QQmlAbstractBinding *, QObject *, int); + }; - virtual void destroy(); + typedef QWeakPointer<QQmlAbstractBinding> Pointer; - virtual QString expression() const; + enum BindingType { Binding = 0, V4 = 1, V8 = 2, ValueTypeProxy = 3 }; + inline BindingType bindingType() const; - enum Type { PropertyBinding, ValueTypeProxy }; - virtual Type bindingType() const { return PropertyBinding; } + // Destroy the binding. Use this instead of calling delete. + // Bindings are free to implement their own memory management, so the delete operator is + // not necessarily safe. The default implementation clears the binding, removes it from + // the object and calls delete. + void destroy() { vtable()->destroy(this); } + QString expression() const { return vtable()->expression(this); } // Should return the encoded property index for the binding. Should return this value // even if the binding is not enabled or added to an object. // Encoding is: coreIndex | (valueTypeIndex << 24) - virtual int propertyIndex() const = 0; + int propertyIndex() const { return vtable()->propertyIndex(this); } // Should return the object for the binding. Should return this object even if the // binding is not enabled or added to the object. - virtual QObject *object() const = 0; + QObject *object() const { return vtable()->object(this); } void setEnabled(bool e) { setEnabled(e, QQmlPropertyPrivate::DontRemoveBinding); } - virtual void setEnabled(bool, QQmlPropertyPrivate::WriteFlags) = 0; + void setEnabled(bool e, QQmlPropertyPrivate::WriteFlags f) { vtable()->setEnabled(this, e, f); } void update() { update(QQmlPropertyPrivate::DontRemoveBinding); } - virtual void update(QQmlPropertyPrivate::WriteFlags) = 0; + void update(QQmlPropertyPrivate::WriteFlags f) { vtable()->update(this, f); } void addToObject(); void removeFromObject(); @@ -92,15 +105,22 @@ public: static inline Pointer getPointer(QQmlAbstractBinding *p); static void printBindingLoopError(QQmlProperty &prop); + // Default implementation for some VTable functions + template<typename T> + static void default_destroy(QQmlAbstractBinding *); + static QString default_expression(const QQmlAbstractBinding *); + static void default_retargetBinding(QQmlAbstractBinding *, QObject *, int); + protected: - QQmlAbstractBinding(); - virtual ~QQmlAbstractBinding(); + QQmlAbstractBinding(BindingType); + ~QQmlAbstractBinding(); void clear(); // Called by QQmlPropertyPrivate to "move" a binding to a different property. // This is only used for alias properties. The default implementation qFatal()'s // to ensure that the method is never called for binding types that don't support it. - virtual void retargetBinding(QObject *, int); + void retargetBinding(QObject *o, int i) { vtable()->retargetBinding(this, o, i); } + private: Pointer weakPointer(); @@ -120,7 +140,13 @@ private: inline void setAddedToObject(bool v); inline bool isAddedToObject() const; - QQmlAbstractBinding *m_nextBinding; + inline QQmlAbstractBinding *nextBinding() const; + inline void setNextBinding(QQmlAbstractBinding *); + + uintptr_t m_nextBindingPtr; + + static VTable *vTables[]; + inline const VTable *vtable() const { return vTables[bindingType()]; } }; QQmlAbstractBinding::Pointer @@ -139,6 +165,29 @@ bool QQmlAbstractBinding::isAddedToObject() const return m_mePtr.flag(); } +QQmlAbstractBinding *QQmlAbstractBinding::nextBinding() const +{ + return (QQmlAbstractBinding *)(m_nextBindingPtr & ~0x3); +} + +void QQmlAbstractBinding::setNextBinding(QQmlAbstractBinding *b) +{ + m_nextBindingPtr = uintptr_t(b) | (m_nextBindingPtr & 0x3); +} + +QQmlAbstractBinding::BindingType QQmlAbstractBinding::bindingType() const +{ + return (BindingType)(m_nextBindingPtr & 0x3); +} + +template<typename T> +void QQmlAbstractBinding::default_destroy(QQmlAbstractBinding *This) +{ + This->removeFromObject(); + This->clear(); + delete static_cast<T *>(This); +} + QT_END_NAMESPACE #endif // QQMLABSTRACTBINDING_P_H |