9#include "ConcurrentControlNetReader.h" 
   16#include <QFutureWatcher> 
   18#include <QtConcurrentRun> 
   19#include <QtConcurrentMap> 
   24#include "ControlNet.h" 
   28#include "IException.h" 
   42    m_mappedRunning = 
false;
 
   44    m_progressBar = 
new ProgressBar(
"Reading Control Nets");
 
   45    m_watcher = 
new QFutureWatcher<Control *>;
 
   49    connect(
m_watcher, SIGNAL(finished()), 
this, SLOT(mappedFinished()));
 
 
   71  ProgressBar *ConcurrentControlNetReader::progressBar() {
 
   81    m_backlog.append(filename);
 
   83    if (!m_progressBar.isNull()) {
 
   84      m_progressBar->setRange(0, m_progressBar->maximum() + 1);
 
 
   96    m_backlog.append(filenames);
 
   98    if (!m_progressBar.isNull()) {
 
   99      m_progressBar->setRange(0, m_progressBar->maximum() + filenames.size());
 
 
  114  void ConcurrentControlNetReader::initProgress() {
 
  116      m_progressBar->setVisible(
false);
 
  117      m_progressBar->setRange(0, 100);
 
  118      m_progressBar->setValue(0);
 
  123  void ConcurrentControlNetReader::start() {
 
  125    if (!m_backlog.isEmpty() && !m_mappedRunning) {
 
  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);
 
  133        functorInput.append(qMakePair(FileName(backlogFileName), progress));
 
  136      QFuture<Control *> networks = QtConcurrent::mapped(functorInput,
 
  137                                    FileNameToControlFunctor(QThread::currentThread()));
 
  142      catch (IException &e) {
 
  146      if (!m_progressBar.isNull()) {
 
  147        m_progressBar->setVisible(
true);
 
  150      delete m_progressUpdateTimer;
 
  153      m_mappedRunning = 
true;
 
  156      m_progressUpdateTimer = 
new QTimer;
 
  157      connect(m_progressUpdateTimer, SIGNAL(timeout()),
 
  158              this, SLOT(updateProgressValue()));
 
  159      m_progressUpdateTimer->start(100);
 
  164  void ConcurrentControlNetReader::updateProgressValue() {
 
  165    if (!m_mappedRunning) {
 
  166      foreach (Progress *progress, m_progress) {
 
  174    int progressMax = (m_progress.count() + m_backlog.count()) * 1000;
 
  175    int progressCurrent = 0;
 
  177    foreach (Progress *progress, m_progress) {
 
  178      if (progress->MaximumSteps()) {
 
  179        if (progress->CurrentStep() < progress->MaximumSteps()) {
 
  180          double progressPercent = progress->CurrentStep() / (double)progress->MaximumSteps();
 
  182          progressCurrent += qFloor(progressPercent * 1000);
 
  185          progressCurrent += 1000;
 
  191      if (progressMax > 0) {
 
  192        m_progressBar->setRange(progressMin, progressMax);
 
  193        m_progressBar->setValue(progressCurrent);
 
  196        m_progressBar->setRange(0, 100);
 
  197        m_progressBar->setValue(100);
 
  203  void ConcurrentControlNetReader::mappedFinished() {
 
  204    m_mappedRunning = 
false;
 
  206    delete m_progressUpdateTimer;
 
  207    updateProgressValue();
 
  209    QList<Control *> networks(
m_watcher->future().results());
 
  210    emit networksReady(networks);
 
  212    if (!m_backlog.isEmpty()) {
 
  221  ConcurrentControlNetReader::FileNameToControlFunctor::FileNameToControlFunctor(
 
  223    m_targetThread = targetThread;
 
  227  ConcurrentControlNetReader::FileNameToControlFunctor::FileNameToControlFunctor(
 
  228      const FileNameToControlFunctor & other) {
 
  229    m_targetThread = other.m_targetThread;
 
  233  ConcurrentControlNetReader::FileNameToControlFunctor::~FileNameToControlFunctor() {
 
  234    m_targetThread = NULL;
 
  238  Control * ConcurrentControlNetReader::FileNameToControlFunctor::operator()(
 
  239      const QPair<FileName, Progress *> &fileNameAndProgress)
 const {
 
  241    QString fileNameString = fileNameAndProgress.first.expanded();
 
  242    Progress *progress = fileNameAndProgress.second;
 
  244    ControlNet *newCnet = 
new ControlNet(fileNameString, progress);
 
  245    Control *result = 
new Control(newCnet, fileNameString);
 
  247    newCnet->setParent(result);
 
  248    result->moveToThread(m_targetThread);
 
  254  ConcurrentControlNetReader::FileNameToControlFunctor &
 
  255      ConcurrentControlNetReader::FileNameToControlFunctor::operator=(
 
  256        const FileNameToControlFunctor &rhs) {
 
  257    m_targetThread = rhs.m_targetThread;
 
QFutureWatcher< Control * > * m_watcher
provides SIGNALS / SLOTS for FileNameToControlFunctor
 
void read(QString filename)
 
void nullify()
Initializes members to NULL.
 
ConcurrentControlNetReader()
Allocates memory at construction instead of as needed.
 
~ConcurrentControlNetReader()
This destructor will cancel all running threads and block.
 
This is free and unencumbered software released into the public domain.