1 | /**************************************************************************** |
2 | ** |
3 | ** Copyright (C) 2016 The Qt Company Ltd. |
4 | ** Contact: https://www.qt.io/licensing/ |
5 | ** |
6 | ** This file is part of the QtCore module of the Qt Toolkit. |
7 | ** |
8 | ** $QT_BEGIN_LICENSE:LGPL$ |
9 | ** Commercial License Usage |
10 | ** Licensees holding valid commercial Qt licenses may use this file in |
11 | ** accordance with the commercial license agreement provided with the |
12 | ** Software or, alternatively, in accordance with the terms contained in |
13 | ** a written agreement between you and The Qt Company. For licensing terms |
14 | ** and conditions see https://www.qt.io/terms-conditions. For further |
15 | ** information use the contact form at https://www.qt.io/contact-us. |
16 | ** |
17 | ** GNU Lesser General Public License Usage |
18 | ** Alternatively, this file may be used under the terms of the GNU Lesser |
19 | ** General Public License version 3 as published by the Free Software |
20 | ** Foundation and appearing in the file LICENSE.LGPL3 included in the |
21 | ** packaging of this file. Please review the following information to |
22 | ** ensure the GNU Lesser General Public License version 3 requirements |
23 | ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. |
24 | ** |
25 | ** GNU General Public License Usage |
26 | ** Alternatively, this file may be used under the terms of the GNU |
27 | ** General Public License version 2.0 or (at your option) the GNU General |
28 | ** Public license version 3 or any later version approved by the KDE Free |
29 | ** Qt Foundation. The licenses are as published by the Free Software |
30 | ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 |
31 | ** included in the packaging of this file. Please review the following |
32 | ** information to ensure the GNU General Public License requirements will |
33 | ** be met: https://www.gnu.org/licenses/gpl-2.0.html and |
34 | ** https://www.gnu.org/licenses/gpl-3.0.html. |
35 | ** |
36 | ** $QT_END_LICENSE$ |
37 | ** |
38 | ****************************************************************************/ |
39 | |
40 | #include "qfuturewatcher.h" |
41 | #include "qfuturewatcher_p.h" |
42 | |
43 | #include <QtCore/qcoreevent.h> |
44 | #include <QtCore/qcoreapplication.h> |
45 | #include <QtCore/qmetaobject.h> |
46 | #include <QtCore/qthread.h> |
47 | |
48 | QT_BEGIN_NAMESPACE |
49 | |
50 | /*! \class QFutureWatcher |
51 | \reentrant |
52 | \since 4.4 |
53 | |
54 | \inmodule QtCore |
55 | \ingroup thread |
56 | |
57 | \brief The QFutureWatcher class allows monitoring a QFuture using signals |
58 | and slots. |
59 | |
60 | QFutureWatcher provides information and notifications about a QFuture. Use |
61 | the setFuture() function to start watching a particular QFuture. The |
62 | future() function returns the future set with setFuture(). |
63 | |
64 | For convenience, several of QFuture's functions are also available in |
65 | QFutureWatcher: progressValue(), progressMinimum(), progressMaximum(), |
66 | progressText(), isStarted(), isFinished(), isRunning(), isCanceled(), |
67 | isSuspending(), isSuspended(), waitForFinished(), result(), and resultAt(). |
68 | The cancel(), setSuspended(), suspend(), resume(), and toggleSuspended() functions |
69 | are slots in QFutureWatcher. |
70 | |
71 | Status changes are reported via the started(), finished(), canceled(), |
72 | suspending(), suspended(), resumed(), resultReadyAt(), and resultsReadyAt() |
73 | signals. Progress information is provided from the progressRangeChanged(), |
74 | void progressValueChanged(), and progressTextChanged() signals. |
75 | |
76 | Throttling control is provided by the setPendingResultsLimit() function. |
77 | When the number of pending resultReadyAt() or resultsReadyAt() signals |
78 | exceeds the limit, the computation represented by the future will be |
79 | throttled automatically. The computation will resume once the number of |
80 | pending signals drops below the limit. |
81 | |
82 | Example: Starting a computation and getting a slot callback when it's |
83 | finished: |
84 | |
85 | \snippet code/src_corelib_thread_qfuturewatcher.cpp 0 |
86 | |
87 | Be aware that not all running asynchronous computations can be canceled or |
88 | suspended. For example, the future returned by QtConcurrent::run() cannot be |
89 | canceled; but the future returned by QtConcurrent::mappedReduced() can. |
90 | |
91 | QFutureWatcher<void> is specialized to not contain any of the result |
92 | fetching functions. Any QFuture<T> can be watched by a |
93 | QFutureWatcher<void> as well. This is useful if only status or progress |
94 | information is needed; not the actual result data. |
95 | |
96 | \sa QFuture, {Qt Concurrent} |
97 | */ |
98 | |
99 | /*! \fn template <typename T> QFutureWatcher<T>::QFutureWatcher(QObject *parent) |
100 | |
101 | Constructs a new QFutureWatcher with the given \a parent. Until a future is |
102 | set with setFuture(), the functions isStarted(), isCanceled(), and |
103 | isFinished() return \c true. |
104 | */ |
105 | QFutureWatcherBase::QFutureWatcherBase(QObject *parent) |
106 | :QObject(*new QFutureWatcherBasePrivate, parent) |
107 | { } |
108 | |
109 | /*! \fn template <typename T> QFutureWatcher<T>::~QFutureWatcher() |
110 | |
111 | Destroys the QFutureWatcher. |
112 | */ |
113 | |
114 | /*! \fn template <typename T> void QFutureWatcher<T>::cancel() |
115 | |
116 | Cancels the asynchronous computation represented by the future(). Note that |
117 | the cancelation is asynchronous. Use waitForFinished() after calling |
118 | cancel() when you need synchronous cancelation. |
119 | |
120 | Currently available results may still be accessed on a canceled QFuture, |
121 | but new results will \e not become available after calling this function. |
122 | Also, this QFutureWatcher will not deliver progress and result ready |
123 | signals once canceled. This includes the progressValueChanged(), |
124 | progressRangeChanged(), progressTextChanged(), resultReadyAt(), and |
125 | resultsReadyAt() signals. |
126 | |
127 | Be aware that not all running asynchronous computations can be canceled. |
128 | For example, the QFuture returned by QtConcurrent::run() cannot be |
129 | canceled; but the QFuture returned by QtConcurrent::mappedReduced() can. |
130 | */ |
131 | void QFutureWatcherBase::cancel() |
132 | { |
133 | futureInterface().cancel(); |
134 | } |
135 | |
136 | #if QT_DEPRECATED_SINCE(6, 0) |
137 | /*! \fn template <typename T> void QFutureWatcher<T>::setPaused(bool paused) |
138 | |
139 | \obsolete |
140 | Use setSuspended() instead. |
141 | |
142 | If \a paused is true, this function pauses the asynchronous computation |
143 | represented by the future(). If the computation is already paused, this |
144 | function does nothing. QFutureWatcher will not immediately stop delivering |
145 | progress and result ready signals when the future is paused. At the moment |
146 | of pausing there may still be computations that are in progress and cannot |
147 | be stopped. Signals for such computations will still be delivered after |
148 | pause. |
149 | |
150 | If \a paused is false, this function resumes the asynchronous computation. |
151 | If the computation was not previously paused, this function does nothing. |
152 | |
153 | Be aware that not all computations can be paused. For example, the |
154 | QFuture returned by QtConcurrent::run() cannot be paused; but the QFuture |
155 | returned by QtConcurrent::mappedReduced() can. |
156 | |
157 | \sa pause(), resume(), togglePaused() |
158 | */ |
159 | void QFutureWatcherBase::setPaused(bool paused) |
160 | { |
161 | futureInterface().setSuspended(paused); |
162 | } |
163 | |
164 | /*! \fn template <typename T> void QFutureWatcher<T>::pause() |
165 | |
166 | \obsolete |
167 | Use suspend() instead. |
168 | |
169 | Pauses the asynchronous computation represented by the future(). This is a |
170 | convenience method that simply calls setPaused(true). |
171 | |
172 | \sa resume() |
173 | */ |
174 | void QFutureWatcherBase::pause() |
175 | { |
176 | futureInterface().setSuspended(true); |
177 | } |
178 | |
179 | #endif // QT_DEPRECATED_SINCE(6, 0) |
180 | |
181 | /*! \fn template <typename T> void QFutureWatcher<T>::setSuspended(bool suspend) |
182 | |
183 | \since 6.0 |
184 | |
185 | If \a suspend is true, this function suspends the asynchronous computation |
186 | represented by the future(). If the computation is already suspended, this |
187 | function does nothing. QFutureWatcher will not immediately stop delivering |
188 | progress and result ready signals when the future is suspended. At the moment |
189 | of suspending there may still be computations that are in progress and cannot |
190 | be stopped. Signals for such computations will still be delivered. |
191 | |
192 | If \a suspend is false, this function resumes the asynchronous computation. |
193 | If the computation was not previously suspended, this function does nothing. |
194 | |
195 | Be aware that not all computations can be suspended. For example, the |
196 | QFuture returned by QtConcurrent::run() cannot be suspended; but the QFuture |
197 | returned by QtConcurrent::mappedReduced() can. |
198 | |
199 | \sa suspend(), resume(), toggleSuspended() |
200 | */ |
201 | void QFutureWatcherBase::setSuspended(bool suspend) |
202 | { |
203 | futureInterface().setSuspended(suspend); |
204 | } |
205 | |
206 | /*! \fn template <typename T> void QFutureWatcher<T>::suspend() |
207 | |
208 | \since 6.0 |
209 | |
210 | Suspends the asynchronous computation represented by this future. This is a |
211 | convenience method that simply calls setSuspended(true). |
212 | |
213 | \sa resume() |
214 | */ |
215 | void QFutureWatcherBase::suspend() |
216 | { |
217 | futureInterface().setSuspended(true); |
218 | } |
219 | |
220 | /*! \fn template <typename T> void QFutureWatcher<T>::resume() |
221 | |
222 | Resumes the asynchronous computation represented by the future(). This is |
223 | a convenience method that simply calls setSuspended(false). |
224 | |
225 | \sa suspend() |
226 | */ |
227 | |
228 | void QFutureWatcherBase::resume() |
229 | { |
230 | futureInterface().setSuspended(false); |
231 | } |
232 | |
233 | #if QT_DEPRECATED_SINCE(6, 0) |
234 | /*! \fn template <typename T> void QFutureWatcher<T>::togglePaused() |
235 | |
236 | \obsolete |
237 | Use toggleSuspended() instead. |
238 | |
239 | Toggles the paused state of the asynchronous computation. In other words, |
240 | if the computation is currently paused, calling this function resumes it; |
241 | if the computation is running, it is paused. This is a convenience method |
242 | for calling setPaused(!isPaused()). |
243 | |
244 | \sa setPaused(), pause(), resume() |
245 | */ |
246 | void QFutureWatcherBase::togglePaused() |
247 | { |
248 | futureInterface().toggleSuspended(); |
249 | } |
250 | #endif // QT_DEPRECATED_SINCE(6, 0) |
251 | |
252 | /*! \fn template <typename T> void QFutureWatcher<T>::toggleSuspended() |
253 | |
254 | \since 6.0 |
255 | |
256 | Toggles the suspended state of the asynchronous computation. In other words, |
257 | if the computation is currently suspending or suspended, calling this |
258 | function resumes it; if the computation is running, it is suspended. This is a |
259 | convenience method for calling setSuspended(!(isSuspending() || isSuspended())). |
260 | |
261 | \sa setSuspended(), suspend(), resume() |
262 | */ |
263 | void QFutureWatcherBase::toggleSuspended() |
264 | { |
265 | futureInterface().toggleSuspended(); |
266 | } |
267 | |
268 | /*! \fn template <typename T> int QFutureWatcher<T>::progressValue() const |
269 | |
270 | Returns the current progress value, which is between the progressMinimum() |
271 | and progressMaximum(). |
272 | |
273 | \sa progressMinimum(), progressMaximum() |
274 | */ |
275 | int QFutureWatcherBase::progressValue() const |
276 | { |
277 | return futureInterface().progressValue(); |
278 | } |
279 | |
280 | /*! \fn template <typename T> int QFutureWatcher<T>::progressMinimum() const |
281 | |
282 | Returns the minimum progressValue(). |
283 | |
284 | \sa progressValue(), progressMaximum() |
285 | */ |
286 | int QFutureWatcherBase::progressMinimum() const |
287 | { |
288 | return futureInterface().progressMinimum(); |
289 | } |
290 | |
291 | /*! \fn template <typename T> int QFutureWatcher<T>::progressMaximum() const |
292 | |
293 | Returns the maximum progressValue(). |
294 | |
295 | \sa progressValue(), progressMinimum() |
296 | */ |
297 | int QFutureWatcherBase::progressMaximum() const |
298 | { |
299 | return futureInterface().progressMaximum(); |
300 | } |
301 | |
302 | /*! \fn template <typename T> QString QFutureWatcher<T>::progressText() const |
303 | |
304 | Returns the (optional) textual representation of the progress as reported |
305 | by the asynchronous computation. |
306 | |
307 | Be aware that not all computations provide a textual representation of the |
308 | progress, and as such, this function may return an empty string. |
309 | */ |
310 | QString QFutureWatcherBase::progressText() const |
311 | { |
312 | return futureInterface().progressText(); |
313 | } |
314 | |
315 | /*! \fn template <typename T> bool QFutureWatcher<T>::isStarted() const |
316 | |
317 | Returns \c true if the asynchronous computation represented by the future() |
318 | has been started, or if no future has been set; otherwise returns \c false. |
319 | */ |
320 | bool QFutureWatcherBase::isStarted() const |
321 | { |
322 | return futureInterface().queryState(QFutureInterfaceBase::Started); |
323 | } |
324 | |
325 | /*! \fn template <typename T> bool QFutureWatcher<T>::isFinished() const |
326 | |
327 | Returns \c true if the asynchronous computation represented by the future() |
328 | has finished, or if no future has been set; otherwise returns \c false. |
329 | */ |
330 | bool QFutureWatcherBase::isFinished() const |
331 | { |
332 | Q_D(const QFutureWatcherBase); |
333 | return d->finished; |
334 | } |
335 | |
336 | /*! \fn template <typename T> bool QFutureWatcher<T>::isRunning() const |
337 | |
338 | Returns \c true if the asynchronous computation represented by the future() |
339 | is currently running; otherwise returns \c false. |
340 | */ |
341 | bool QFutureWatcherBase::isRunning() const |
342 | { |
343 | return futureInterface().queryState(QFutureInterfaceBase::Running); |
344 | } |
345 | |
346 | /*! \fn template <typename T> bool QFutureWatcher<T>::isCanceled() const |
347 | |
348 | Returns \c true if the asynchronous computation has been canceled with the |
349 | cancel() function, or if no future has been set; otherwise returns \c false. |
350 | |
351 | Be aware that the computation may still be running even though this |
352 | function returns \c true. See cancel() for more details. |
353 | */ |
354 | bool QFutureWatcherBase::isCanceled() const |
355 | { |
356 | return futureInterface().queryState(QFutureInterfaceBase::Canceled); |
357 | } |
358 | |
359 | #if QT_DEPRECATED_SINCE(6, 0) |
360 | |
361 | /*! \fn template <typename T> bool QFutureWatcher<T>::isPaused() const |
362 | |
363 | \obsolete |
364 | Use isSuspending() or isSuspended() instead. |
365 | |
366 | Returns \c true if the asynchronous computation has been paused with the |
367 | pause() function; otherwise returns \c false. |
368 | |
369 | Be aware that the computation may still be running even though this |
370 | function returns \c true. See setPaused() for more details. To check |
371 | if pause actually took effect, use isSuspended() instead. |
372 | |
373 | \sa setPaused(), togglePaused(), isSuspended() |
374 | */ |
375 | |
376 | bool QFutureWatcherBase::isPaused() const |
377 | { |
378 | QT_WARNING_PUSH |
379 | QT_WARNING_DISABLE_DEPRECATED |
380 | return futureInterface().isPaused(); |
381 | QT_WARNING_POP |
382 | } |
383 | #endif // QT_DEPRECATED_SINCE(6, 0) |
384 | |
385 | /*! \fn template <typename T> bool QFutureWatcher<T>::isSuspending() const |
386 | |
387 | \since 6.0 |
388 | |
389 | Returns \c true if the asynchronous computation has been suspended with the |
390 | suspend() function, but the work is not yet suspended, and computation is still |
391 | running. Returns \c false otherwise. |
392 | |
393 | To check if suspension is actually in effect, use isSuspended() instead. |
394 | |
395 | \sa setSuspended(), toggleSuspended(), isSuspended() |
396 | */ |
397 | bool QFutureWatcherBase::isSuspending() const |
398 | { |
399 | return futureInterface().isSuspending(); |
400 | } |
401 | |
402 | /*! \fn template <typename T> bool QFutureWatcher<T>::isSuspended() const |
403 | |
404 | \since 6.0 |
405 | |
406 | Returns \c true if a suspension of the asynchronous computation has been |
407 | requested, and it is in effect, meaning that no more results or progress |
408 | changes are expected. |
409 | |
410 | \sa suspended(), setSuspended(), isSuspending() |
411 | */ |
412 | bool QFutureWatcherBase::isSuspended() const |
413 | { |
414 | return futureInterface().isSuspended(); |
415 | } |
416 | |
417 | /*! \fn template <typename T> void QFutureWatcher<T>::waitForFinished() |
418 | |
419 | Waits for the asynchronous computation to finish (including cancel()ed |
420 | computations), i.e. until isFinished() returns \c true. |
421 | */ |
422 | void QFutureWatcherBase::waitForFinished() |
423 | { |
424 | futureInterface().waitForFinished(); |
425 | } |
426 | |
427 | bool QFutureWatcherBase::event(QEvent *event) |
428 | { |
429 | Q_D(QFutureWatcherBase); |
430 | if (event->type() == QEvent::FutureCallOut) { |
431 | QFutureCallOutEvent *callOutEvent = static_cast<QFutureCallOutEvent *>(event); |
432 | d->sendCallOutEvent(callOutEvent); |
433 | return true; |
434 | } |
435 | return QObject::event(event); |
436 | } |
437 | |
438 | /*! \fn template <typename T> void QFutureWatcher<T>::setPendingResultsLimit(int limit) |
439 | |
440 | The setPendingResultsLimit() provides throttling control. When the number |
441 | of pending resultReadyAt() or resultsReadyAt() signals exceeds the |
442 | \a limit, the computation represented by the future will be throttled |
443 | automatically. The computation will resume once the number of pending |
444 | signals drops below the \a limit. |
445 | */ |
446 | void QFutureWatcherBase::setPendingResultsLimit(int limit) |
447 | { |
448 | Q_D(QFutureWatcherBase); |
449 | d->maximumPendingResultsReady = limit; |
450 | } |
451 | |
452 | void QFutureWatcherBase::connectNotify(const QMetaMethod &signal) |
453 | { |
454 | Q_D(QFutureWatcherBase); |
455 | static const QMetaMethod resultReadyAtSignal = QMetaMethod::fromSignal(&QFutureWatcherBase::resultReadyAt); |
456 | if (signal == resultReadyAtSignal) |
457 | d->resultAtConnected.ref(); |
458 | #ifndef QT_NO_DEBUG |
459 | static const QMetaMethod finishedSignal = QMetaMethod::fromSignal(&QFutureWatcherBase::finished); |
460 | if (signal == finishedSignal) { |
461 | if (futureInterface().isRunning()) { |
462 | //connections should be established before calling stFuture to avoid race. |
463 | // (The future could finish before the connection is made.) |
464 | qWarning("QFutureWatcher::connect: connecting after calling setFuture() is likely to produce race" ); |
465 | } |
466 | } |
467 | #endif |
468 | } |
469 | |
470 | void QFutureWatcherBase::disconnectNotify(const QMetaMethod &signal) |
471 | { |
472 | Q_D(QFutureWatcherBase); |
473 | static const QMetaMethod resultReadyAtSignal = QMetaMethod::fromSignal(&QFutureWatcherBase::resultReadyAt); |
474 | if (signal == resultReadyAtSignal) |
475 | d->resultAtConnected.deref(); |
476 | } |
477 | |
478 | /*! |
479 | \internal |
480 | */ |
481 | QFutureWatcherBasePrivate::QFutureWatcherBasePrivate() |
482 | : maximumPendingResultsReady(QThread::idealThreadCount() * 2), |
483 | resultAtConnected(0), |
484 | finished(true) /* the initial m_future is a canceledResult(), with Finished set */ |
485 | { } |
486 | |
487 | /*! |
488 | \internal |
489 | */ |
490 | void QFutureWatcherBase::connectOutputInterface() |
491 | { |
492 | futureInterface().d->connectOutputInterface(d_func()); |
493 | } |
494 | |
495 | /*! |
496 | \internal |
497 | */ |
498 | void QFutureWatcherBase::disconnectOutputInterface(bool pendingAssignment) |
499 | { |
500 | if (pendingAssignment) { |
501 | Q_D(QFutureWatcherBase); |
502 | d->pendingResultsReady.storeRelaxed(0); |
503 | d->finished = false; /* May soon be amended, during connectOutputInterface() */ |
504 | } |
505 | |
506 | futureInterface().d->disconnectOutputInterface(d_func()); |
507 | } |
508 | |
509 | void QFutureWatcherBasePrivate::postCallOutEvent(const QFutureCallOutEvent &callOutEvent) |
510 | { |
511 | Q_Q(QFutureWatcherBase); |
512 | |
513 | if (callOutEvent.callOutType == QFutureCallOutEvent::ResultsReady) { |
514 | if (pendingResultsReady.fetchAndAddRelaxed(1) >= maximumPendingResultsReady) |
515 | q->futureInterface().d->internal_setThrottled(true); |
516 | } |
517 | |
518 | QCoreApplication::postEvent(q, callOutEvent.clone()); |
519 | } |
520 | |
521 | void QFutureWatcherBasePrivate::callOutInterfaceDisconnected() |
522 | { |
523 | QCoreApplication::removePostedEvents(q_func(), QEvent::FutureCallOut); |
524 | } |
525 | |
526 | void QFutureWatcherBasePrivate::sendCallOutEvent(QFutureCallOutEvent *event) |
527 | { |
528 | Q_Q(QFutureWatcherBase); |
529 | |
530 | switch (event->callOutType) { |
531 | case QFutureCallOutEvent::Started: |
532 | emit q->started(); |
533 | break; |
534 | case QFutureCallOutEvent::Finished: |
535 | finished = true; |
536 | emit q->finished(); |
537 | break; |
538 | case QFutureCallOutEvent::Canceled: |
539 | pendingResultsReady.storeRelaxed(0); |
540 | emit q->canceled(); |
541 | break; |
542 | case QFutureCallOutEvent::Suspending: |
543 | if (q->futureInterface().isCanceled()) |
544 | break; |
545 | emit q->suspending(); |
546 | #if QT_DEPRECATED_SINCE(6, 0) |
547 | QT_WARNING_PUSH |
548 | QT_WARNING_DISABLE_DEPRECATED |
549 | emit q->paused(); |
550 | QT_WARNING_POP |
551 | #endif |
552 | break; |
553 | case QFutureCallOutEvent::Suspended: |
554 | if (q->futureInterface().isCanceled()) |
555 | break; |
556 | emit q->suspended(); |
557 | break; |
558 | case QFutureCallOutEvent::Resumed: |
559 | if (q->futureInterface().isCanceled()) |
560 | break; |
561 | emit q->resumed(); |
562 | break; |
563 | case QFutureCallOutEvent::ResultsReady: { |
564 | if (q->futureInterface().isCanceled()) |
565 | break; |
566 | |
567 | if (pendingResultsReady.fetchAndAddRelaxed(-1) <= maximumPendingResultsReady) |
568 | q->futureInterface().setThrottled(false); |
569 | |
570 | const int beginIndex = event->index1; |
571 | const int endIndex = event->index2; |
572 | |
573 | emit q->resultsReadyAt(beginIndex, endIndex); |
574 | |
575 | if (resultAtConnected.loadRelaxed() <= 0) |
576 | break; |
577 | |
578 | for (int i = beginIndex; i < endIndex; ++i) |
579 | emit q->resultReadyAt(i); |
580 | |
581 | } break; |
582 | case QFutureCallOutEvent::Progress: |
583 | if (q->futureInterface().isCanceled()) |
584 | break; |
585 | |
586 | emit q->progressValueChanged(event->index1); |
587 | if (!event->text.isNull()) // ### |
588 | emit q->progressTextChanged(event->text); |
589 | break; |
590 | case QFutureCallOutEvent::ProgressRange: |
591 | emit q->progressRangeChanged(event->index1, event->index2); |
592 | break; |
593 | default: break; |
594 | } |
595 | } |
596 | |
597 | |
598 | /*! \fn template <typename T> const T &QFutureWatcher<T>::result() const |
599 | |
600 | Returns the first result in the future(). If the result is not immediately |
601 | available, this function will block and wait for the result to become |
602 | available. This is a convenience method for calling resultAt(0). |
603 | |
604 | \sa resultAt() |
605 | */ |
606 | |
607 | /*! \fn template <typename T> const T &QFutureWatcher<T>::resultAt(int index) const |
608 | |
609 | Returns the result at \a index in the future(). If the result is not |
610 | immediately available, this function will block and wait for the result to |
611 | become available. |
612 | |
613 | \sa result() |
614 | */ |
615 | |
616 | /*! \fn template <typename T> void QFutureWatcher<T>::setFuture(const QFuture<T> &future) |
617 | |
618 | Starts watching the given \a future. |
619 | |
620 | One of the signals might be emitted for the current state of the |
621 | \a future. For example, if the future is already stopped, the |
622 | finished signal will be emitted. |
623 | |
624 | To avoid a race condition, it is important to call this function |
625 | \e after doing the connections. |
626 | */ |
627 | |
628 | /*! \fn template <typename T> QFuture<T> QFutureWatcher<T>::future() const |
629 | |
630 | Returns the watched future. |
631 | */ |
632 | |
633 | /*! \fn template <typename T> void QFutureWatcher<T>::started() |
634 | |
635 | This signal is emitted when this QFutureWatcher starts watching the future |
636 | set with setFuture(). |
637 | */ |
638 | |
639 | /*! |
640 | \fn template <typename T> void QFutureWatcher<T>::finished() |
641 | This signal is emitted when the watched future finishes. |
642 | */ |
643 | |
644 | /*! |
645 | \fn template <typename T> void QFutureWatcher<T>::canceled() |
646 | This signal is emitted if the watched future is canceled. |
647 | */ |
648 | |
649 | /*! \fn template <typename T> void QFutureWatcher<T>::suspending() |
650 | |
651 | \since 6.0 |
652 | |
653 | This signal is emitted when the state of the watched future is |
654 | set to suspended. |
655 | |
656 | \note This signal only informs that suspension has been requested. It |
657 | doesn't indicate that all background operations are stopped. Signals |
658 | for computations that were in progress at the moment of suspending will |
659 | still be delivered. To be informed when suspension actually |
660 | took effect, use the suspended() signal. |
661 | |
662 | \sa setSuspended(), suspend(), suspended() |
663 | */ |
664 | |
665 | #if QT_DEPRECATED_SINCE(6, 0) |
666 | /*! \fn template <typename T> void QFutureWatcher<T>::paused() |
667 | |
668 | \obsolete |
669 | Use suspending() instead. |
670 | |
671 | This signal is emitted when the state of the watched future is |
672 | set to paused. |
673 | |
674 | \note This signal only informs that pause has been requested. It |
675 | doesn't indicate that all background operations are stopped. Signals |
676 | for computations that were in progress at the moment of pausing will |
677 | still be delivered. To to be informed when pause() actually |
678 | took effect, use the suspended() signal. |
679 | |
680 | \sa setPaused(), pause(), suspended() |
681 | */ |
682 | #endif // QT_DEPRECATED_SINCE(6, 0) |
683 | |
684 | /*! \fn template <typename T> void QFutureWatcher<T>::suspended() |
685 | |
686 | \since 6.0 |
687 | |
688 | This signal is emitted when suspend() took effect, meaning that there are |
689 | no more running computations. After receiving this signal no more result |
690 | ready or progress reporting signals are expected. |
691 | |
692 | \sa setSuspended(), suspend(), suspended() |
693 | */ |
694 | |
695 | /*! \fn template <typename T> void QFutureWatcher<T>::resumed() |
696 | This signal is emitted when the watched future is resumed. |
697 | */ |
698 | |
699 | /*! |
700 | \fn template <typename T> void QFutureWatcher<T>::progressRangeChanged(int minimum, int maximum) |
701 | |
702 | The progress range for the watched future has changed to \a minimum and |
703 | \a maximum |
704 | */ |
705 | |
706 | /*! |
707 | \fn template <typename T> void QFutureWatcher<T>::progressValueChanged(int progressValue) |
708 | |
709 | This signal is emitted when the watched future reports progress, |
710 | \a progressValue gives the current progress. In order to avoid overloading |
711 | the GUI event loop, QFutureWatcher limits the progress signal emission |
712 | rate. This means that listeners connected to this slot might not get all |
713 | progress reports the future makes. The last progress update (where |
714 | \a progressValue equals the maximum value) will always be delivered. |
715 | */ |
716 | |
717 | /*! \fn template <typename T> void QFutureWatcher<T>::progressTextChanged(const QString &progressText) |
718 | |
719 | This signal is emitted when the watched future reports textual progress |
720 | information, \a progressText. |
721 | */ |
722 | |
723 | /*! |
724 | \fn template <typename T> void QFutureWatcher<T>::resultReadyAt(int index) |
725 | |
726 | This signal is emitted when the watched future reports a ready result at |
727 | \a index. If the future reports multiple results, the index will indicate |
728 | which one it is. Results can be reported out-of-order. To get the result, |
729 | call resultAt(index); |
730 | */ |
731 | |
732 | /*! |
733 | \fn template <typename T> void QFutureWatcher<T>::resultsReadyAt(int beginIndex, int endIndex); |
734 | |
735 | This signal is emitted when the watched future reports ready results. |
736 | The results are indexed from \a beginIndex to \a endIndex. |
737 | |
738 | */ |
739 | |
740 | QT_END_NAMESPACE |
741 | |
742 | #include "moc_qfuturewatcher.cpp" |
743 | |