Applied initial patches for wx2.8 compatibility
[ctsim.git] / src / backgroundsupr.cpp
index 4083c8220f8647253b19f44aa124c2bd8eae9bb3..c4720770bdc310051a4cd6da8fa4e212881d5d2a 100644 (file)
@@ -9,7 +9,7 @@
 **  This is part of the CTSim program
 **  Copyright (C) 1983-2001 Kevin Rosenberg
 **
-**  $Id: backgroundsupr.cpp,v 1.7 2001/02/25 19:24:01 kevin Exp $
+**  $Id$
 **
 **  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
@@ -31,6 +31,9 @@
 #include "wx/wx.h"
 #endif
 
+// pragma line required for Fedora 4 and wxWin 2.4.2
+#pragma implementation "timer.h"
+
 #include "ct.h"
 #include "ctsim.h"
 #include "docs.h"
 #include "backgroundsupr.h"
 #include "backgroundmgr.h"
 
-#if defined(HAVE_CONFIG_H)
-#include "config.h"
-#endif
+#ifdef HAVE_WXTHREADS
 
+#define USE_BKGMGR 1
 
 ////////////////////////////////////////////////////////////////////////////
 //
 
 IMPLEMENT_DYNAMIC_CLASS(BackgroundSupervisor, wxEvtHandler)
 BEGIN_EVENT_TABLE(BackgroundSupervisor, BackgroundSupervisor)
-EVT_MENU(MSG_BACKGROUND_SUPERVISOR_CANCEL, BackgroundSupervisor::OnCancel)
-EVT_MENU(MSG_WORKER_THREAD_FAIL, BackgroundSupervisor::OnWorkerFail)
-EVT_MENU(MSG_WORKER_THREAD_DONE, BackgroundSupervisor::OnWorkerDone)
-EVT_MENU(MSG_WORKER_THREAD_UNIT_TICK, BackgroundSupervisor::OnWorkerUnitTick)
-EVT_MENU(MSG_DOCUMENT_ACK_REMOVE, BackgroundSupervisor::OnAckDocumentRemove)
 END_EVENT_TABLE()
 
