Isis 3 Programmer Reference
ConcurrentControlNetReader.cpp
1 
7 /* SPDX-License-Identifier: CC0-1.0 */
8 
9 #include "ConcurrentControlNetReader.h"
10 
11 #include <algorithm>
12 #include <iostream>
13 
14 #include <QDebug>
15 #include <QFuture>
16 #include <QFutureWatcher>
17 #include <QString>
18 #include <QtConcurrentRun>
19 #include <QtConcurrentMap>
20 #include <QtCore>
21 #include <QTimer>
22 
23 #include "Control.h"
24 #include "ControlNet.h"
25 #include "FileName.h"
26 #include "IString.h"
27 #include "Progress.h"
28 #include "IException.h"
29 
30 using std::cerr;
31 using std::cout;
32 using std::swap;
33 
34 namespace Isis {
35 
40  nullify();
41 
42  m_mappedRunning = false;
43 
44  m_progressBar = new ProgressBar("Reading Control Nets");
46 
47  initProgress();
48 
49  connect(m_watcher, SIGNAL(finished()), this, SLOT(mappedFinished()));
50  }
51 
52 
57 
58  if (m_watcher)
59  {
60  m_watcher->cancel();
61  m_watcher->waitForFinished();
62  }
63 
64  delete m_watcher;
65  m_watcher = NULL;
66 
67  delete m_progressBar;
68  }
69 
70 
71  ProgressBar *ConcurrentControlNetReader::progressBar() {
72  return m_progressBar;
73  }
74 
75 
79  void ConcurrentControlNetReader::read(QString filename) {
80 
81  m_backlog.append(filename);
82 
83  if (!m_progressBar.isNull()) {
84  m_progressBar->setRange(0, m_progressBar->maximum() + 1);
85  }
86 
87  start();
88  }
89 
90 
95 
96  m_backlog.append(filenames);
97 
98  if (!m_progressBar.isNull()) {
99  m_progressBar->setRange(0, m_progressBar->maximum() + filenames.size());
100  }
101 
102  start();
103  }
104 
105 
110  m_watcher = NULL;
111  }
112 
113 
114  void ConcurrentControlNetReader::initProgress() {
115  if (m_progressBar) {
116  m_progressBar->setVisible(false);
117  m_progressBar->setRange(0, 100);
118  m_progressBar->setValue(0);
119  }
120  }
121 
122 
123  void ConcurrentControlNetReader::start() {
124 
125  if (!m_backlog.isEmpty() && !m_mappedRunning) {
126 
127  QList< QPair<FileName, Progress *> > functorInput;
128  foreach (QString backlogFileName, m_backlog) {
129  Progress *progress = new Progress;
130  progress->DisableAutomaticDisplay();
131  m_progress.append(progress);
132 
133  functorInput.append(qMakePair(FileName(backlogFileName), progress));
134  }
135 
136  QFuture<Control *> networks = QtConcurrent::mapped(functorInput,
137  FileNameToControlFunctor(QThread::currentThread()));
138 
139  try {
140  networks.result();
141  }
142  catch (IException &e) {
143  throw e;
144  }
145 
146  if (!m_progressBar.isNull()) {
147  m_progressBar->setVisible(true);
148  }
149 
150  delete m_progressUpdateTimer;
151 
152  m_watcher->setFuture(networks);
153  m_mappedRunning = true;
154  m_backlog.clear();
155 
156  m_progressUpdateTimer = new QTimer;
157  connect(m_progressUpdateTimer, SIGNAL(timeout()),
158  this, SLOT(updateProgressValue()));
159  m_progressUpdateTimer->start(100);
160  }
161  }
162 
163 
164  void ConcurrentControlNetReader::updateProgressValue() {
165  if (!m_mappedRunning) {
166  foreach (Progress *progress, m_progress) {
167  delete progress;
168  }
169 
170  m_progress.clear();
171  }
172 
173  int progressMin = 0;
174  int progressMax = (m_progress.count() + m_backlog.count()) * 1000;
175  int progressCurrent = 0;
176 
177  foreach (Progress *progress, m_progress) {
178  if (progress->MaximumSteps()) {
179  if (progress->CurrentStep() < progress->MaximumSteps()) {
180  double progressPercent = progress->CurrentStep() / (double)progress->MaximumSteps();
181 
182  progressCurrent += qFloor(progressPercent * 1000);
183  }
184  else {
185  progressCurrent += 1000;
186  }
187  }
188  }
189 
190  if (m_progressBar) {
191  if (progressMax > 0) {
192  m_progressBar->setRange(progressMin, progressMax);
193  m_progressBar->setValue(progressCurrent);
194  }
195  else {
196  m_progressBar->setRange(0, 100);
197  m_progressBar->setValue(100);
198  }
199  }
200  }
201 
202 
203  void ConcurrentControlNetReader::mappedFinished() {
204  m_mappedRunning = false;
205 
206  delete m_progressUpdateTimer;
207  updateProgressValue();
208 
209  QList<Control *> networks(m_watcher->future().results());
210  emit networksReady(networks);
211 
212  if (!m_backlog.isEmpty()) {
213  start();
214  }
215  else {
216  initProgress();
217  }
218  }
219 
220 
221  ConcurrentControlNetReader::FileNameToControlFunctor::FileNameToControlFunctor(
222  QThread *targetThread) {
223  m_targetThread = targetThread;
224  }
225 
226 
227  ConcurrentControlNetReader::FileNameToControlFunctor::FileNameToControlFunctor(
228  const FileNameToControlFunctor & other) {
229  m_targetThread = other.m_targetThread;
230  }
231 
232 
233  ConcurrentControlNetReader::FileNameToControlFunctor::~FileNameToControlFunctor() {
234  m_targetThread = NULL;
235  }
236 
237 
238  Control * ConcurrentControlNetReader::FileNameToControlFunctor::operator()(
239  const QPair<FileName, Progress *> &fileNameAndProgress) const {
240 
241  QString fileNameString = fileNameAndProgress.first.expanded();
242  Progress *progress = fileNameAndProgress.second;
243 
244  ControlNet *newCnet = new ControlNet(fileNameString, progress);
245  Control *result = new Control(newCnet, fileNameString);
246 
247  newCnet->setParent(result);
248  result->moveToThread(m_targetThread);
249 
250  return result;
251  }
252 
253 
254  ConcurrentControlNetReader::FileNameToControlFunctor &
255  ConcurrentControlNetReader::FileNameToControlFunctor::operator=(
256  const FileNameToControlFunctor &rhs) {
257  m_targetThread = rhs.m_targetThread;
258  return *this;
259  }
260 }
Isis::ConcurrentControlNetReader::nullify
void nullify()
Initializes members to NULL.
Definition: ConcurrentControlNetReader.cpp:109
QList
This is free and unencumbered software released into the public domain.
Definition: BoxcarCachingAlgorithm.h:13
Isis::ProgressBar
Definition: ProgressBar.h:15
Isis::ConcurrentControlNetReader::~ConcurrentControlNetReader
~ConcurrentControlNetReader()
This destructor will cancel all running threads and block.
Definition: ConcurrentControlNetReader.cpp:56
Isis::ConcurrentControlNetReader::ConcurrentControlNetReader
ConcurrentControlNetReader()
Allocates memory at construction instead of as needed.
Definition: ConcurrentControlNetReader.cpp:39
QStringList
QThread
QPair
This is free and unencumbered software released into the public domain.
Definition: CubeIoHandler.h:23
QFutureWatcher
This is free and unencumbered software released into the public domain.
Definition: AbstractTableModel.h:24
Isis::ConcurrentControlNetReader::read
void read(QString filename)
Definition: ConcurrentControlNetReader.cpp:79
Isis::ConcurrentControlNetReader::m_watcher
QFutureWatcher< Control * > * m_watcher
provides SIGNALS / SLOTS for FileNameToControlFunctor
Definition: ConcurrentControlNetReader.h:69
Isis
This is free and unencumbered software released into the public domain.
Definition: Apollo.h:16