source: trunk/src/corelib/concurrent/qfutureinterface.h@ 5

Last change on this file since 5 was 2, checked in by Dmitry A. Kuminov, 16 years ago

Initially imported qt-all-opensource-src-4.5.1 from Trolltech.

File size: 9.4 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
4** Contact: Qt Software Information ([email protected])
5**
6** This file is part of the QtCore module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial Usage
10** Licensees holding valid Qt Commercial licenses may use this file in
11** accordance with the Qt Commercial License Agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and Nokia.
14**
15** GNU Lesser General Public License Usage
16** Alternatively, this file may be used under the terms of the GNU Lesser
17** General Public License version 2.1 as published by the Free Software
18** Foundation and appearing in the file LICENSE.LGPL included in the
19** packaging of this file. Please review the following information to
20** ensure the GNU Lesser General Public License version 2.1 requirements
21** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
22**
23** In addition, as a special exception, Nokia gives you certain
24** additional rights. These rights are described in the Nokia Qt LGPL
25** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
26** package.
27**
28** GNU General Public License Usage
29** Alternatively, this file may be used under the terms of the GNU
30** General Public License version 3.0 as published by the Free Software
31** Foundation and appearing in the file LICENSE.GPL included in the
32** packaging of this file. Please review the following information to
33** ensure the GNU General Public License version 3.0 requirements will be
34** met: http://www.gnu.org/copyleft/gpl.html.
35**
36** If you are unsure which license is appropriate for your use, please
37** contact the sales department at [email protected].
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42#ifndef QFUTUREINTERFACE_H
43#define QFUTUREINTERFACE_H
44
45#include <QtCore/qglobal.h>
46#include <QtCore/qrunnable.h>
47
48#ifndef QT_NO_QFUTURE
49
50#include <QtCore/qmutex.h>
51#include <QtCore/qtconcurrentexception.h>
52#include <QtCore/qtconcurrentresultstore.h>
53
54QT_BEGIN_HEADER
55QT_BEGIN_NAMESPACE
56
57QT_MODULE(Core)
58
59template <typename T> class QFuture;
60class QFutureInterfaceBasePrivate;
61class QFutureWatcherBase;
62class QFutureWatcherBasePrivate;
63
64class Q_CORE_EXPORT QFutureInterfaceBase
65{
66public:
67 enum State {
68 NoState = 0x00,
69 Running = 0x01,
70 Started = 0x02,
71 Finished = 0x04,
72 Canceled = 0x08,
73 Paused = 0x10,
74 Throttled = 0x20
75 };
76
77 QFutureInterfaceBase(State initialState = NoState);
78 QFutureInterfaceBase(const QFutureInterfaceBase &other);
79 virtual ~QFutureInterfaceBase();
80
81 // reporting functions available to the engine author:
82 void reportStarted();
83 void reportFinished();
84 void reportCanceled();
85#ifndef QT_NO_EXCEPTIONS
86 void reportException(const QtConcurrent::Exception &e);
87#endif
88 void reportResultsReady(int beginIndex, int endIndex);
89
90 void setRunnable(QRunnable *runnable);
91 void setFilterMode(bool enable);
92 void setProgressRange(int minimum, int maximum);
93 int progressMinimum() const;
94 int progressMaximum() const;
95 bool isProgressUpdateNeeded() const;
96 void setProgressValue(int progressValue);
97 int progressValue() const;
98 void setProgressValueAndText(int progressValue, const QString &progressText);
99 QString progressText() const;
100
101 void setExpectedResultCount(int resultCount);
102 int expectedResultCount();
103 int resultCount() const;
104
105 bool queryState(State state) const;
106 bool isRunning() const;
107 bool isStarted() const;
108 bool isCanceled() const;
109 bool isFinished() const;
110 bool isPaused() const;
111 bool isThrottled() const;
112 bool isResultReadyAt(int index) const;
113
114 void cancel();
115 void setPaused(bool paused);
116 void togglePaused();
117 void setThrottled(bool enable);
118
119 void waitForFinished();
120 bool waitForNextResult();
121 void waitForResult(int resultIndex);
122 void waitForResume();
123
124 QMutex *mutex() const;
125 QtConcurrent::internal::ExceptionStore &exceptionStore();
126 QtConcurrent::ResultStoreBase &resultStoreBase();
127 const QtConcurrent::ResultStoreBase &resultStoreBase() const;
128
129 inline bool operator==(const QFutureInterfaceBase &other) const { return d == other.d; }
130 inline bool operator!=(const QFutureInterfaceBase &other) const { return d != other.d; }
131 QFutureInterfaceBase &operator=(const QFutureInterfaceBase &other);
132
133protected:
134 bool referenceCountIsOne() const;
135public:
136
137#ifndef QFUTURE_TEST
138private:
139#endif
140 QFutureInterfaceBasePrivate *d;
141
142private:
143 friend class QFutureWatcherBase;
144 friend class QFutureWatcherBasePrivate;
145};
146
147template <typename T>
148class QFutureInterface : public QFutureInterfaceBase
149{
150public:
151 QFutureInterface(State initialState = NoState)
152 : QFutureInterfaceBase(initialState)
153 { }
154 QFutureInterface(const QFutureInterface &other)
155 : QFutureInterfaceBase(other)
156 { }
157 ~QFutureInterface()
158 {
159 if (referenceCountIsOne())
160 resultStore().clear();
161 }
162
163 static QFutureInterface canceledResult()
164 { return QFutureInterface(State(Started | Finished | Canceled)); }
165
166 QFutureInterface &operator=(const QFutureInterface &other)
167 {
168 QFutureInterfaceBase::operator=(other);
169 return *this;
170 }
171
172 inline QFuture<T> future(); // implemented in qfuture.h
173
174 inline void reportResult(const T *result, int index = -1);
175 inline void reportResult(const T &result, int index = -1);
176 inline void reportResults(const QVector<T> &results, int beginIndex = -1, int count = -1);
177 inline void reportFinished(const T *result = 0);
178
179 inline const T &resultReference(int index) const;
180 inline const T *resultPointer(int index) const;
181 inline QList<T> results();
182private:
183 QtConcurrent::ResultStore<T> &resultStore()
184 { return static_cast<QtConcurrent::ResultStore<T> &>(resultStoreBase()); }
185 const QtConcurrent::ResultStore<T> &resultStore() const
186 { return static_cast<const QtConcurrent::ResultStore<T> &>(resultStoreBase()); }
187};
188
189template <typename T>
190inline void QFutureInterface<T>::reportResult(const T *result, int index)
191{
192 QMutexLocker locker(mutex());
193 if (this->queryState(Canceled) || this->queryState(Finished)) {
194 return;
195 }
196
197 QtConcurrent::ResultStore<T> &store = resultStore();
198
199
200 if (store.filterMode()) {
201 const int resultCountBefore = store.count();
202 store.addResult(index, result);
203 this->reportResultsReady(resultCountBefore, resultCountBefore + store.count());
204 } else {
205 const int insertIndex = store.addResult(index, result);
206 this->reportResultsReady(insertIndex, insertIndex + 1);
207 }
208}
209
210template <typename T>
211inline void QFutureInterface<T>::reportResult(const T &result, int index)
212{
213 reportResult(&result, index);
214}
215
216template <typename T>
217inline void QFutureInterface<T>::reportResults(const QVector<T> &_results, int beginIndex, int count)
218{
219 QMutexLocker locker(mutex());
220 if (this->queryState(Canceled) || this->queryState(Finished)) {
221 return;
222 }
223
224 QtConcurrent::ResultStore<T> &store = resultStore();
225
226 if (store.filterMode()) {
227 const int resultCountBefore = store.count();
228 store.addResults(beginIndex, &_results, count);
229 this->reportResultsReady(resultCountBefore, store.count());
230 } else {
231 const int insertIndex = store.addResults(beginIndex, &_results, count);
232 this->reportResultsReady(insertIndex, insertIndex + _results.count());
233 }
234}
235
236template <typename T>
237inline void QFutureInterface<T>::reportFinished(const T *result)
238{
239 if (result)
240 reportResult(result);
241 QFutureInterfaceBase::reportFinished();
242}
243
244template <typename T>
245inline const T &QFutureInterface<T>::resultReference(int index) const
246{
247 QMutexLocker lock(mutex());
248 return resultStore().resultAt(index).value();
249}
250
251template <typename T>
252inline const T *QFutureInterface<T>::resultPointer(int index) const
253{
254 QMutexLocker lock(mutex());
255 return resultStore().resultAt(index).pointer();
256}
257
258template <typename T>
259inline QList<T> QFutureInterface<T>::results()
260{
261 if (this->isCanceled()) {
262 exceptionStore().throwPossibleException();
263 return QList<T>();
264 }
265 QFutureInterfaceBase::waitForResult(-1);
266
267 QList<T> res;
268 QMutexLocker lock(mutex());
269
270 QtConcurrent::ResultIterator<T> it = resultStore().begin();
271 while (it != resultStore().end()) {
272 res.append(it.value());
273 ++it;
274 }
275
276 return res;
277}
278
279template <>
280class QFutureInterface<void> : public QFutureInterfaceBase
281{
282public:
283 QFutureInterface<void>(State initialState = NoState)
284 : QFutureInterfaceBase(initialState)
285 { }
286 QFutureInterface<void>(const QFutureInterface<void> &other)
287 : QFutureInterfaceBase(other)
288 { }
289
290 static QFutureInterface<void> canceledResult()
291 { return QFutureInterface(State(Started | Finished | Canceled)); }
292
293 QFutureInterface<void> &operator=(const QFutureInterface<void> &other)
294 {
295 QFutureInterfaceBase::operator=(other);
296 return *this;
297 }
298
299 inline QFuture<void> future(); // implemented in qfuture.h
300
301 void reportResult(const void *, int) { }
302 void reportResults(const QVector<void> &, int) { }
303 void reportFinished(void * = 0) { QFutureInterfaceBase::reportFinished(); }
304};
305
306QT_END_NAMESPACE
307QT_END_HEADER
308
309#endif // QT_NO_CONCURRENT
310
311#endif // QFUTUREINTERFACE_H
Note: See TracBrowser for help on using the repository browser.