-// Static function
-void 
-BackgroundSupervisor::cancelSupervisor (BackgroundSupervisor* pSupervisor)
-{
-  wxCommandEvent cancelEvent (wxEVT_COMMAND_MENU_SELECTED, MSG_BACKGROUND_SUPERVISOR_CANCEL);
-  wxPostEvent (pSupervisor, cancelEvent);
-}
 
 
-BackgroundSupervisor::BackgroundSupervisor (wxFrame* pParentFrame, wxDocument* pDocument, const char* const pszProcessTitle, int iTotalUnits)
-    : m_pParentFrame(pParentFrame), m_pDocument(pDocument), m_pDialogProgress(NULL), m_strProcessTitle(pszProcessTitle), 
-    m_iTotalUnits(iTotalUnits), m_iNumThreads(0), m_bDone(false), m_bFail(false), m_bCancelled(false), 
-    m_pTimer(NULL), m_bBackgroundTaskAdded(false), m_bWorkersDeleted(false),
-    wxEvtHandler()
+BackgroundSupervisor::BackgroundSupervisor (SupervisorThread* pMyThread, wxWindow* pParentFrame, BackgroundProcessingDocument* pDocument, wxChar const* pszProcessTitle, int iTotalUnits)
+    : wxEvtHandler(), m_pMyThread(pMyThread), m_pParentFrame(pParentFrame), m_pDocument(pDocument), m_strProcessTitle(pszProcessTitle),
+    m_iTotalUnits(iTotalUnits), m_iNumThreads(0), m_bDone(false), m_bFail(false), m_bCancelled(false), m_iRunning(0),
+    m_pTimer(NULL), m_bWorkersDeleted(false), m_bBackgroundManagerAdded(false)
 {
   m_iNumThreads = theApp->getNumberCPU();
-//    ++m_iNumThreads;
+  //   ++m_iNumThreads;
 
-  m_vecpThreads.reserve (m_iNumThreads);
+  m_vecpThreads.resize (m_iNumThreads);
   for (int iThread = 0; iThread < m_iNumThreads; iThread++)
     m_vecpThreads[iThread] = NULL;
 
@@ -84,20 +73,9 @@ BackgroundSupervisor::BackgroundSupervisor (wxFrame* pParentFrame, wxDocument* p
 
 BackgroundSupervisor::~BackgroundSupervisor()
 {
-  if (m_bBackgroundTaskAdded) {
-    wxCommandEvent doneEvent (wxEVT_COMMAND_MENU_SELECTED, MSG_BACKGROUND_SUPERVISOR_REMOVE);
-    doneEvent.SetClientData (this);
-    wxPostEvent (theApp->getBackgroundManager(), doneEvent);
-    wxPostEvent (m_pDocument, doneEvent);
-  }
-
-  while (m_bBackgroundTaskAdded) {
-    m_pMyThread->Sleep(50);
-    ProcessPendingEvents();
-  }
+  m_pDocument->removeBackgroundSupervisor (this);
 
   delete m_pTimer;
-  delete m_pDialogProgress;
 }
 
 void
@@ -107,139 +85,132 @@ BackgroundSupervisor::deleteWorkers()
   if (m_bWorkersDeleted)
     return;
 
-  for (int i = 0; i < m_iNumThreads; i++) 
-    if (m_vecpThreads[i]) {
-      m_vecpThreads[i]->Delete(); // sends Destroy message to workers
-  }
+  for (int i = 0; i < m_iNumThreads; i++)
+    if (m_vecpThreads[i])
+      m_vecpThreads[i]->Delete(); // send Destroy message to workers
 
-  while (m_iRunning > 0) {
+#ifdef USE_BKGMGR
+  wxCommandEvent doneEvent (wxEVT_COMMAND_MENU_SELECTED, MSG_BACKGROUND_SUPERVISOR_REMOVE);
+  doneEvent.SetClientData (this);
+  wxPostEvent (theApp->getBackgroundManager(), doneEvent);
+#endif
+
+  while (m_iRunning > 0 || m_bBackgroundManagerAdded)
     m_pMyThread->Sleep(50);
-    ProcessPendingEvents();
-  }
-  m_iRunning = 0;
+
   m_bWorkersDeleted = true;
 }
 
+void
+BackgroundSupervisor::ackRemoveBackgroundManager()
+{
+  m_bBackgroundManagerAdded = false;
+}
+
 bool
 BackgroundSupervisor::start()
 {
   int iBaseUnits = m_iTotalUnits / m_iNumThreads;
   int iExtraUnits = m_iTotalUnits % m_iNumThreads;
+  int iStartUnit = 0;
   for (int iThread = 0; iThread < m_iNumThreads; iThread++) {
-    int iStartUnit = iThread * iBaseUnits;
     int iNumUnits = iBaseUnits;
     if (iThread < iExtraUnits)
       ++iNumUnits;
     m_vecpThreads[iThread] = createWorker (iThread, iStartUnit, iNumUnits);
     if (! m_vecpThreads[iThread]) {
       m_bFail = true;
-      m_strFailMessage = "createWorker returned NULL [BackgroundSupervisor]";
+      m_strFailMessage = _T("createWorker returned NULL [BackgroundSupervisor]");
       break;
     }
     if (m_vecpThreads[iThread]->Create () != wxTHREAD_NO_ERROR) {
       m_bFail = true;
-      m_strFailMessage = "Thread creation failed [BackgroundSupervisor]";
+      m_strFailMessage = _T("Thread creation failed [BackgroundSupervisor]");
       break;
     }
-    m_vecpThreads[iThread]->SetPriority (40);
+   m_vecpThreads[iThread]->SetPriority (40);
+   iStartUnit += iNumUnits;
   }
   if (m_bFail)
     return false;
 
   m_pTimer = new Timer;
-  
-  if (! theApp->getUseBackgroundTasks())
-    m_pDialogProgress = new wxProgressDialog (_T("Filtered Backprojection"), _T("Reconstruction Progress"), 
-    m_iTotalUnits, m_pParentFrame, wxPD_CAN_ABORT | wxPD_AUTO_HIDE);
-  else {
-    std::string strLabel (m_strProcessTitle);
-    strLabel += " ";
-    strLabel += m_pParentFrame->GetTitle();
-    wxCommandEvent addTaskEvent (wxEVT_COMMAND_MENU_SELECTED, MSG_BACKGROUND_SUPERVISOR_ADD);
-    addTaskEvent.SetString (strLabel.c_str());
-    addTaskEvent.SetInt (m_iTotalUnits);
-    addTaskEvent.SetClientData (this);
-    wxPostEvent (theApp->getBackgroundManager(), addTaskEvent);
-    wxPostEvent (m_pDocument, addTaskEvent);
-    m_bBackgroundTaskAdded = true;
-  }
-  
+
+  wxString strLabel (m_strProcessTitle);
+  strLabel += _T(" ");
+  strLabel += dynamic_cast<wxFrame*>(m_pParentFrame)->GetTitle();
+
+#ifdef USE_BKGMGR
+  wxCommandEvent addTaskEvent (wxEVT_COMMAND_MENU_SELECTED, MSG_BACKGROUND_SUPERVISOR_ADD);
+  addTaskEvent.SetString (strLabel);
+  addTaskEvent.SetInt (m_iTotalUnits);
+  addTaskEvent.SetClientData (this);
+  wxPostEvent (theApp->getBackgroundManager(), addTaskEvent);
+#endif
+
+  m_pDocument->addBackgroundSupervisor (this);
+  m_bBackgroundManagerAdded = true;
+
   m_iRunning = m_iNumThreads;
   m_iUnitsDone = 0;
 
   for (int i = 0; i < m_iNumThreads; i++)
     m_vecpThreads[i]->Run();
-    
+
   return true;
 }
 
 void
-BackgroundSupervisor::OnCancel(wxCommandEvent& event)
+BackgroundSupervisor::onCancel()
 {
   m_bCancelled = true;
   m_bDone = true;
-  deleteWorkers();
 }
 
-void
-BackgroundSupervisor::OnAckDocumentRemove(wxCommandEvent& event)
-{
-  m_bBackgroundTaskAdded = false;
-}
 
 void
-BackgroundSupervisor::OnWorkerUnitTick (wxCommandEvent& event)
+BackgroundSupervisor::onWorkerUnitTick ()
 {
     ++m_iUnitsDone;
-    
-#ifdef DEBUG
-    if (theApp->getVerboseLogging())
-      *theApp->getLog() << "Units done: " << static_cast<int>(m_iUnitsDone) <<"\n";
+
+#ifdef USE_BKGMGR
+    wxCommandEvent addTaskEvent (wxEVT_COMMAND_MENU_SELECTED, MSG_BACKGROUND_SUPERVISOR_UNIT_TICK);
+    addTaskEvent.SetInt (m_iUnitsDone - 1);
+    addTaskEvent.SetClientData (this);
+    wxPostEvent (theApp->getBackgroundManager(), addTaskEvent);
 #endif
-    
-    if (m_pDialogProgress) {
-      if (! m_pDialogProgress->Update (m_iUnitsDone - 1)) {
-        wxCommandEvent dummy;
-        OnCancel (dummy);
-      }
-    } else {
-      wxCommandEvent addTaskEvent (wxEVT_COMMAND_MENU_SELECTED, MSG_BACKGROUND_SUPERVISOR_UNIT_TICK);
-      addTaskEvent.SetInt (m_iUnitsDone - 1);
-      addTaskEvent.SetClientData (this);
-      wxPostEvent (theApp->getBackgroundManager(), addTaskEvent);
-    }
 }
 
 void
-BackgroundSupervisor::OnWorkerDone (wxCommandEvent& event)
+BackgroundSupervisor::onWorkerDone (int iThread)
 {
+        wxCriticalSection critsectDone;
+        critsectDone.Enter();
+
   m_iRunning--;
-  wxASSERT (m_iRunning >= 0);
 
 #ifdef DEBUG
   if (theApp->getVerboseLogging()) {
     wxString msg;
-    msg.Printf("Background Supervisor: Thread finished. Remaining threads: %d\n", m_iRunning);  
+    msg.Printf(_T("Background Supervisor: Thread finished. Remaining threads: %d\n"), m_iRunning);
     wxCommandEvent eventLog (wxEVT_COMMAND_MENU_SELECTED, MAINMENU_LOG_EVENT );
     eventLog.SetString( msg );
     wxPostEvent( theApp->getMainFrame(), eventLog ); // send log event
   }
 #endif
-  if (m_iRunning <= 0 && ! m_bCancelled) {
-    deleteWorkers();
-    onDone();
-  }
+
+  critsectDone.Leave();
 }
 
 void
-BackgroundSupervisor::OnWorkerFail (wxCommandEvent& event)
+BackgroundSupervisor::onWorkerFail (int iThread, const wxString& strFailMessage)
 {
   m_iRunning--;
   wxCommandEvent eventLog( wxEVT_COMMAND_MENU_SELECTED, MAINMENU_LOG_EVENT );
-  eventLog.SetString( event.GetString() );
+  eventLog.SetString( strFailMessage );
   wxPostEvent( theApp->getMainFrame(), eventLog ); // send log event
 
-  wxCommandEvent dummy;
-  OnCancel(dummy);
+  onCancel();
 }
 
+#endif // HAVE_WXTHREADS