diff align/ExternalProgramAligner.cpp @ 769:a316cb6fed81 pitch-align

Fixes to notification and completion in aligners
author Chris Cannam
date Thu, 28 May 2020 17:04:36 +0100
parents 6429a164b7e1
children 699b5b130ea2
line wrap: on
line diff
--- a/align/ExternalProgramAligner.cpp	Fri May 22 17:17:44 2020 +0100
+++ b/align/ExternalProgramAligner.cpp	Thu May 28 17:04:36 2020 +0100
@@ -63,6 +63,11 @@
         return;
     }
 
+    if (m_program == "") {
+        emit failed(m_toAlign, tr("No external program specified"));
+        return;
+    }
+
     while (!reference->isReady(nullptr) || !other->isReady(nullptr)) {
         qApp->processEvents();
     }
@@ -114,22 +119,25 @@
     if (!success) {
         
         SVCERR << "ERROR: ExternalProgramAligner: Program did not start" << endl;
+
+        other->setAlignment({});
+        ModelById::release(m_alignmentModel);
+        delete m_process;
+        m_process = nullptr;
+
         emit failed(m_toAlign,
                     tr("Alignment program \"%1\" did not start")
                     .arg(m_program));
         
-        other->setAlignment({});
-        ModelById::release(m_alignmentModel);
-        delete m_process;
-        m_process = nullptr;
-        
     } else {
+        alignmentModel->setCompletion(10);
         m_document->addNonDerivedModel(m_alignmentModel);
     }
 }
 
 void
-ExternalProgramAligner::programFinished(int  exitCode, QProcess::ExitStatus status)
+ExternalProgramAligner::programFinished(int exitCode,
+                                        QProcess::ExitStatus status)
 {
     SVCERR << "ExternalProgramAligner::programFinished" << endl;
     
@@ -147,6 +155,8 @@
                << endl;
         return;
     }
+
+    QString errorText;
     
     if (exitCode == 0 && status == 0) {
 
@@ -170,10 +180,9 @@
         if (!reader.isOK()) {
             SVCERR << "ERROR: ExternalProgramAligner: Failed to parse output"
                    << endl;
-            QString error = tr("Failed to parse output of program: %1")
+            errorText = tr("Failed to parse output of program: %1")
                 .arg(reader.getError());
-            alignmentModel->setError(error);
-            emit failed(m_toAlign, error);
+            alignmentModel->setError(errorText);
             goto done;
         }
 
@@ -186,22 +195,20 @@
         if (!path) {
             SVCERR << "ERROR: ExternalProgramAligner: Output did not convert to sparse time-value model"
                    << endl;
-            QString error =
+            errorText =
                 tr("Output of alignment program was not in the proper format");
-            alignmentModel->setError(error);
+            alignmentModel->setError(errorText);
             delete csvOutput;
-            emit failed(m_toAlign, error);
             goto done;
         }
                        
         if (path->isEmpty()) {
             SVCERR << "ERROR: ExternalProgramAligner: Output contained no mappings"
                    << endl;
-            QString error = 
+            errorText = 
                 tr("Output of alignment program contained no mappings");
-            alignmentModel->setError(error);
+            alignmentModel->setError(errorText);
             delete path;
-            emit failed(m_toAlign, error);
             goto done;
         }
 
@@ -211,8 +218,7 @@
         auto pathId =
             ModelById::add(std::shared_ptr<SparseTimeValueModel>(path));
         alignmentModel->setPathFrom(pathId);
-
-        emit complete(m_alignmentModel);
+        alignmentModel->setCompletion(100);
 
         ModelById::release(pathId);
         
@@ -220,12 +226,19 @@
         SVCERR << "ERROR: ExternalProgramAligner: Aligner program "
                << "failed: exit code " << exitCode << ", status " << status
                << endl;
-        QString error = tr("Aligner process returned non-zero exit status");
-        alignmentModel->setError(error);
-        emit failed(m_toAlign, error);
+        errorText = tr("Aligner process returned non-zero exit status");
+        alignmentModel->setError(errorText);
     }
 
 done:
     delete m_process;
     m_process = nullptr;
+
+    // "This should be emitted as the last thing the aligner does, as
+    // the recipient may delete the aligner during the call."
+    if (errorText == "") {
+        emit complete(m_alignmentModel);
+    } else {
+        emit failed(m_toAlign, errorText);
+    }
 }