1 /****************************************************************************
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
6 ** This file is part of the QtQml module of the Qt Toolkit.
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** GNU Lesser General Public License Usage
10 ** This file may be used under the terms of the GNU Lesser General Public
11 ** License version 2.1 as published by the Free Software Foundation and
12 ** appearing in the file LICENSE.LGPL included in the packaging of this
13 ** file. Please review the following information to ensure the GNU Lesser
14 ** General Public License version 2.1 requirements will be met:
15 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
17 ** In addition, as a special exception, Nokia gives you certain additional
18 ** rights. These rights are described in the Nokia Qt LGPL Exception
19 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
21 ** GNU General Public License Usage
22 ** Alternatively, this file may be used under the terms of the GNU General
23 ** Public License version 3.0 as published by the Free Software Foundation
24 ** and appearing in the file LICENSE.GPL included in the packaging of this
25 ** file. Please review the following information to ensure the GNU General
26 ** Public License version 3.0 requirements will be met:
27 ** http://www.gnu.org/copyleft/gpl.html.
30 ** Alternatively, this file may be used in accordance with the terms and
31 ** conditions contained in a signed written agreement between you and Nokia.
40 ****************************************************************************/
42 #ifndef QQMLABSTRACTBINDING_P_H
43 #define QQMLABSTRACTBINDING_P_H
49 // This file is not part of the Qt API. It exists purely as an
50 // implementation detail. This header file may change from version to
51 // version without notice, or even be removed.
56 #include <QtCore/qsharedpointer.h>
57 #include <private/qtqmlglobal_p.h>
58 #include <private/qqmlproperty_p.h>
59 #include <private/qpointervaluepair_p.h>
63 class Q_QML_PRIVATE_EXPORT QQmlAbstractBinding
67 void (*destroy)(QQmlAbstractBinding *);
68 QString (*expression)(const QQmlAbstractBinding *);
69 int (*propertyIndex)(const QQmlAbstractBinding *);
70 QObject *(*object)(const QQmlAbstractBinding *);
71 void (*setEnabled)(QQmlAbstractBinding *, bool, QQmlPropertyPrivate::WriteFlags);
72 void (*update)(QQmlAbstractBinding *, QQmlPropertyPrivate::WriteFlags);
73 void (*retargetBinding)(QQmlAbstractBinding *, QObject *, int);
76 typedef QWeakPointer<QQmlAbstractBinding> Pointer;
78 enum BindingType { Binding = 0, V4 = 1, V8 = 2, ValueTypeProxy = 3 };
79 inline BindingType bindingType() const;
81 // Destroy the binding. Use this instead of calling delete.
82 // Bindings are free to implement their own memory management, so the delete operator is
83 // not necessarily safe. The default implementation clears the binding, removes it from
84 // the object and calls delete.
85 void destroy() { vtable()->destroy(this); }
86 QString expression() const { return vtable()->expression(this); }
88 // Should return the encoded property index for the binding. Should return this value
89 // even if the binding is not enabled or added to an object.
90 // Encoding is: coreIndex | (valueTypeIndex << 24)
91 int propertyIndex() const { return vtable()->propertyIndex(this); }
92 // Should return the object for the binding. Should return this object even if the
93 // binding is not enabled or added to the object.
94 QObject *object() const { return vtable()->object(this); }
96 void setEnabled(bool e) { setEnabled(e, QQmlPropertyPrivate::DontRemoveBinding); }
97 void setEnabled(bool e, QQmlPropertyPrivate::WriteFlags f) { vtable()->setEnabled(this, e, f); }
99 void update() { update(QQmlPropertyPrivate::DontRemoveBinding); }
100 void update(QQmlPropertyPrivate::WriteFlags f) { vtable()->update(this, f); }
103 void removeFromObject();
105 static inline Pointer getPointer(QQmlAbstractBinding *p);
106 static void printBindingLoopError(QQmlProperty &prop);
108 // Default implementation for some VTable functions
110 static void default_destroy(QQmlAbstractBinding *);
111 static QString default_expression(const QQmlAbstractBinding *);
112 static void default_retargetBinding(QQmlAbstractBinding *, QObject *, int);
115 QQmlAbstractBinding(BindingType);
116 ~QQmlAbstractBinding();
119 // Called by QQmlPropertyPrivate to "move" a binding to a different property.
120 // This is only used for alias properties. The default implementation qFatal()'s
121 // to ensure that the method is never called for binding types that don't support it.
122 void retargetBinding(QObject *o, int i) { vtable()->retargetBinding(this, o, i); }
125 Pointer weakPointer();
127 friend class QQmlData;
128 friend class QQmlComponentPrivate;
129 friend class QQmlValueTypeProxyBinding;
130 friend class QQmlPropertyPrivate;
131 friend class QQmlVME;
132 friend class QtSharedPointer::ExternalRefCount<QQmlAbstractBinding>;
134 typedef QSharedPointer<QQmlAbstractBinding> SharedPointer;
135 // To save memory, we also store the rarely used weakPointer() instance in here
136 // We also use the flag bits:
137 // m_mePtr.flag1: added to object
138 QPointerValuePair<QQmlAbstractBinding*, SharedPointer> m_mePtr;
140 inline void setAddedToObject(bool v);
141 inline bool isAddedToObject() const;
143 inline QQmlAbstractBinding *nextBinding() const;
144 inline void setNextBinding(QQmlAbstractBinding *);
146 uintptr_t m_nextBindingPtr;
148 static VTable *vTables[];
149 inline const VTable *vtable() const { return vTables[bindingType()]; }
152 QQmlAbstractBinding::Pointer
153 QQmlAbstractBinding::getPointer(QQmlAbstractBinding *p)
155 return p ? p->weakPointer() : Pointer();
158 void QQmlAbstractBinding::setAddedToObject(bool v)
160 m_mePtr.setFlagValue(v);
163 bool QQmlAbstractBinding::isAddedToObject() const
165 return m_mePtr.flag();
168 QQmlAbstractBinding *QQmlAbstractBinding::nextBinding() const
170 return (QQmlAbstractBinding *)(m_nextBindingPtr & ~0x3);
173 void QQmlAbstractBinding::setNextBinding(QQmlAbstractBinding *b)
175 m_nextBindingPtr = uintptr_t(b) | (m_nextBindingPtr & 0x3);
178 QQmlAbstractBinding::BindingType QQmlAbstractBinding::bindingType() const
180 return (BindingType)(m_nextBindingPtr & 0x3);
184 void QQmlAbstractBinding::default_destroy(QQmlAbstractBinding *This)
186 This->removeFromObject();
188 delete static_cast<T *>(This);
193 #endif // QQMLABSTRACTBINDING_P_H