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"
50 class QQmlNotifierEndpoint;
51 class Q_QML_PRIVATE_EXPORT QQmlNotifier
54 inline QQmlNotifier();
55 inline ~QQmlNotifier();
59 friend class QQmlData;
60 friend class QQmlNotifierEndpoint;
61 friend class QQmlThreadNotifierProxyObject;
63 static void emitNotify(QQmlNotifierEndpoint *, void **a);
64 QQmlNotifierEndpoint *endpoints;
68 class QQmlNotifierEndpoint
71 inline QQmlNotifierEndpoint();
72 inline ~QQmlNotifierEndpoint();
74 // QQmlNotifierEndpoint can only invoke one of a set of pre-defined callbacks.
75 // To add another callback, extend this enum and add the callback to the top
76 // of qqmlnotifier.cpp. Four bits are reserved for the callback, so there can
77 // be up to 15 of them (0 is reserved).
81 QQmlJavaScriptExpressionGuard = 2,
82 QQmlVMEMetaObjectEndpoint = 3,
83 QV4BindingsSubscription = 4
86 inline void setCallback(Callback c) { callback = c; }
88 inline bool isConnected();
89 inline bool isConnected(QObject *source, int sourceSignal);
90 inline bool isConnected(QQmlNotifier *);
92 void connect(QObject *source, int sourceSignal, QQmlEngine *engine);
93 inline void connect(QQmlNotifier *);
94 inline void disconnect();
96 inline bool isNotifying() const;
97 inline void cancelNotify();
100 friend class QQmlData;
101 friend class QQmlNotifier;
103 // Contains either the QObject*, or the QQmlNotifier* that this
104 // endpoint is connected to. While the endpoint is notifying, the
105 // senderPtr points to another intptr_t that contains this value.
107 inline QObject *senderAsObject() const;
108 inline QQmlNotifier *senderAsNotifier() const;
111 // The index is in the range returned by QObjectPrivate::signalIndex().
112 // This is different from QMetaMethod::methodIndex().
113 signed int sourceSignal:28;
115 QQmlNotifierEndpoint *next;
116 QQmlNotifierEndpoint **prev;
119 QQmlNotifier::QQmlNotifier()
124 QQmlNotifier::~QQmlNotifier()
126 QQmlNotifierEndpoint *endpoint = endpoints;
128 QQmlNotifierEndpoint *n = endpoint;
131 if (n->isNotifying()) *((intptr_t *)(n->senderPtr & ~0x1)) = 0;
136 n->sourceSignal = -1;
141 void QQmlNotifier::notify()
143 void *args[] = { 0 };
144 if (endpoints) emitNotify(endpoints, args);
147 QQmlNotifierEndpoint::QQmlNotifierEndpoint()
148 : senderPtr(0), callback(None), sourceSignal(-1), next(0), prev(0)
152 QQmlNotifierEndpoint::~QQmlNotifierEndpoint()
157 bool QQmlNotifierEndpoint::isConnected()
163 \a sourceSignal MUST be in the signal index range (see QObjectPrivate::signalIndex()).
164 This is different from QMetaMethod::methodIndex().
166 bool QQmlNotifierEndpoint::isConnected(QObject *source, int sourceSignal)
168 return this->sourceSignal != -1 && senderAsObject() == source &&
169 this->sourceSignal == sourceSignal;
172 bool QQmlNotifierEndpoint::isConnected(QQmlNotifier *notifier)
174 return sourceSignal == -1 && senderAsNotifier() == notifier;
177 void QQmlNotifierEndpoint::connect(QQmlNotifier *notifier)
181 next = notifier->endpoints;
182 if (next) { next->prev = &next; }
183 notifier->endpoints = this;
184 prev = ¬ifier->endpoints;
185 senderPtr = intptr_t(notifier);
188 void QQmlNotifierEndpoint::disconnect()
190 if (next) next->prev = prev;
191 if (prev) *prev = next;
192 if (isNotifying()) *((intptr_t *)(senderPtr & ~0x1)) = 0;
200 Returns true if a notify is in progress. This means that the signal or QQmlNotifier
201 that this endpoing is connected to has been triggered, but this endpoint's callback has not
204 An in progress notify can be cancelled by calling cancelNotify.
206 bool QQmlNotifierEndpoint::isNotifying() const
208 return senderPtr & 0x1;
212 Cancel any notifies that are in progress.
214 void QQmlNotifierEndpoint::cancelNotify()
217 intptr_t sp = *((intptr_t *)(senderPtr & ~0x1));
218 *((intptr_t *)(senderPtr & ~0x1)) = 0;
223 QObject *QQmlNotifierEndpoint::senderAsObject() const
225 return isNotifying()?((QObject *)(*((intptr_t *)(senderPtr & ~0x1)))):((QObject *)senderPtr);
228 QQmlNotifier *QQmlNotifierEndpoint::senderAsNotifier() const
230 return isNotifying()?((QQmlNotifier *)(*((intptr_t *)(senderPtr & ~0x1)))):((QQmlNotifier *)senderPtr);
235 #endif // QQMLNOTIFIER_P_H