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 #ifndef QFUTUREWATCHER_H 41 #define QFUTUREWATCHER_H 42 43 #include <QtCore/qfuture.h> 44 #include <QtCore/qobject.h> 45 46 QT_REQUIRE_CONFIG(future); 47 48 QT_BEGIN_NAMESPACE 49 50 51 class QEvent; 52 53 class QFutureWatcherBasePrivate; 54 class Q_CORE_EXPORT QFutureWatcherBase : public QObject 55 { 56 Q_OBJECT 57 Q_DECLARE_PRIVATE(QFutureWatcherBase) 58 59 public: 60 explicit QFutureWatcherBase(QObject *parent = nullptr); 61 // de-inline dtor 62 63 int progressValue() const; 64 int progressMinimum() const; 65 int progressMaximum() const; 66 QString progressText() const; 67 68 bool isStarted() const; 69 bool isFinished() const; 70 bool isRunning() const; 71 bool isCanceled() const; 72 bool isPaused() const; 73 74 void waitForFinished(); 75 76 void setPendingResultsLimit(int limit); 77 78 bool event(QEvent *event) override; 79 80 Q_SIGNALS: 81 void started(); 82 void finished(); 83 void canceled(); 84 void paused(); 85 void resumed(); 86 void resultReadyAt(int resultIndex); 87 void resultsReadyAt(int beginIndex, int endIndex); 88 void progressRangeChanged(int minimum, int maximum); 89 void progressValueChanged(int progressValue); 90 void progressTextChanged(const QString &progressText); 91 92 public Q_SLOTS: 93 void cancel(); 94 void setPaused(bool paused); 95 void pause(); 96 void resume(); 97 void togglePaused(); 98 99 protected: 100 void connectNotify (const QMetaMethod &signal) override; 101 void disconnectNotify (const QMetaMethod &signal) override; 102 103 // called from setFuture() implemented in template sub-classes 104 void connectOutputInterface(); 105 void disconnectOutputInterface(bool pendingAssignment = false); 106 107 private: 108 // implemented in the template sub-classes 109 virtual const QFutureInterfaceBase &futureInterface() const = 0; 110 virtual QFutureInterfaceBase &futureInterface() = 0; 111 }; 112 113 template <typename T> 114 class QFutureWatcher : public QFutureWatcherBase 115 { 116 public: 117 explicit QFutureWatcher(QObject *_parent = nullptr) QFutureWatcherBase(_parent)118 : QFutureWatcherBase(_parent) 119 { } ~QFutureWatcher()120 ~QFutureWatcher() 121 { disconnectOutputInterface(); } 122 123 void setFuture(const QFuture<T> &future); future()124 QFuture<T> future() const 125 { return m_future; } 126 result()127 T result() const { return m_future.result(); } resultAt(int index)128 T resultAt(int index) const { return m_future.resultAt(index); } 129 130 #ifdef Q_QDOC 131 int progressValue() const; 132 int progressMinimum() const; 133 int progressMaximum() const; 134 QString progressText() const; 135 136 bool isStarted() const; 137 bool isFinished() const; 138 bool isRunning() const; 139 bool isCanceled() const; 140 bool isPaused() const; 141 142 void waitForFinished(); 143 144 void setPendingResultsLimit(int limit); 145 146 Q_SIGNALS: 147 void started(); 148 void finished(); 149 void canceled(); 150 void paused(); 151 void resumed(); 152 void resultReadyAt(int resultIndex); 153 void resultsReadyAt(int beginIndex, int endIndex); 154 void progressRangeChanged(int minimum, int maximum); 155 void progressValueChanged(int progressValue); 156 void progressTextChanged(const QString &progressText); 157 158 public Q_SLOTS: 159 void cancel(); 160 void setPaused(bool paused); 161 void pause(); 162 void resume(); 163 void togglePaused(); 164 #endif 165 166 private: 167 QFuture<T> m_future; futureInterface()168 const QFutureInterfaceBase &futureInterface() const override { return m_future.d; } futureInterface()169 QFutureInterfaceBase &futureInterface() override { return m_future.d; } 170 }; 171 172 template <typename T> setFuture(const QFuture<T> & _future)173Q_INLINE_TEMPLATE void QFutureWatcher<T>::setFuture(const QFuture<T> &_future) 174 { 175 if (_future == m_future) 176 return; 177 178 disconnectOutputInterface(true); 179 m_future = _future; 180 connectOutputInterface(); 181 } 182 183 template <> 184 class QFutureWatcher<void> : public QFutureWatcherBase 185 { 186 public: 187 explicit QFutureWatcher(QObject *_parent = nullptr) QFutureWatcherBase(_parent)188 : QFutureWatcherBase(_parent) 189 { } ~QFutureWatcher()190 ~QFutureWatcher() 191 { disconnectOutputInterface(); } 192 193 void setFuture(const QFuture<void> &future); future()194 QFuture<void> future() const 195 { return m_future; } 196 197 private: 198 QFuture<void> m_future; futureInterface()199 const QFutureInterfaceBase &futureInterface() const override { return m_future.d; } futureInterface()200 QFutureInterfaceBase &futureInterface() override { return m_future.d; } 201 }; 202 setFuture(const QFuture<void> & _future)203Q_INLINE_TEMPLATE void QFutureWatcher<void>::setFuture(const QFuture<void> &_future) 204 { 205 if (_future == m_future) 206 return; 207 208 disconnectOutputInterface(true); 209 m_future = _future; 210 connectOutputInterface(); 211 } 212 213 QT_END_NAMESPACE 214 215 #endif // QFUTUREWATCHER_H 216