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.

342 lines
8.4 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose: List of game managers to update
  4. //
  5. // $Revision: $
  6. // $NoKeywords: $
  7. //===========================================================================//
  8. #include "gamemanager.h"
  9. #include "tier0/icommandline.h"
  10. // FIXME: REMOVE (for Sleep)
  11. #include <windows.h>
  12. //-----------------------------------------------------------------------------
  13. // globals
  14. //-----------------------------------------------------------------------------
  15. int IGameManager::m_nFrameNumber = 0;
  16. bool IGameManager::m_bStopRequested = false;
  17. bool IGameManager::m_bIsRunning = false;
  18. bool IGameManager::m_bIsInitialized = false;
  19. bool IGameManager::m_bLevelStartRequested = false;
  20. bool IGameManager::m_bLevelShutdownRequested = false;
  21. float IGameManager::m_flCurrentTime = 0.0f;
  22. float IGameManager::m_flLastTime = 0.0f;
  23. LevelState_t IGameManager::m_LevelState = NOT_IN_LEVEL;
  24. CUtlVector< IGameManager* > IGameManager::m_GameManagers;
  25. //-----------------------------------------------------------------------------
  26. // Adds a system to the list of systems to run
  27. //-----------------------------------------------------------------------------
  28. void IGameManager::Add( IGameManager* pSys )
  29. {
  30. Assert( !m_bIsRunning );
  31. m_GameManagers.AddToTail( pSys );
  32. }
  33. //-----------------------------------------------------------------------------
  34. // Removes a system from the list of systems to update
  35. //-----------------------------------------------------------------------------
  36. void IGameManager::Remove( IGameManager* pSys )
  37. {
  38. Assert( !m_bIsRunning );
  39. m_GameManagers.FindAndRemove( pSys );
  40. }
  41. //-----------------------------------------------------------------------------
  42. // Removes *all* systems from the list of systems to update
  43. //-----------------------------------------------------------------------------
  44. void IGameManager::RemoveAll( )
  45. {
  46. m_GameManagers.RemoveAll();
  47. }
  48. //-----------------------------------------------------------------------------
  49. // Invokes a method on all installed game systems in proper order
  50. //-----------------------------------------------------------------------------
  51. void IGameManager::InvokeMethod( GameManagerFunc_t f )
  52. {
  53. int i;
  54. int nCount = m_GameManagers.Count();
  55. for ( i = 0; i < nCount; ++i )
  56. {
  57. (m_GameManagers[i]->*f)();
  58. }
  59. }
  60. void IGameManager::InvokeMethodReverseOrder( GameManagerFunc_t f )
  61. {
  62. int i;
  63. int nCount = m_GameManagers.Count();
  64. for ( i = nCount; --i >= 0; )
  65. {
  66. (m_GameManagers[i]->*f)();
  67. }
  68. }
  69. bool IGameManager::InvokeMethod( GameManagerInitFunc_t f )
  70. {
  71. int i;
  72. int nCount = m_GameManagers.Count();
  73. for ( i = 0; i < nCount; ++i )
  74. {
  75. if ( !(m_GameManagers[i]->*f)() )
  76. return false;
  77. }
  78. return true;
  79. }
  80. LevelRetVal_t IGameManager::InvokeLevelMethod( GameManagerLevelFunc_t f, bool bFirstCall )
  81. {
  82. LevelRetVal_t nRetVal = FINISHED;
  83. int i;
  84. int nCount = m_GameManagers.Count();
  85. for ( i = 0; i < nCount; ++i )
  86. {
  87. LevelRetVal_t val = (m_GameManagers[i]->*f)( bFirstCall );
  88. if ( val == FAILED )
  89. return FAILED;
  90. if ( val == MORE_WORK )
  91. {
  92. nRetVal = MORE_WORK;
  93. }
  94. }
  95. return nRetVal;
  96. }
  97. LevelRetVal_t IGameManager::InvokeLevelMethodReverseOrder( GameManagerLevelFunc_t f, bool bFirstCall )
  98. {
  99. LevelRetVal_t nRetVal = FINISHED;
  100. int i;
  101. int nCount = m_GameManagers.Count();
  102. for ( i = 0; i < nCount; ++i )
  103. {
  104. LevelRetVal_t val = ( m_GameManagers[i]->*f )( bFirstCall );
  105. if ( val == FAILED )
  106. {
  107. nRetVal = FAILED;
  108. }
  109. if ( ( val == MORE_WORK ) && ( nRetVal != FAILED ) )
  110. {
  111. nRetVal = MORE_WORK;
  112. }
  113. }
  114. return nRetVal;
  115. }
  116. //-----------------------------------------------------------------------------
  117. // Init, shutdown game system
  118. //-----------------------------------------------------------------------------
  119. bool IGameManager::InitAllManagers()
  120. {
  121. m_nFrameNumber = 0;
  122. if ( !InvokeMethod( &IGameManager::Init ) )
  123. return false;
  124. m_bIsInitialized = true;
  125. return true;
  126. }
  127. void IGameManager::ShutdownAllManagers()
  128. {
  129. if ( m_bIsInitialized )
  130. {
  131. InvokeMethodReverseOrder( &IGameManager::Shutdown );
  132. m_bIsInitialized = false;
  133. }
  134. }
  135. //-----------------------------------------------------------------------------
  136. // Updates the state machine related to loading levels
  137. //-----------------------------------------------------------------------------
  138. void IGameManager::UpdateLevelStateMachine()
  139. {
  140. // Do we want to switch into the level shutdown state?
  141. bool bFirstLevelShutdownFrame = false;
  142. if ( m_bLevelShutdownRequested )
  143. {
  144. if ( m_LevelState != LOADING_LEVEL )
  145. {
  146. m_bLevelShutdownRequested = false;
  147. }
  148. if ( m_LevelState == IN_LEVEL )
  149. {
  150. m_LevelState = SHUTTING_DOWN_LEVEL;
  151. bFirstLevelShutdownFrame = true;
  152. }
  153. }
  154. // Perform level shutdown
  155. if ( m_LevelState == SHUTTING_DOWN_LEVEL )
  156. {
  157. LevelRetVal_t val = InvokeLevelMethodReverseOrder( &IGameManager::LevelShutdown, bFirstLevelShutdownFrame );
  158. if ( val != MORE_WORK )
  159. {
  160. m_LevelState = NOT_IN_LEVEL;
  161. }
  162. }
  163. // Do we want to switch into the level startup state?
  164. bool bFirstLevelStartFrame = false;
  165. if ( m_bLevelStartRequested )
  166. {
  167. if ( m_LevelState != SHUTTING_DOWN_LEVEL )
  168. {
  169. m_bLevelStartRequested = false;
  170. }
  171. if ( m_LevelState == NOT_IN_LEVEL )
  172. {
  173. m_LevelState = LOADING_LEVEL;
  174. bFirstLevelStartFrame = true;
  175. }
  176. }
  177. // Perform level load
  178. if ( m_LevelState == LOADING_LEVEL )
  179. {
  180. LevelRetVal_t val = InvokeLevelMethod( &IGameManager::LevelInit, bFirstLevelStartFrame );
  181. if ( val == FAILED )
  182. {
  183. m_LevelState = NOT_IN_LEVEL;
  184. }
  185. else if ( val == FINISHED )
  186. {
  187. m_LevelState = IN_LEVEL;
  188. }
  189. }
  190. }
  191. //-----------------------------------------------------------------------------
  192. // Runs the main loop.
  193. //-----------------------------------------------------------------------------
  194. void IGameManager::Start()
  195. {
  196. Assert( !m_bIsRunning && m_bIsInitialized );
  197. m_bIsRunning = true;
  198. m_bStopRequested = false;
  199. // This option is useful when running the app twice on the same machine
  200. // It makes the 2nd instance of the app run a lot faster
  201. bool bPlayNice = ( CommandLine()->CheckParm( "-yieldcycles" ) != 0 );
  202. float flStartTime = m_flCurrentTime = m_flLastTime = Plat_FloatTime();
  203. int nFramesSimulated = 0;
  204. int nCount = m_GameManagers.Count();
  205. while ( !m_bStopRequested )
  206. {
  207. UpdateLevelStateMachine();
  208. m_flLastTime = m_flCurrentTime;
  209. m_flCurrentTime = Plat_FloatTime();
  210. int nSimulationFramesNeeded = 1 + (int)( ( m_flCurrentTime - flStartTime ) / TICK_INTERVAL );
  211. while( nSimulationFramesNeeded > nFramesSimulated )
  212. {
  213. for ( int i = 0; i < nCount; ++i )
  214. {
  215. if ( m_GameManagers[i]->PerformsSimulation() )
  216. {
  217. m_GameManagers[i]->Update();
  218. }
  219. }
  220. ++m_nFrameNumber;
  221. ++nFramesSimulated;
  222. }
  223. // Always do I/O related managers regardless of framerate
  224. for ( int i = 0; i < nCount; ++i )
  225. {
  226. if ( !m_GameManagers[i]->PerformsSimulation() )
  227. {
  228. m_GameManagers[i]->Update();
  229. }
  230. }
  231. if ( bPlayNice )
  232. {
  233. Sleep( 1 );
  234. }
  235. }
  236. m_bIsRunning = false;
  237. }
  238. //-----------------------------------------------------------------------------
  239. // Stops the main loop at the next appropriate time
  240. //-----------------------------------------------------------------------------
  241. void IGameManager::Stop()
  242. {
  243. if ( m_bIsRunning )
  244. {
  245. m_bStopRequested = true;
  246. }
  247. }
  248. //-----------------------------------------------------------------------------
  249. // Returns the current frame number
  250. //-----------------------------------------------------------------------------
  251. int IGameManager::FrameNumber()
  252. {
  253. return m_nFrameNumber;
  254. }
  255. float IGameManager::CurrentSimulationTime()
  256. {
  257. return m_nFrameNumber * TICK_INTERVAL;
  258. }
  259. float IGameManager::SimulationDeltaTime()
  260. {
  261. return TICK_INTERVAL;
  262. }
  263. //-----------------------------------------------------------------------------
  264. // Used in rendering
  265. //-----------------------------------------------------------------------------
  266. float IGameManager::CurrentTime()
  267. {
  268. return m_flCurrentTime;
  269. }
  270. float IGameManager::DeltaTime()
  271. {
  272. return m_flCurrentTime - m_flLastTime;
  273. }
  274. //-----------------------------------------------------------------------------
  275. // Returns the current level state
  276. //-----------------------------------------------------------------------------
  277. LevelState_t IGameManager::GetLevelState()
  278. {
  279. return m_LevelState;
  280. }
  281. //-----------------------------------------------------------------------------
  282. // Start loading a level
  283. //-----------------------------------------------------------------------------
  284. void IGameManager::StartNewLevel()
  285. {
  286. m_bLevelShutdownRequested = true;
  287. m_bLevelStartRequested = true;
  288. }
  289. void IGameManager::ShutdownLevel()
  290. {
  291. m_bLevelShutdownRequested = true;
  292. }