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 QQMLNOTIFIER_P_H
43 #define QQMLNOTIFIER_P_H
45 #include "qqmldata_p.h"
46 #include "qqmlguard_p.h"
47 #include <QtCore/qmetaobject.h>
48 #include <private/qmetaobject_p.h>
52 class QQmlNotifierEndpoint;
53 class Q_QML_PRIVATE_EXPORT QQmlNotifier
56 inline QQmlNotifier();
57 inline ~QQmlNotifier();
61 friend class QQmlData;
62 friend class QQmlNotifierEndpoint;
63 friend class QQmlThreadNotifierProxyObject;
65 static void emitNotify(QQmlNotifierEndpoint *, void **a);
66 QQmlNotifierEndpoint *endpoints;
70 class QQmlNotifierEndpoint
73 inline QQmlNotifierEndpoint();
74 inline ~QQmlNotifierEndpoint();
76 // QQmlNotifierEndpoint can only invoke one of a set of pre-defined callbacks.
77 // To add another callback, extend this enum and add the callback to the top
78 // of qqmlnotifier.cpp. Four bits are reserved for the callback, so there can
79 // be up to 15 of them (0 is reserved).
83 QQmlJavaScriptExpressionGuard = 2,
84 QQmlVMEMetaObjectEndpoint = 3,
85 QV4BindingsSubscription = 4
88 inline void setCallback(Callback c) { callback = c; }
90 inline bool isConnected();
91 inline bool isConnected(QObject *source, int sourceSignal);
92 inline bool isConnected(QQmlNotifier *);
94 void connect(QObject *source, int sourceSignal, QQmlEngine *engine);
95 inline void connect(QQmlNotifier *);
96 inline void disconnect();
98 inline bool isNotifying() const;
99 inline void cancelNotify();
102 friend class QQmlData;
103 friend class QQmlNotifier;
105 // Contains either the QObject*, or the QQmlNotifier* that this
106 // endpoint is connected to. While the endpoint is notifying, the
107 // senderPtr points to another intptr_t that contains this value.
109 inline QObject *senderAsObject() const;
110 inline QQmlNotifier *senderAsNotifier() const;
113 // The index is in the range returned by QObjectPrivate::signalIndex().
114 // This is different from QMetaMethod::methodIndex().
115 signed int sourceSignal:28;
117 QQmlNotifierEndpoint *next;
118 QQmlNotifierEndpoint **prev;
121 QQmlNotifier::QQmlNotifier()
126 QQmlNotifier::~QQmlNotifier()
128 QQmlNotifierEndpoint *endpoint = endpoints;
130 QQmlNotifierEndpoint *n = endpoint;
133 if (n->isNotifying()) *((intptr_t *)(n->senderPtr & ~0x1)) = 0;
138 n->sourceSignal = -1;
143 void QQmlNotifier::notify()
145 void *args[] = { 0 };
146 if (endpoints) emitNotify(endpoints, args);
149 QQmlNotifierEndpoint::QQmlNotifierEndpoint()
150 : senderPtr(0), callback(None), sourceSignal(-1), next(0), prev(0)
154 QQmlNotifierEndpoint::~QQmlNotifierEndpoint()
159 bool QQmlNotifierEndpoint::isConnected()
165 \a sourceSignal MUST be in the signal index range (see QObjectPrivate::signalIndex()).
166 This is different from QMetaMethod::methodIndex().
168 bool QQmlNotifierEndpoint::isConnected(QObject *source, int sourceSignal)
170 return this->sourceSignal != -1 && senderAsObject() == source &&
171 this->sourceSignal == sourceSignal;
174 bool QQmlNotifierEndpoint::isConnected(QQmlNotifier *notifier)
176 return sourceSignal == -1 && senderAsNotifier() == notifier;
179 void QQmlNotifierEndpoint::connect(QQmlNotifier *notifier)
183 next = notifier->endpoints;
184 if (next) { next->prev = &next; }
185 notifier->endpoints = this;
186 prev = ¬ifier->endpoints;
187 senderPtr = intptr_t(notifier);
190 void QQmlNotifierEndpoint::disconnect()
192 if (sourceSignal != -1) {
193 QObject * const obj = senderAsObject();
194 QObjectPrivate * const priv = QObjectPrivate::get(obj);
195 priv->disconnectNotify(QMetaObjectPrivate::signal(obj->metaObject(), sourceSignal));
197 if (next) next->prev = prev;
198 if (prev) *prev = next;
199 if (isNotifying()) *((intptr_t *)(senderPtr & ~0x1)) = 0;
207 Returns true if a notify is in progress. This means that the signal or QQmlNotifier
208 that this endpoing is connected to has been triggered, but this endpoint's callback has not
211 An in progress notify can be cancelled by calling cancelNotify.
213 bool QQmlNotifierEndpoint::isNotifying() const
215 return senderPtr & 0x1;
219 Cancel any notifies that are in progress.
221 void QQmlNotifierEndpoint::cancelNotify()
224 intptr_t sp = *((intptr_t *)(senderPtr & ~0x1));
225 *((intptr_t *)(senderPtr & ~0x1)) = 0;
230 QObject *QQmlNotifierEndpoint::senderAsObject() const
232 return isNotifying()?((QObject *)(*((intptr_t *)(senderPtr & ~0x1)))):((QObject *)senderPtr);
235 QQmlNotifier *QQmlNotifierEndpoint::senderAsNotifier() const
237 return isNotifying()?((QQmlNotifier *)(*((intptr_t *)(senderPtr & ~0x1)))):((QQmlNotifier *)senderPtr);
242 #endif // QQMLNOTIFIER_P_H