r589: Added threaded rasterizer
[ctsim.git] / src / threadrecon.cpp
index 7a7b3ddb1c33f530bcd2a348851f8dd44f882fa1..2cd9dd1bda33475e1bbe711cb119d952d58440b6 100644 (file)
@@ -9,7 +9,7 @@
 **  This is part of the CTSim program
 **  Copyright (C) 1983-2001 Kevin Rosenberg
 **
-**  $Id: threadrecon.cpp,v 1.8 2001/02/25 06:32:12 kevin Exp $
+**  $Id: threadrecon.cpp,v 1.14 2001/02/27 03:59:30 kevin Exp $
 **
 **  This program is free software; you can redistribute it and/or modify
 **  it under the terms of the GNU General Public License (version 2) as
@@ -65,13 +65,13 @@ ReconstructorSupervisorThread::ReconstructorSupervisorThread (ProjectionFileView
 wxThread::ExitCode
 ReconstructorSupervisorThread::Entry()
 {
-  ReconstructorSupervisor reconSupervisor (m_pProjView, m_iNX, m_iNY, 
+  ReconstructorSupervisor reconSupervisor (this, m_pProjView, m_iNX, m_iNY, 
    m_strFilterName.c_str(), m_dFilterParam, m_strFilterMethod.c_str(), m_iZeropad, m_strFilterGenerationName.c_str(), 
    m_strInterpName.c_str(), m_iInterpParam, m_strBackprojectName.c_str(), m_strLabel.c_str());
 
   reconSupervisor.start();
   while (! reconSupervisor.isDone() && ! reconSupervisor.fail()) {
-    Sleep(50);
+    Sleep(100);
     Yield();
   }
   if (reconSupervisor.fail())
@@ -84,9 +84,9 @@ ReconstructorSupervisorThread::Entry()
     wxPostEvent( theApp->getMainFrame(), eventLog ); // send log event
   }
 
-  while (reconSupervisor.anyWorkersRunning()) {
+  while (! reconSupervisor.workersDeleted()) {
     Sleep(50);
-    Yield();
+    reconSupervisor.ProcessPendingEvents();
   }
 
   return reinterpret_cast<wxThread::ExitCode>(0);
@@ -104,7 +104,7 @@ ReconstructorSupervisorThread::OnExit()
 //
 /////////////////////////////////////////////////////////////////////
 
-ReconstructorSupervisor::ReconstructorSupervisor (ProjectionFileView* pProjView, 
+ReconstructorSupervisor::ReconstructorSupervisor (SupervisorThread* pThread, ProjectionFileView* pProjView, 
   int iImageNX, int iImageNY, const char* pszFilterName, double dFilterParam, const char* pszFilterMethod, 
   int iZeropad, const char* pszFilterGenerationName, const char* pszInterpName, int iInterpParam,
   const char* pszBackprojectName, const char* const pszLabel)
@@ -113,11 +113,11 @@ ReconstructorSupervisor::ReconstructorSupervisor (ProjectionFileView* pProjView,
       m_pszFilterName(pszFilterName), m_dFilterParam(dFilterParam), m_pszFilterMethod(pszFilterMethod),
       m_iZeropad(iZeropad), m_pszFilterGenerationName(pszFilterGenerationName), m_pszInterpName(pszInterpName),
       m_iInterpParam(iInterpParam), m_pszBackprojectName(pszBackprojectName), m_pszLabel(pszLabel), 
-      BackgroundSupervisor (pProjView->GetFrame(), pProjView->GetDocument(), "Reconstructing", pProjView->GetDocument()->getProjections().nView())
+      BackgroundSupervisor (pThread, pProjView->GetFrame(), pProjView->GetDocument(), "Reconstructing", pProjView->GetDocument()->getProjections().nView())
 {
   m_vecpChildImageFile.reserve (getNumWorkers());
   for (unsigned int iThread = 0; iThread < getNumWorkers(); iThread++) {
-    m_vecpChildImageFile[iThread] = new ImageFile (iImageNX, iImageNY);    
+    m_vecpChildImageFile[iThread] = new ImageFile (m_iImageNX, m_iImageNY);    
   }
 
 }
@@ -127,8 +127,7 @@ ReconstructorSupervisor::~ReconstructorSupervisor()
   for (int i = 0; i < getNumWorkers(); i++) {
       delete m_vecpChildImageFile[i];
       m_vecpChildImageFile[i] = NULL;
-    }    
-
+    }
 }
 
 BackgroundWorkerThread*
@@ -197,6 +196,7 @@ ReconstructorSupervisor::getImageFile()
 //
 /////////////////////////////////////////////////////////////////////
 
+void
 ReconstructorWorker::SetParameters (ProjectionFileView* pProjView, ImageFile* pImageFile, 
  const char* pszFilterName, double dFilterParam, const char* pszFilterMethod, int iZeropad,
  const char* pszFilterGenerationName, const char* pszInterpName, int iInterpParam, 
@@ -221,46 +221,52 @@ ReconstructorWorker::Entry ()
     *m_pImageFile, m_pszFilterName, m_dFilterParam, m_pszFilterMethod, m_iZeropad, 
     m_pszFilterGenerationName, m_pszInterpName, m_iInterpParam, m_pszBackprojectName, Trace::TRACE_NONE);
 
-  wxCommandEvent eventDone (wxEVT_COMMAND_MENU_SELECTED, BackgroundSupervisor::MSG_WORKER_THREAD_DONE);
-  eventDone.SetInt (m_iThread); // Send back thread# that has finished
-
-  if (pReconstructor->fail()) {
-      wxString msg("Unable to make reconstructor: ");
-      msg += pReconstructor->failMessage().c_str();  
+  bool bFail = pReconstructor->fail();
+  wxString failMsg;
+  if (bFail) {
+      failMsg = "Unable to make reconstructor: ";
+      failMsg += pReconstructor->failMessage().c_str();  
       wxCommandEvent event( wxEVT_COMMAND_MENU_SELECTED, MAINMENU_LOG_EVENT );
-      event.SetString( msg );
+      event.SetString( failMsg );
       wxPostEvent( theApp->getMainFrame(), event );
-
-      wxPostEvent (m_pSupervisor, eventDone);
-      return reinterpret_cast<wxThread::ExitCode>(-1);
   }
-
-  wxCommandEvent eventProgress (wxEVT_COMMAND_MENU_SELECTED, BackgroundSupervisor::MSG_WORKER_THREAD_UNIT_TICK);
-
-  for (int iUnit = 0; iUnit < m_iNumUnits; iUnit++) {
-    if (TestDestroy()) {
+  else
+  {
+    wxCommandEvent eventProgress (wxEVT_COMMAND_MENU_SELECTED, BackgroundSupervisor::MSG_WORKER_THREAD_UNIT_TICK);
+    for (int iUnit = 0; iUnit < m_iNumUnits; iUnit++) {
+      if (TestDestroy()) {
 #ifdef DEBUG
-      if (theApp->getVerboseLogging()) {
-        wxString msg;
-        msg.Printf("Worker thread: Received destroy message at work unit #%d\n", iUnit);  
-        wxCommandEvent event( wxEVT_COMMAND_MENU_SELECTED, MAINMENU_LOG_EVENT );
-        event.SetString( msg );
-        wxPostEvent( theApp->getMainFrame(), event ); 
-      }
+        if (theApp->getVerboseLogging()) {
+          wxString msg;
+          msg.Printf("Worker thread: Received destroy message at work unit #%d\n", iUnit);  
+          wxCommandEvent event( wxEVT_COMMAND_MENU_SELECTED, MAINMENU_LOG_EVENT );
+          event.SetString( msg );
+          wxPostEvent( theApp->getMainFrame(), event ); 
+        }
 #endif
-      delete pReconstructor;
-      wxPostEvent (m_pSupervisor, eventDone);
-  
-      return reinterpret_cast<wxThread::ExitCode>(-1);
+        break;
+      }
+      pReconstructor->reconstructView (iUnit + m_iStartUnit, 1);
+      m_pSupervisor->AddPendingEvent (eventProgress);
     }
-    pReconstructor->reconstructView (iUnit + m_iStartUnit, 1);
-    wxPostEvent (m_pSupervisor, eventProgress);
+    pReconstructor->postProcessing();
   }
-  pReconstructor->postProcessing();
-  
-  wxPostEvent (m_pSupervisor, eventDone);
-  
   delete pReconstructor;
+
+  if (bFail) {
+    wxCommandEvent eventFail (wxEVT_COMMAND_MENU_SELECTED, BackgroundSupervisor::MSG_WORKER_THREAD_FAIL);
+    eventFail.SetInt (m_iThread); // Send back thread# that has finished
+    eventFail.SetString (failMsg);
+    wxPostEvent (m_pSupervisor, eventFail);
+  } else {
+    wxCommandEvent eventDone (wxEVT_COMMAND_MENU_SELECTED, BackgroundSupervisor::MSG_WORKER_THREAD_DONE);
+    eventDone.SetInt (m_iThread); // Send back thread# that has finished
+    wxPostEvent (m_pSupervisor, eventDone);
+  }
+
+  while (! TestDestroy())
+    Sleep(100);
+
   return reinterpret_cast<wxThread::ExitCode>(0);
 }