Merge branch 'master' of git://gitorious.org/qt/qtdeclarative into api_changes
[profile/ivi/qtdeclarative.git] / src / qml / qml / qqmlnotifier_p.h
1 /****************************************************************************
2 **
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
5 **
6 ** This file is part of the QtQml module of the Qt Toolkit.
7 **
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.
16 **
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.
20 **
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.
28 **
29 ** Other Usage
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.
32 **
33 **
34 **
35 **
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42 #ifndef QQMLNOTIFIER_P_H
43 #define QQMLNOTIFIER_P_H
44
45 #include "qqmldata_p.h"
46 #include "qqmlguard_p.h"
47
48 QT_BEGIN_NAMESPACE
49
50 class QQmlNotifierEndpoint;
51 class Q_QML_EXPORT QQmlNotifier
52 {
53 public:
54     inline QQmlNotifier();
55     inline ~QQmlNotifier();
56     inline void notify();
57
58 private:
59     friend class QQmlData;
60     friend class QQmlNotifierEndpoint;
61
62     static void emitNotify(QQmlNotifierEndpoint *);
63     QQmlNotifierEndpoint *endpoints;
64 };
65
66 class QQmlNotifierEndpoint
67 {
68 public:
69     inline QQmlNotifierEndpoint();
70     inline ~QQmlNotifierEndpoint();
71
72     typedef void (*Callback)(QQmlNotifierEndpoint *);
73     Callback callback;
74
75     inline bool isConnected();
76     inline bool isConnected(QObject *source, int sourceSignal);
77     inline bool isConnected(QQmlNotifier *);
78
79     void connect(QObject *source, int sourceSignal);
80     inline void connect(QQmlNotifier *);
81     inline void disconnect();
82
83     inline bool isNotifying() const;
84     inline void cancelNotify();
85
86     void copyAndClear(QQmlNotifierEndpoint &other);
87
88 private:
89     friend class QQmlData;
90     friend class QQmlNotifier;
91
92     union {
93         QQmlNotifier *notifier;
94         QObject *source;
95     };
96     unsigned int notifying : 1;
97     signed int sourceSignal : 31;
98     QQmlNotifierEndpoint **disconnected;
99     QQmlNotifierEndpoint  *next;
100     QQmlNotifierEndpoint **prev;
101 };
102
103 QQmlNotifier::QQmlNotifier()
104 : endpoints(0)
105 {
106 }
107
108 QQmlNotifier::~QQmlNotifier()
109 {    
110     QQmlNotifierEndpoint *endpoint = endpoints;
111     while (endpoint) {
112         QQmlNotifierEndpoint *n = endpoint;
113         endpoint = n->next;
114
115         n->next = 0;
116         n->prev = 0;
117         n->notifier = 0;
118         n->sourceSignal = -1;
119         if (n->disconnected) *n->disconnected = 0;
120         n->disconnected = 0;
121     }
122     endpoints = 0;
123 }
124
125 void QQmlNotifier::notify()
126 {
127     if (endpoints) emitNotify(endpoints);
128 }
129
130 QQmlNotifierEndpoint::QQmlNotifierEndpoint()
131 : callback(0), notifier(0), notifying(0), sourceSignal(-1), disconnected(0), next(0), prev(0)
132 {
133 }
134
135 QQmlNotifierEndpoint::~QQmlNotifierEndpoint()
136 {
137     disconnect();
138 }
139
140 bool QQmlNotifierEndpoint::isConnected()
141 {
142     return prev != 0;
143 }
144
145 bool QQmlNotifierEndpoint::isConnected(QObject *source, int sourceSignal)
146 {
147     return this->sourceSignal != -1 && this->source == source && this->sourceSignal == sourceSignal;
148 }
149
150 bool QQmlNotifierEndpoint::isConnected(QQmlNotifier *notifier)
151 {
152     return sourceSignal == -1 && this->notifier == notifier;
153 }
154
155 void QQmlNotifierEndpoint::connect(QQmlNotifier *notifier)
156 {
157     disconnect();
158
159     next = notifier->endpoints;
160     if (next) { next->prev = &next; }
161     notifier->endpoints = this;
162     prev = &notifier->endpoints;
163     this->notifier = notifier;
164 }
165
166 void QQmlNotifierEndpoint::disconnect()
167 {
168     if (next) next->prev = prev;
169     if (prev) *prev = next;
170     if (disconnected) *disconnected = 0;
171     next = 0;
172     prev = 0;
173     disconnected = 0;
174     notifier = 0;
175     notifying = 0;
176     sourceSignal = -1;
177 }
178
179 /*!
180 Returns true if a notify is in progress.  This means that the signal or QQmlNotifier
181 that this endpoing is connected to has been triggered, but this endpoint's callback has not
182 yet been called.
183
184 An in progress notify can be cancelled by calling cancelNotify.
185 */
186 bool QQmlNotifierEndpoint::isNotifying() const
187 {
188     return notifying == 1;
189 }
190
191 /*!
192 Cancel any notifies that are in progress.
193 */
194 void QQmlNotifierEndpoint::cancelNotify() 
195 {
196     notifying = 0;
197     if (disconnected) {
198         *disconnected = 0;
199         disconnected = 0;
200     }
201 }
202
203 QT_END_NAMESPACE
204
205 #endif // QQMLNOTIFIER_P_H
206