1 /*=============================================================================
2
3 Library: CTK
4
5 Copyright (c) German Cancer Research Center,
6 Division of Medical and Biological Informatics
7
8 Licensed under the Apache License, Version 2.0 (the "License");
9 you may not use this file except in compliance with the License.
10 You may obtain a copy of the License at
11
12 http://www.apache.org/licenses/LICENSE-2.0
13
14 Unless required by applicable law or agreed to in writing, software
15 distributed under the License is distributed on an "AS IS" BASIS,
16 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 See the License for the specific language governing permissions and
18 limitations under the License.
19
20 =============================================================================*/
21
22 #ifndef CTKCMDLINEMODULEFUTUREINTERFACE_H
23 #define CTKCMDLINEMODULEFUTUREINTERFACE_H
24
25 #include <ctkCommandLineModulesCoreExport.h>
26
27 #include "ctkCmdLineModuleResult.h"
28
29 #include <QFutureInterface>
30 #if (QT_VERSION < QT_VERSION_CHECK(5, 0, 0))
31 #include <QtCore>
32 #else
33 #include <QtConcurrent>
34 #include <qresultstore.h>
35 #endif
36
37
38 class ctkCmdLineModuleFuture;
39 class ctkCmdLineModuleFutureInterfacePrivate;
40
41 /**
42 * \ingroup CommandLineModulesCore_API
43 *
44 * \brief A QFutureInterface specialization.
45 *
46 * This QFutureInterface must be used by custom backend implementations to retrieve
47 * a suitable QFuture object and to report state changes to it via this interface.
48 */
49 template <>
50 class CTK_CMDLINEMODULECORE_EXPORT QFutureInterface<ctkCmdLineModuleResult> : public QFutureInterfaceBase
51 {
52
53 public:
54
55 QFutureInterface(State initialState = NoState);
56
57 QFutureInterface(const QFutureInterface &other);
58
59 ~QFutureInterface();
60
61 static QFutureInterface canceledResult();
62
63 QFutureInterface& operator=(const QFutureInterface& other);
64
65 inline ctkCmdLineModuleFuture future(); // implemented in ctkCmdLineModuleFuture.h
66
67 bool canCancel() const;
68 void setCanCancel(bool canCancel);
69 bool canPause() const;
70 void setCanPause(bool canPause);
71
72 inline void reportResult(const ctkCmdLineModuleResult *result, int index = -1);
73 inline void reportResult(const ctkCmdLineModuleResult &result, int index = -1);
74 inline void reportResults(const QVector<ctkCmdLineModuleResult> &results, int beginIndex = -1, int count = -1);
75 inline void reportFinished(const ctkCmdLineModuleResult *result = 0);
76
77 void reportOutputData(const QByteArray& outputData);
78 void reportErrorData(const QByteArray& errorData);
79
80 inline const ctkCmdLineModuleResult &resultReference(int index) const;
81 inline const ctkCmdLineModuleResult *resultPointer(int index) const;
82 inline QList<ctkCmdLineModuleResult> results();
83
84 QByteArray outputData(int position = 0, int size = -1) const;
85 QByteArray errorData(int position = 0, int size = -1) const;
86
87 private:
88
89 friend struct ctkCmdLineModuleFutureWatcherPrivate;
90
91 #if (QT_VERSION < QT_VERSION_CHECK(5, 0, 0))
resultStore()92 QtConcurrent::ResultStore<ctkCmdLineModuleResult> &resultStore()
93 { return static_cast<QtConcurrent::ResultStore<ctkCmdLineModuleResult> &>(resultStoreBase()); }
resultStore()94 const QtConcurrent::ResultStore<ctkCmdLineModuleResult> &resultStore() const
95 { return static_cast<const QtConcurrent::ResultStore<ctkCmdLineModuleResult> &>(resultStoreBase()); }
96 #elif (QT_VERSION < QT_VERSION_CHECK(5, 9, 0))
resultStore()97 QtPrivate::ResultStore<ctkCmdLineModuleResult> &resultStore()
98 { return static_cast<QtPrivate::ResultStore<ctkCmdLineModuleResult> &>(resultStoreBase()); }
resultStore()99 const QtPrivate::ResultStore<ctkCmdLineModuleResult> &resultStore() const
100 { return static_cast<const QtPrivate::ResultStore<ctkCmdLineModuleResult> &>(resultStoreBase()); }
101 #else
resultStore()102 QtPrivate::ResultStoreBase &resultStore()
103 { return static_cast<QtPrivate::ResultStoreBase &>(resultStoreBase()); }
resultStore()104 const QtPrivate::ResultStoreBase &resultStore() const
105 { return static_cast<const QtPrivate::ResultStoreBase &>(resultStoreBase()); }
106 #endif
107
108 ctkCmdLineModuleFutureInterfacePrivate* d;
109 };
110
reportResult(const ctkCmdLineModuleResult * result,int index)111 inline void QFutureInterface<ctkCmdLineModuleResult>::reportResult(const ctkCmdLineModuleResult *result, int index)
112 {
113 QMutexLocker locker(mutex());
114 if (this->queryState(Canceled) || this->queryState(Finished)) {
115 return;
116 }
117
118 #if (QT_VERSION < QT_VERSION_CHECK(5, 0, 0))
119 QtConcurrent::ResultStore<ctkCmdLineModuleResult> &store = resultStore();
120 #elif (QT_VERSION < QT_VERSION_CHECK(5, 9, 0))
121 QtPrivate::ResultStore<ctkCmdLineModuleResult> &store = resultStore();
122 #else
123 QtPrivate::ResultStoreBase &store = resultStore();
124 #endif
125
126 if (store.filterMode()) {
127 const int resultCountBefore = store.count();
128 store.addResult(index, result);
129 this->reportResultsReady(resultCountBefore, resultCountBefore + store.count());
130 } else {
131 const int insertIndex = store.addResult(index, result);
132 this->reportResultsReady(insertIndex, insertIndex + 1);
133 }
134 }
135
reportResult(const ctkCmdLineModuleResult & result,int index)136 inline void QFutureInterface<ctkCmdLineModuleResult>::reportResult(const ctkCmdLineModuleResult &result, int index)
137 {
138 reportResult(&result, index);
139 }
140
reportResults(const QVector<ctkCmdLineModuleResult> & _results,int beginIndex,int count)141 inline void QFutureInterface<ctkCmdLineModuleResult>::reportResults(const QVector<ctkCmdLineModuleResult> &_results, int beginIndex, int count)
142 {
143 QMutexLocker locker(mutex());
144 if (this->queryState(Canceled) || this->queryState(Finished)) {
145 return;
146 }
147
148 #if (QT_VERSION < QT_VERSION_CHECK(5, 0, 0))
149 QtConcurrent::ResultStore<ctkCmdLineModuleResult> &store = resultStore();
150 #elif (QT_VERSION < QT_VERSION_CHECK(5, 9, 0))
151 QtPrivate::ResultStore<ctkCmdLineModuleResult> &store = resultStore();
152 #else
153 QtPrivate::ResultStoreBase &store = resultStore();
154 #endif
155
156 if (store.filterMode()) {
157 const int resultCountBefore = store.count();
158 store.addResults(beginIndex, &_results, count);
159 this->reportResultsReady(resultCountBefore, store.count());
160 } else {
161 const int insertIndex = store.addResults(beginIndex, &_results, count);
162 this->reportResultsReady(insertIndex, insertIndex + _results.count());
163 }
164 }
165
reportFinished(const ctkCmdLineModuleResult * result)166 inline void QFutureInterface<ctkCmdLineModuleResult>::reportFinished(const ctkCmdLineModuleResult *result)
167 {
168 if (result)
169 reportResult(result);
170 QFutureInterfaceBase::reportFinished();
171 }
172
resultReference(int index)173 inline const ctkCmdLineModuleResult &QFutureInterface<ctkCmdLineModuleResult>::resultReference(int index) const
174 {
175 QMutexLocker lock(mutex());
176 #if (QT_VERSION < QT_VERSION_CHECK(5, 9, 0))
177 return resultStore().resultAt(index).value();
178 #else
179 return resultStore().resultAt(index).value<ctkCmdLineModuleResult>();
180 #endif
181 }
182
resultPointer(int index)183 inline const ctkCmdLineModuleResult *QFutureInterface<ctkCmdLineModuleResult>::resultPointer(int index) const
184 {
185 QMutexLocker lock(mutex());
186 #if (QT_VERSION < QT_VERSION_CHECK(5, 9, 0))
187 return resultStore().resultAt(index).pointer();
188 #else
189 return resultStore().resultAt(index).pointer<ctkCmdLineModuleResult>();
190 #endif
191 }
192
results()193 inline QList<ctkCmdLineModuleResult> QFutureInterface<ctkCmdLineModuleResult>::results()
194 {
195 if (this->isCanceled()) {
196 exceptionStore().throwPossibleException();
197 return QList<ctkCmdLineModuleResult>();
198 }
199 QFutureInterfaceBase::waitForResult(-1);
200
201 QList<ctkCmdLineModuleResult> res;
202 QMutexLocker lock(mutex());
203
204 #if (QT_VERSION < QT_VERSION_CHECK(5, 0, 0))
205 QtConcurrent::ResultIterator<ctkCmdLineModuleResult> it = resultStore().begin();
206 #elif (QT_VERSION < QT_VERSION_CHECK(5, 9, 0))
207 QtPrivate::ResultIterator<ctkCmdLineModuleResult> it = resultStore().begin();
208 #else
209 QtPrivate::ResultIteratorBase it = resultStore().begin();
210 #endif
211 while (it != resultStore().end()) {
212 #if (QT_VERSION < QT_VERSION_CHECK(5, 9, 0))
213 res.append(it.value());
214 #else
215 res.append(it.value<ctkCmdLineModuleResult>());
216 #endif
217 ++it;
218 }
219
220 return res;
221 }
222
223 typedef QFutureInterface<ctkCmdLineModuleResult> ctkCmdLineModuleFutureInterface;
224
225 #endif // CTKCMDLINEMODULEFUTUREINTERFACE_H
226