Team Fortress 2 Source Code as on 22/4/2020
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

223 lines
3.9 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. // $NoKeywords: $
  6. //=============================================================================//
  7. #include "stdafx.h"
  8. #include "bsplightingthread.h"
  9. // memdbgon must be the last include file in a .cpp file!!!
  10. #include "tier0/memdbgon.h"
  11. // --------------------------------------------------------------------------- //
  12. // Global functions.
  13. // --------------------------------------------------------------------------- //
  14. IBSPLightingThread* CreateBSPLightingThread( IVRadDLL *pDLL )
  15. {
  16. CBSPLightingThread *pRet = new CBSPLightingThread;
  17. if( pRet->Init( pDLL ) )
  18. {
  19. return pRet;
  20. }
  21. else
  22. {
  23. delete pRet;
  24. return 0;
  25. }
  26. }
  27. DWORD WINAPI ThreadMainLoop_Static( LPVOID lpParameter )
  28. {
  29. return ((CBSPLightingThread*)lpParameter)->ThreadMainLoop();
  30. }
  31. // --------------------------------------------------------------------------- //
  32. // Static helpers.
  33. // --------------------------------------------------------------------------- //
  34. class CCSLock
  35. {
  36. public:
  37. CCSLock( CRITICAL_SECTION *pCS )
  38. {
  39. EnterCriticalSection( pCS );
  40. m_pCS = pCS;
  41. }
  42. ~CCSLock()
  43. {
  44. LeaveCriticalSection( m_pCS );
  45. }
  46. CRITICAL_SECTION *m_pCS;
  47. };
  48. // --------------------------------------------------------------------------- //
  49. //
  50. // --------------------------------------------------------------------------- //
  51. CBSPLightingThread::CBSPLightingThread()
  52. {
  53. InitializeCriticalSection( &m_CS );
  54. m_hThread = 0;
  55. m_ThreadID = 0;
  56. m_ThreadCmd = THREADCMD_NONE;
  57. m_ThreadState = STATE_IDLE;
  58. }
  59. CBSPLightingThread::~CBSPLightingThread()
  60. {
  61. if( m_hThread )
  62. {
  63. // Stop the current lighting process if one is going on.
  64. Interrupt();
  65. // Tell the thread to exit.
  66. SetThreadCmd( THREADCMD_EXIT );
  67. // Wait for the thread to exit.
  68. WaitForSingleObject( m_hThread, INFINITE );
  69. // Now we can close the thread handle.
  70. CloseHandle( m_hThread );
  71. m_hThread = NULL;
  72. }
  73. DeleteCriticalSection( &m_CS );
  74. }
  75. void CBSPLightingThread::Release()
  76. {
  77. delete this;
  78. }
  79. void CBSPLightingThread::StartLighting( char const *pVMFFileWithEntities )
  80. {
  81. // First, kill any lighting going on.
  82. Interrupt();
  83. // Store the VMF file data for the thread.
  84. int len = strlen( pVMFFileWithEntities ) + 1;
  85. m_VMFFileWithEntities.CopyArray( pVMFFileWithEntities, len );
  86. // Tell the thread to start lighting.
  87. SetThreadState( STATE_LIGHTING );
  88. SetThreadCmd( THREADCMD_LIGHT );
  89. }
  90. int CBSPLightingThread::GetCurrentState()
  91. {
  92. return GetThreadState();
  93. }
  94. void CBSPLightingThread::Interrupt()
  95. {
  96. if( GetThreadState() == STATE_LIGHTING )
  97. {
  98. m_pVRadDLL->Interrupt();
  99. while( GetThreadState() == STATE_LIGHTING )
  100. Sleep( 10 );
  101. }
  102. }
  103. float CBSPLightingThread::GetPercentComplete()
  104. {
  105. return m_pVRadDLL->GetPercentComplete();
  106. }
  107. bool CBSPLightingThread::Init( IVRadDLL *pDLL )
  108. {
  109. m_pVRadDLL = pDLL;
  110. m_hThread = CreateThread(
  111. NULL,
  112. 0,
  113. ThreadMainLoop_Static,
  114. this,
  115. 0,
  116. &m_ThreadID );
  117. if( !m_hThread )
  118. return false;
  119. SetThreadPriority( m_hThread, THREAD_PRIORITY_LOWEST );
  120. return true;
  121. }
  122. DWORD CBSPLightingThread::ThreadMainLoop()
  123. {
  124. while( 1 )
  125. {
  126. int cmd = GetThreadCmd();
  127. if( cmd == THREADCMD_NONE )
  128. {
  129. // Keep waiting for a new command.
  130. Sleep( 10 );
  131. }
  132. else if( cmd == THREADCMD_LIGHT )
  133. {
  134. if( m_pVRadDLL->DoIncrementalLight( m_VMFFileWithEntities.Base() ) )
  135. SetThreadState( STATE_FINISHED );
  136. else
  137. SetThreadState( STATE_IDLE );
  138. }
  139. else if( cmd == THREADCMD_EXIT )
  140. {
  141. return 0;
  142. }
  143. }
  144. }
  145. int CBSPLightingThread::GetThreadCmd()
  146. {
  147. CCSLock lock( &m_CS );
  148. int ret = m_ThreadCmd;
  149. m_ThreadCmd = THREADCMD_NONE;
  150. return ret;
  151. }
  152. void CBSPLightingThread::SetThreadCmd( int cmd )
  153. {
  154. CCSLock lock( &m_CS );
  155. m_ThreadCmd = cmd;
  156. }
  157. int CBSPLightingThread::GetThreadState()
  158. {
  159. CCSLock lock( &m_CS );
  160. return m_ThreadState;
  161. }
  162. void CBSPLightingThread::SetThreadState( int state )
  163. {
  164. CCSLock lock( &m_CS );
  165. m_ThreadState = state;
  166. }