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 << 16)
91 int propertyIndex() const { return vtable()->propertyIndex(this); }
93 // Should return the object for the binding. Should return this object even if the
94 // binding is not enabled or added to the object.
95 QObject *object() const { return vtable()->object(this); }
97 void setEnabled(bool e) { setEnabled(e, QQmlPropertyPrivate::DontRemoveBinding); }
98 void setEnabled(bool e, QQmlPropertyPrivate::WriteFlags f) { vtable()->setEnabled(this, e, f); }
100 void update() { update(QQmlPropertyPrivate::DontRemoveBinding); }
101 void update(QQmlPropertyPrivate::WriteFlags f) { vtable()->update(this, f); }
104 void removeFromObject();
106 static inline Pointer getPointer(QQmlAbstractBinding *p);
107 static void printBindingLoopError(QQmlProperty &prop);
109 // Default implementation for some VTable functions
111 static void default_destroy(QQmlAbstractBinding *);
112 static QString default_expression(const QQmlAbstractBinding *);
113 static void default_retargetBinding(QQmlAbstractBinding *, QObject *, int);
116 QQmlAbstractBinding(BindingType);
117 ~QQmlAbstractBinding();
120 // Called by QQmlPropertyPrivate to "move" a binding to a different property.
121 // This is only used for alias properties. The default implementation qFatal()'s
122 // to ensure that the method is never called for binding types that don't support it.
123 void retargetBinding(QObject *o, int i) { vtable()->retargetBinding(this, o, i); }
126 Pointer weakPointer();
128 friend class QQmlData;
129 friend class QQmlComponentPrivate;
130 friend class QQmlValueTypeProxyBinding;
131 friend class QQmlPropertyPrivate;
132 friend class QQmlVME;
133 friend class QtSharedPointer::ExternalRefCount<QQmlAbstractBinding>;
135 typedef QSharedPointer<QQmlAbstractBinding> SharedPointer;
136 // To save memory, we also store the rarely used weakPointer() instance in here
137 // We also use the flag bits:
138 // m_mePtr.flag1: added to object
139 QPointerValuePair<QQmlAbstractBinding*, SharedPointer> m_mePtr;
141 inline void setAddedToObject(bool v);
142 inline bool isAddedToObject() const;
144 inline QQmlAbstractBinding *nextBinding() const;
145 inline void setNextBinding(QQmlAbstractBinding *);
147 uintptr_t m_nextBindingPtr;
149 static VTable *vTables[];
150 inline const VTable *vtable() const { return vTables[bindingType()]; }
153 QQmlAbstractBinding::Pointer
154 QQmlAbstractBinding::getPointer(QQmlAbstractBinding *p)
156 return p ? p->weakPointer() : Pointer();
159 void QQmlAbstractBinding::setAddedToObject(bool v)
161 m_mePtr.setFlagValue(v);
164 bool QQmlAbstractBinding::isAddedToObject() const
166 return m_mePtr.flag();
169 QQmlAbstractBinding *QQmlAbstractBinding::nextBinding() const
171 return (QQmlAbstractBinding *)(m_nextBindingPtr & ~0x3);
174 void QQmlAbstractBinding::setNextBinding(QQmlAbstractBinding *b)
176 m_nextBindingPtr = uintptr_t(b) | (m_nextBindingPtr & 0x3);
179 QQmlAbstractBinding::BindingType QQmlAbstractBinding::bindingType() const
181 return (BindingType)(m_nextBindingPtr & 0x3);
185 void QQmlAbstractBinding::default_destroy(QQmlAbstractBinding *This)
187 This->removeFromObject();
189 delete static_cast<T *>(This);
194 #endif // QQMLABSTRACTBINDING_P_H