mirror of
https://github.com/nillerusr/source-engine.git
synced 2026-08-09 10:19:38 +00:00
1
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user