X-Git-Url: http://git.kpe.io/?p=ctsim.git;a=blobdiff_plain;f=src%2Fthreadraster.cpp;fp=src%2Fthreadraster.cpp;h=00f89dc103c670901ba203ac60c9b97965407f1a;hp=0000000000000000000000000000000000000000;hb=432ba2c487a5320352f14bdd2cce008fccef6902;hpb=f1e69bf8888b1462007c93c8d6bf3ae1e0ecec20 diff --git a/src/threadraster.cpp b/src/threadraster.cpp new file mode 100644 index 0000000..00f89dc --- /dev/null +++ b/src/threadraster.cpp @@ -0,0 +1,232 @@ +/***************************************************************************** +** FILE IDENTIFICATION +** +** Name: threadraster.cpp +** Purpose: Threaded rasterizer class +** Programmer: Kevin Rosenberg +** Date Started: February 2001 +** +** This is part of the CTSim program +** Copyright (C) 1983-2001 Kevin Rosenberg +** +** $Id: threadraster.cpp,v 1.1 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 +** published by the Free Software Foundation. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with this program; if not, write to the Free Software +** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +******************************************************************************/ + +#include "wx/wxprec.h" + +#ifndef WX_PRECOMP +#include "wx/wx.h" +#endif + +#include "ct.h" +#include "ctsim.h" +#include "docs.h" +#include "views.h" +#include "threadraster.h" +#include "backgroundmgr.h" +#include "backgroundsupr.h" + +#if defined(HAVE_CONFIG_H) +#include "config.h" +#endif + + + +///////////////////////////////////////////////////////////////////// +// +// Class RasterizerSupervisorThread -- Thread for Background Supervisor +// +///////////////////////////////////////////////////////////////////// + +RasterizerSupervisorThread::RasterizerSupervisorThread (PhantomFileView* pProjView, int iNX, int iNY, + int iNSample, double dViewRatio, const char* const pszLabel) +: m_pPhantomView(pProjView), m_iNX(iNX), m_iNY(iNY), m_iNSample(iNSample), m_dViewRatio(dViewRatio), m_strLabel(pszLabel), + SupervisorThread() +{ +} + +wxThread::ExitCode +RasterizerSupervisorThread::Entry() +{ + RasterizerSupervisor rasterSupervisor (this, m_pPhantomView, m_iNX, m_iNY, m_iNSample, m_dViewRatio, m_strLabel.c_str()); + + rasterSupervisor.start(); + while (! rasterSupervisor.isDone() && ! rasterSupervisor.fail()) { + Sleep(100); + Yield(); + } + if (rasterSupervisor.fail()) + { + wxString msg ("Error starting Rasterizer supervisor: "); + msg += rasterSupervisor.getFailMessage().c_str(); + msg += "\n"; + wxCommandEvent eventLog (wxEVT_COMMAND_MENU_SELECTED, MAINMENU_LOG_EVENT ); + eventLog.SetString( msg ); + wxPostEvent( theApp->getMainFrame(), eventLog ); // send log event + } + + while (! rasterSupervisor.workersDeleted()) { + Sleep(50); + rasterSupervisor.ProcessPendingEvents(); + } + + return reinterpret_cast(0); +} + +void +RasterizerSupervisorThread::OnExit() +{ +} + + +///////////////////////////////////////////////////////////////////// +// +// Class RasterizerSupervisor -- A Background Supervisor +// +///////////////////////////////////////////////////////////////////// + +RasterizerSupervisor::RasterizerSupervisor (SupervisorThread* pThread, PhantomFileView* pPhantomView, int iNX, int iNY, + int iNSample, double dViewRatio, const char* const pszLabel) + : m_pPhantomView(pPhantomView), m_pPhantomDoc(pPhantomView->GetDocument()), + m_iNX(iNX), m_iNY(iNY), m_iNSample(iNSample), m_dViewRatio(dViewRatio), m_pszLabel(pszLabel), + BackgroundSupervisor (pThread, pPhantomView->GetFrame(), pPhantomView->GetDocument(), "Rasterizing", iNX) +{ + m_vecpChildImageFiles.reserve (getNumWorkers()); + for (unsigned int iThread = 0; iThread < getNumWorkers(); iThread++) { + m_vecpChildImageFiles[iThread] = new ImageFile; + } + + + +} + +RasterizerSupervisor::~RasterizerSupervisor() +{ + for (int i = 0; i < getNumWorkers(); i++) + delete m_vecpChildImageFiles[i]; +} + +BackgroundWorkerThread* +RasterizerSupervisor::createWorker (int iThread, int iStartUnit, int iNumUnits) +{ + RasterizerWorker* pThread = new RasterizerWorker (this, iThread, iStartUnit, iNumUnits); + m_vecpChildImageFiles[iThread]->setArraySize (iNumUnits, m_iNY); + pThread->SetParameters (m_pPhantomView, m_vecpChildImageFiles[iThread], m_iNX, m_iNY, m_iNSample, m_dViewRatio); + + return pThread; +} + +void +RasterizerSupervisor::onDone() +{ + wxCriticalSection doneSection; + wxCriticalSectionLocker critsect (doneSection); + + ImageFileDocument* pImageDoc = theApp->newImageDoc(); + if (! pImageDoc) { + sys_error (ERR_SEVERE, "Unable to create image file"); + return; + } + + ImageFile* pImageFile = getImageFile(); + pImageDoc->setImageFile (pImageFile); + if (theApp->getAskDeleteNewDocs()) + pImageDoc->Modify (true); + pImageDoc->UpdateAllViews (NULL); + if (ImageFileView* imageView = pImageDoc->getView()) { + imageView->OnUpdate (imageView, NULL); + imageView->getFrame()->SetFocus(); + imageView->getFrame()->Show(true); + } + *theApp->getLog() << m_pszLabel << "\n"; + pImageFile->labelAdd (m_pszLabel, getTimerEnd()); + + setDone(); +} + + +ImageFile* +RasterizerSupervisor::getImageFile() +{ + ImageFile* pImageFile = new ImageFile (m_iNX, m_iNY); + + size_t iColSize = sizeof(ImageFileValue) * m_iNY; + + ImageFileArray globalArray = pImageFile->getArray(); + int iGlobalCol = 0; + for (int iw = 0; iw < getNumWorkers(); iw++) { + ImageFileArray childArray = m_vecpChildImageFiles[iw]->getArray(); + for (int iCol = 0; iCol < m_vecpChildImageFiles[iw]->nx(); iCol++) { + memcpy (globalArray[iGlobalCol++], childArray[iCol], iColSize); + } + } + return (pImageFile); +} + + +///////////////////////////////////////////////////////////////////// +// +// Class RasterizerWorker -- A worker thread +// +///////////////////////////////////////////////////////////////////// + +void +RasterizerWorker::SetParameters (PhantomFileView* pPhantomView, ImageFile* pImageFile, int iNX, int iNY, int iNSample, double dViewRatio) +{ + m_pImageFile = pImageFile; + m_iNX = iNX; + m_iNY = iNY; + m_pPhantomView = pPhantomView; + m_iNSample = iNSample; + m_dViewRatio = dViewRatio; +} + +wxThread::ExitCode +RasterizerWorker::Entry () +{ + const Phantom& rPhantom = m_pPhantomView->GetDocument()->getPhantom(); + 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 ); + } +#endif + break; + } + rPhantom.convertToImagefile (*m_pImageFile, m_iNX, m_dViewRatio, m_iNSample, Trace::TRACE_NONE, + iUnit + m_iStartUnit, 1, iUnit); + wxPostEvent (m_pSupervisor, eventProgress); + } + 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(0); +} + +void +RasterizerWorker::OnExit () +{ +}