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)173 Q_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)203 Q_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