diff options
Diffstat (limited to 'app/legion/gamemanager.cpp')
| -rw-r--r-- | app/legion/gamemanager.cpp | 342 |
1 files changed, 342 insertions, 0 deletions
diff --git a/app/legion/gamemanager.cpp b/app/legion/gamemanager.cpp new file mode 100644 index 0000000..a7934db --- /dev/null +++ b/app/legion/gamemanager.cpp @@ -0,0 +1,342 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: List of game managers to update +// +// $Revision: $ +// $NoKeywords: $ +//===========================================================================// + +#include "gamemanager.h" +#include "tier0/icommandline.h" + +// FIXME: REMOVE (for Sleep) +#include <windows.h> + + +//----------------------------------------------------------------------------- +// globals +//----------------------------------------------------------------------------- +int IGameManager::m_nFrameNumber = 0; +bool IGameManager::m_bStopRequested = false; +bool IGameManager::m_bIsRunning = false; +bool IGameManager::m_bIsInitialized = false; +bool IGameManager::m_bLevelStartRequested = false; +bool IGameManager::m_bLevelShutdownRequested = false; +float IGameManager::m_flCurrentTime = 0.0f; +float IGameManager::m_flLastTime = 0.0f; +LevelState_t IGameManager::m_LevelState = NOT_IN_LEVEL; + +CUtlVector< IGameManager* > IGameManager::m_GameManagers; + + +//----------------------------------------------------------------------------- +// Adds a system to the list of systems to run +//----------------------------------------------------------------------------- +void IGameManager::Add( IGameManager* pSys ) +{ + Assert( !m_bIsRunning ); + m_GameManagers.AddToTail( pSys ); +} + + +//----------------------------------------------------------------------------- +// Removes a system from the list of systems to update +//----------------------------------------------------------------------------- +void IGameManager::Remove( IGameManager* pSys ) +{ + Assert( !m_bIsRunning ); + m_GameManagers.FindAndRemove( pSys ); +} + + +//----------------------------------------------------------------------------- +// Removes *all* systems from the list of systems to update +//----------------------------------------------------------------------------- +void IGameManager::RemoveAll( ) +{ + m_GameManagers.RemoveAll(); +} + + +//----------------------------------------------------------------------------- +// Invokes a method on all installed game systems in proper order +//----------------------------------------------------------------------------- +void IGameManager::InvokeMethod( GameManagerFunc_t f ) +{ + int i; + int nCount = m_GameManagers.Count(); + for ( i = 0; i < nCount; ++i ) + { + (m_GameManagers[i]->*f)(); + } +} + +void IGameManager::InvokeMethodReverseOrder( GameManagerFunc_t f ) +{ + int i; + int nCount = m_GameManagers.Count(); + for ( i = nCount; --i >= 0; ) + { + (m_GameManagers[i]->*f)(); + } +} + +bool IGameManager::InvokeMethod( GameManagerInitFunc_t f ) +{ + int i; + int nCount = m_GameManagers.Count(); + for ( i = 0; i < nCount; ++i ) + { + if ( !(m_GameManagers[i]->*f)() ) + return false; + } + return true; +} + +LevelRetVal_t IGameManager::InvokeLevelMethod( GameManagerLevelFunc_t f, bool bFirstCall ) +{ + LevelRetVal_t nRetVal = FINISHED; + int i; + int nCount = m_GameManagers.Count(); + for ( i = 0; i < nCount; ++i ) + { + LevelRetVal_t val = (m_GameManagers[i]->*f)( bFirstCall ); + if ( val == FAILED ) + return FAILED; + if ( val == MORE_WORK ) + { + nRetVal = MORE_WORK; + } + } + return nRetVal; +} + +LevelRetVal_t IGameManager::InvokeLevelMethodReverseOrder( GameManagerLevelFunc_t f, bool bFirstCall ) +{ + LevelRetVal_t nRetVal = FINISHED; + int i; + int nCount = m_GameManagers.Count(); + for ( i = 0; i < nCount; ++i ) + { + LevelRetVal_t val = ( m_GameManagers[i]->*f )( bFirstCall ); + if ( val == FAILED ) + { + nRetVal = FAILED; + } + if ( ( val == MORE_WORK ) && ( nRetVal != FAILED ) ) + { + nRetVal = MORE_WORK; + } + } + return nRetVal; +} + + +//----------------------------------------------------------------------------- +// Init, shutdown game system +//----------------------------------------------------------------------------- +bool IGameManager::InitAllManagers() +{ + m_nFrameNumber = 0; + if ( !InvokeMethod( &IGameManager::Init ) ) + return false; + + m_bIsInitialized = true; + return true; +} + +void IGameManager::ShutdownAllManagers() +{ + if ( m_bIsInitialized ) + { + InvokeMethodReverseOrder( &IGameManager::Shutdown ); + m_bIsInitialized = false; + } +} + + +//----------------------------------------------------------------------------- +// Updates the state machine related to loading levels +//----------------------------------------------------------------------------- +void IGameManager::UpdateLevelStateMachine() +{ + // Do we want to switch into the level shutdown state? + bool bFirstLevelShutdownFrame = false; + if ( m_bLevelShutdownRequested ) + { + if ( m_LevelState != LOADING_LEVEL ) + { + m_bLevelShutdownRequested = false; + } + if ( m_LevelState == IN_LEVEL ) + { + m_LevelState = SHUTTING_DOWN_LEVEL; + bFirstLevelShutdownFrame = true; + } + } + + // Perform level shutdown + if ( m_LevelState == SHUTTING_DOWN_LEVEL ) + { + LevelRetVal_t val = InvokeLevelMethodReverseOrder( &IGameManager::LevelShutdown, bFirstLevelShutdownFrame ); + if ( val != MORE_WORK ) + { + m_LevelState = NOT_IN_LEVEL; + } + } + + // Do we want to switch into the level startup state? + bool bFirstLevelStartFrame = false; + if ( m_bLevelStartRequested ) + { + if ( m_LevelState != SHUTTING_DOWN_LEVEL ) + { + m_bLevelStartRequested = false; + } + if ( m_LevelState == NOT_IN_LEVEL ) + { + m_LevelState = LOADING_LEVEL; + bFirstLevelStartFrame = true; + } + } + + // Perform level load + if ( m_LevelState == LOADING_LEVEL ) + { + LevelRetVal_t val = InvokeLevelMethod( &IGameManager::LevelInit, bFirstLevelStartFrame ); + if ( val == FAILED ) + { + m_LevelState = NOT_IN_LEVEL; + } + else if ( val == FINISHED ) + { + m_LevelState = IN_LEVEL; + } + } +} + + +//----------------------------------------------------------------------------- +// Runs the main loop. +//----------------------------------------------------------------------------- +void IGameManager::Start() +{ + Assert( !m_bIsRunning && m_bIsInitialized ); + + m_bIsRunning = true; + m_bStopRequested = false; + + // This option is useful when running the app twice on the same machine + // It makes the 2nd instance of the app run a lot faster + bool bPlayNice = ( CommandLine()->CheckParm( "-yieldcycles" ) != 0 ); + + float flStartTime = m_flCurrentTime = m_flLastTime = Plat_FloatTime(); + int nFramesSimulated = 0; + int nCount = m_GameManagers.Count(); + while ( !m_bStopRequested ) + { + UpdateLevelStateMachine(); + + m_flLastTime = m_flCurrentTime; + m_flCurrentTime = Plat_FloatTime(); + int nSimulationFramesNeeded = 1 + (int)( ( m_flCurrentTime - flStartTime ) / TICK_INTERVAL ); + while( nSimulationFramesNeeded > nFramesSimulated ) + { + for ( int i = 0; i < nCount; ++i ) + { + if ( m_GameManagers[i]->PerformsSimulation() ) + { + m_GameManagers[i]->Update(); + } + } + ++m_nFrameNumber; + ++nFramesSimulated; + } + + // Always do I/O related managers regardless of framerate + for ( int i = 0; i < nCount; ++i ) + { + if ( !m_GameManagers[i]->PerformsSimulation() ) + { + m_GameManagers[i]->Update(); + } + } + + if ( bPlayNice ) + { + Sleep( 1 ); + } + } + + m_bIsRunning = false; +} + + +//----------------------------------------------------------------------------- +// Stops the main loop at the next appropriate time +//----------------------------------------------------------------------------- +void IGameManager::Stop() +{ + if ( m_bIsRunning ) + { + m_bStopRequested = true; + } +} + + +//----------------------------------------------------------------------------- +// Returns the current frame number +//----------------------------------------------------------------------------- +int IGameManager::FrameNumber() +{ + return m_nFrameNumber; +} + +float IGameManager::CurrentSimulationTime() +{ + return m_nFrameNumber * TICK_INTERVAL; +} + +float IGameManager::SimulationDeltaTime() +{ + return TICK_INTERVAL; +} + + +//----------------------------------------------------------------------------- +// Used in rendering +//----------------------------------------------------------------------------- +float IGameManager::CurrentTime() +{ + return m_flCurrentTime; +} + +float IGameManager::DeltaTime() +{ + return m_flCurrentTime - m_flLastTime; +} + + +//----------------------------------------------------------------------------- +// Returns the current level state +//----------------------------------------------------------------------------- +LevelState_t IGameManager::GetLevelState() +{ + return m_LevelState; +} + + +//----------------------------------------------------------------------------- +// Start loading a level +//----------------------------------------------------------------------------- +void IGameManager::StartNewLevel() +{ + m_bLevelShutdownRequested = true; + m_bLevelStartRequested = true; +} + +void IGameManager::ShutdownLevel() +{ + m_bLevelShutdownRequested = true; +} + |