summaryrefslogtreecommitdiff
path: root/app/legion/gamemanager.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'app/legion/gamemanager.cpp')
-rw-r--r--app/legion/gamemanager.cpp342
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;
+}
+