Go to the
documentation of this file.
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042 #ifndef QFUTUREINTERFACE_H
00043 #define QFUTUREINTERFACE_H
00044
00045 #include <QtCore/qglobal.h>
00046 #include <QtCore/qrunnable.h>
00047
00048 #ifndef QT_NO_QFUTURE
00049
00050 #include <QtCore/qmutex.h>
00051 #include <QtCore/qtconcurrentexception.h>
00052 #include <QtCore/qtconcurrentresultstore.h>
00053
00054 QT_BEGIN_HEADER
00055 QT_BEGIN_NAMESPACE
00056
00057 QT_MODULE(Core)
00058
00059 template <typename T> class QFuture;
00060 class QFutureInterfaceBasePrivate;
00061 class QFutureWatcherBase;
00062 class QFutureWatcherBasePrivate;
00063
00064 class Q_CORE_EXPORT QFutureInterfaceBase
00065 {
00066 public:
00067 enum State {
00068 NoState = 0x00,
00069 Running = 0x01,
00070 Started = 0x02,
00071 Finished = 0x04,
00072 Canceled = 0x08,
00073 Paused = 0x10,
00074 Throttled = 0x20
00075 };
00076
00077 QFutureInterfaceBase(State initialState = NoState);
00078 QFutureInterfaceBase(const QFutureInterfaceBase &other);
00079 virtual ~QFutureInterfaceBase();
00080
00081
00082 void reportStarted();
00083 void reportFinished();
00084 void reportCanceled();
00085 #ifndef QT_NO_EXCEPTIONS
00086 void reportException(const QtConcurrent::Exception &e);
00087 #endif
00088 void reportResultsReady(int beginIndex, int endIndex);
00089
00090 void setRunnable(QRunnable *runnable);
00091 void setFilterMode(bool enable);
00092 void setProgressRange(int minimum, int maximum);
00093 int progressMinimum() const;
00094 int progressMaximum() const;
00095 bool isProgressUpdateNeeded() const;
00096 void setProgressValue(int progressValue);
00097 int progressValue() const;
00098 void setProgressValueAndText(int progressValue, const QString &progressText);
00099 QString progressText() const;
00100
00101 void setExpectedResultCount(int resultCount);
00102 int expectedResultCount();
00103 int resultCount() const;
00104
00105 bool queryState(State state) const;
00106 bool isRunning() const;
00107 bool isStarted() const;
00108 bool isCanceled() const;
00109 bool isFinished() const;
00110 bool isPaused() const;
00111 bool isThrottled() const;
00112 bool isResultReadyAt(int index) const;
00113
00114 void cancel();
00115 void setPaused(bool paused);
00116 void togglePaused();
00117 void setThrottled(bool enable);
00118
00119 void waitForFinished();
00120 bool waitForNextResult();
00121 void waitForResult(int resultIndex);
00122 void waitForResume();
00123
00124 QMutex *mutex() const;
00125 QtConcurrent::internal::ExceptionStore &exceptionStore();
00126 QtConcurrent::ResultStoreBase &resultStoreBase();
00127 const QtConcurrent::ResultStoreBase &resultStoreBase() const;
00128
00129 inline bool operator==(const QFutureInterfaceBase &other) const { return d == other.d; }
00130 inline bool operator!=(const QFutureInterfaceBase &other) const { return d != other.d; }
00131 QFutureInterfaceBase &operator=(const QFutureInterfaceBase &other);
00132
00133 protected:
00134 bool referenceCountIsOne() const;
00135 public:
00136
00137 #ifndef QFUTURE_TEST
00138 private:
00139 #endif
00140 QFutureInterfaceBasePrivate *d;
00141
00142 private:
00143 friend class QFutureWatcherBase;
00144 friend class QFutureWatcherBasePrivate;
00145 };
00146
00147 template <typename T>
00148 class QFutureInterface : public QFutureInterfaceBase
00149 {
00150 public:
00151 QFutureInterface(State initialState = NoState)
00152 : QFutureInterfaceBase(initialState)
00153 { }
00154 QFutureInterface(const QFutureInterface &other)
00155 : QFutureInterfaceBase(other)
00156 { }
00157 ~QFutureInterface()
00158 {
00159 if (referenceCountIsOne())
00160 resultStore().clear();
00161 }
00162
00163 static QFutureInterface canceledResult()
00164 { return QFutureInterface(State(Started | Finished | Canceled)); }
00165
00166 QFutureInterface &operator=(const QFutureInterface &other)
00167 {
00168 if (referenceCountIsOne())
00169 resultStore().clear();
00170 QFutureInterfaceBase::operator=(other);
00171 return *this;
00172 }
00173
00174 inline QFuture<T> future();
00175
00176 inline void reportResult(const T *result, int index = -1);
00177 inline void reportResult(const T &result, int index = -1);
00178 inline void reportResults(const QVector<T> &results, int beginIndex = -1, int count = -1);
00179 inline void reportFinished(const T *result = 0);
00180
00181 inline const T &resultReference(int index) const;
00182 inline const T *resultPointer(int index) const;
00183 inline QList<T> results();
00184 private:
00185 QtConcurrent::ResultStore<T> &resultStore()
00186 { return static_cast<QtConcurrent::ResultStore<T> &>(resultStoreBase()); }
00187 const QtConcurrent::ResultStore<T> &resultStore() const
00188 { return static_cast<const QtConcurrent::ResultStore<T> &>(resultStoreBase()); }
00189 };
00190
00191 template <typename T>
00192 inline void QFutureInterface<T>::reportResult(const T *result, int index)
00193 {
00194 QMutexLocker locker(mutex());
00195 if (this->queryState(Canceled) || this->queryState(Finished)) {
00196 return;
00197 }
00198
00199 QtConcurrent::ResultStore<T> &store = resultStore();
00200
00201
00202 if (store.filterMode()) {
00203 const int resultCountBefore = store.count();
00204 store.addResult(index, result);
00205 this->reportResultsReady(resultCountBefore, resultCountBefore + store.count());
00206 } else {
00207 const int insertIndex = store.addResult(index, result);
00208 this->reportResultsReady(insertIndex, insertIndex + 1);
00209 }
00210 }
00211
00212 template <typename T>
00213 inline void QFutureInterface<T>::reportResult(const T &result, int index)
00214 {
00215 reportResult(&result, index);
00216 }
00217
00218 template <typename T>
00219 inline void QFutureInterface<T>::reportResults(const QVector<T> &_results, int beginIndex, int count)
00220 {
00221 QMutexLocker locker(mutex());
00222 if (this->queryState(Canceled) || this->queryState(Finished)) {
00223 return;
00224 }
00225
00226 QtConcurrent::ResultStore<T> &store = resultStore();
00227
00228 if (store.filterMode()) {
00229 const int resultCountBefore = store.count();
00230 store.addResults(beginIndex, &_results, count);
00231 this->reportResultsReady(resultCountBefore, store.count());
00232 } else {
00233 const int insertIndex = store.addResults(beginIndex, &_results, count);
00234 this->reportResultsReady(insertIndex, insertIndex + _results.count());
00235 }
00236 }
00237
00238 template <typename T>
00239 inline void QFutureInterface<T>::reportFinished(const T *result)
00240 {
00241 if (result)
00242 reportResult(result);
00243 QFutureInterfaceBase::reportFinished();
00244 }
00245
00246 template <typename T>
00247 inline const T &QFutureInterface<T>::resultReference(int index) const
00248 {
00249 QMutexLocker lock(mutex());
00250 return resultStore().resultAt(index).value();
00251 }
00252
00253 template <typename T>
00254 inline const T *QFutureInterface<T>::resultPointer(int index) const
00255 {
00256 QMutexLocker lock(mutex());
00257 return resultStore().resultAt(index).pointer();
00258 }
00259
00260 template <typename T>
00261 inline QList<T> QFutureInterface<T>::results()
00262 {
00263 if (this->isCanceled()) {
00264 exceptionStore().throwPossibleException();
00265 return QList<T>();
00266 }
00267 QFutureInterfaceBase::waitForResult(-1);
00268
00269 QList<T> res;
00270 QMutexLocker lock(mutex());
00271
00272 QtConcurrent::ResultIterator<T> it = resultStore().begin();
00273 while (it != resultStore().end()) {
00274 res.append(it.value());
00275 ++it;
00276 }
00277
00278 return res;
00279 }
00280
00281 template <>
00282 class QFutureInterface<void> : public QFutureInterfaceBase
00283 {
00284 public:
00285 QFutureInterface<void>(State initialState = NoState)
00286 : QFutureInterfaceBase(initialState)
00287 { }
00288 QFutureInterface<void>(const QFutureInterface<void> &other)
00289 : QFutureInterfaceBase(other)
00290 { }
00291
00292 static QFutureInterface<void> canceledResult()
00293 { return QFutureInterface(State(Started | Finished | Canceled)); }
00294
00295 QFutureInterface<void> &operator=(const QFutureInterface<void> &other)
00296 {
00297 QFutureInterfaceBase::operator=(other);
00298 return *this;
00299 }
00300
00301 inline QFuture<void> future();
00302
00303 void reportResult(const void *, int) { }
00304 void reportResults(const QVector<void> &, int) { }
00305 void reportFinished(void * = 0) { QFutureInterfaceBase::reportFinished(); }
00306 };
00307
00308 QT_END_NAMESPACE
00309 QT_END_HEADER
00310
00311 #endif // QT_NO_CONCURRENT
00312
00313 #endif // QFUTUREINTERFACE_H