Ejemplo n.º 1
0
void Do_Cooperate( int level )
{
  if ( level != 1 )
  {
    do
    {
    }
    while ( POVMS_ProcessMessages( POVMS_Render_Context, 0 ) - 1 );
    do
    {
    }
    while ( POVMS_ProcessMessages( POVMS_Output_Context, 0 ) - 1 );
  }
  return;
}
Ejemplo n.º 2
0
void vfeSession::WorkerThread()
{
  WorkerThreadStartup();

  if (POVMS_Init() == false)
    m_LastError = vfePOVMSInitFailed ;
  else if (POVMS_OpenContext (const_cast<void **>(&pov::POVMS_GUI_Context)) != kNoError)
    m_LastError = vfeOpenContextFailed ;
  else if (POVMS_GetContextAddress (pov::POVMS_GUI_Context, const_cast<void **>(&pov::GUIThreadAddr)) != kNoErr)
    m_LastError = vfeConnectFailed ;

  if (m_LastError != vfeNoError)
  {
    m_InitializeEvent.notify_all ();
    return;
  }

  m_BackendThread = povray_init (boost::bind(&vfeSession::BackendThreadNotify, this), const_cast<void **>(&pov::RenderThreadAddr)) ;
  POVMS_Output_Context = pov::POVMS_GUI_Context ;

  m_Console = shared_ptr<vfeConsole> (new vfeConsole(this, m_ConsoleWidth)) ;

  POVMS_Object obj ;
  m_Frontend = new VirtualFrontEnd (*this, POVMS_Output_Context, (POVMSAddress) pov::RenderThreadAddr, obj, NULL, m_Console) ;
  if (m_Frontend == NULL)
    throw POV_EXCEPTION_STRING ("Worker thread failed to create frontend");
  m_BackendState = m_Frontend->GetState();
  m_InitializeEvent.notify_all ();

  try
  {
    while (m_WorkerThreadShutdownRequest == false)
    {
      if (m_BackendThreadExited)
      {
        // the main thread (created by pov_init()) has exited. this is not good.
        // we could re-start it, but given it's only supposed to exit under critical
        // circumstances, we won't risk it and instead will alert the user. note that
        // if we are implementing a detached frontend and are not attached, this may
        // not be possible, but there's not a lot we can do about that.
        throw vfeCriticalError("Backend worker thread shut down prematurely: please re-start POV-Ray.");
      }
      try
      {
        while (POVMS_ProcessMessages (pov::POVMS_GUI_Context, true, true) == kFalseErr)
        {
          m_MessageCount++ ;
          ProcessFrontend () ;
          if (m_RenderCancelRequested == true || m_RequestFlag != rqNoRequest || m_WorkerThreadShutdownRequest == true)
            break ;
        }
        ProcessFrontend () ;
        if (m_RenderCancelRequested)
        {
          POV_LONG ts = GetTimestamp() + 2500;
          m_RenderCancelled = true;
          while (POVMS_ProcessMessages (pov::POVMS_GUI_Context, false, false) == kFalseErr)
          {
            ProcessFrontend () ;
            // don't allow it to take more than 2.5 seconds to process remaining messages
            // (this should not happen unless our thread priority is too low)
            if (GetTimestamp() > ts)
              break;
          }
          ProcessFrontend () ;
          if (ProcessCancelRender() == true)
            m_RenderCancelRequested = false;
        }
        if (m_RequestFlag != rqNoRequest)
        {
          int rq = m_RequestFlag;
          m_RequestFlag = rqNoRequest;
          switch (rq)
          {
            case rqPauseRequest:
              m_RequestResult = m_Frontend->Pause() ? 1 : 0;
              break;
            case rqResumeRequest:
              m_RequestResult = m_Frontend->Resume() ? 1 : 0;
              break;
          }
          m_RequestEvent.notify_all ();
        }
        boost::thread::yield();
      }
      catch (pov_base::Exception& e)
      {
        SetFailed();
        if (StopRender(e.what()) == false)
          m_RenderCancelRequested = true;
      }
      catch (vfeException& e)
      {
        SetFailed();
        if (StopRender(e.what()) == false)
          m_RenderCancelRequested = true;
      }
      catch (std::exception& e)
      {
        SetFailed();
        if (StopRender(e.what()) == false)
          m_RenderCancelRequested = true;
      }
    }
  }
  catch (vfeCriticalError& e)
  {
    m_HadCriticalError = true;
    m_Failed = true;
    m_LastError = vfeCaughtCriticalError;
    NotifyCriticalError (e.what(), e.Filename().c_str(), e.Line()) ;
  }
  catch (vfeException&)
  {
    m_Failed = true;
    m_LastError = vfeCaughtException;
  }
  catch (std::exception&)
  {
    m_Failed = true;
    m_LastError = vfeCaughtException;
  }
  if (m_LastError == vfeCaughtException || m_LastError == vfeCaughtCriticalError)
  {
    while (POVMS_ProcessMessages (pov::POVMS_GUI_Context, false, false) == kFalseErr)
      ProcessFrontend () ;
    ProcessFrontend () ;
    ProcessCancelRender() ;
  }
  if (m_LastError == vfeCaughtException || m_LastError == vfeCaughtCriticalError)
    NotifyEvent(stCriticalError|stRenderShutdown);

  try
  {
    delete m_Frontend;
    m_Frontend = NULL;
    WorkerThreadShutdown();
    m_Initialized = false;
    m_BackendThread = NULL;
    povray_terminate();
    POVMS_CloseContext (POVMS_Output_Context);
    m_CurrentSessionTemporaryHack = NULL;
    m_WorkerThreadExited = true;
    m_ShutdownEvent.notify_all ();
  }
  catch (std::runtime_error)
  {
    // typical cause of an exception here (at least if it is a POVException) is if the destruction
    // of m_Frontend takes too long. this can happen if there's a lot of memory blocks to free.
  }
}