mirror of
https://github.com/alliedmodders/hl2sdk.git
synced 2025-12-07 10:38:23 +00:00
Update IGameSystem & Add IGameSystemFactory interfaces (#174)
Co-authored-by: komashchenko <22940384+komashchenko@users.noreply.github.com>
This commit is contained in:
parent
c002d23f81
commit
3864058382
@ -1,443 +0,0 @@
|
||||
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Deals with singleton
|
||||
//
|
||||
// $Revision: $
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#include "cbase.h"
|
||||
#include "igamesystem.h"
|
||||
#include "datacache/imdlcache.h"
|
||||
#include "utlvector.h"
|
||||
#include "vprof.h"
|
||||
#if defined( _X360 )
|
||||
#include "xbox/xbox_console.h"
|
||||
#endif
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
// enable this #define (here or in your vpc) to have
|
||||
// each GameSystem accounted for individually in the vprof.
|
||||
// You must enable VPROF_LEVEL 1 too.
|
||||
// #define VPROF_ACCOUNT_GAMESYSTEMS
|
||||
|
||||
// Pointer to a member method of IGameSystem
|
||||
typedef void (IGameSystem::*GameSystemFunc_t)();
|
||||
|
||||
// Pointer to a member method of IGameSystem
|
||||
typedef void (IGameSystemPerFrame::*PerFrameGameSystemFunc_t)();
|
||||
|
||||
// Used to invoke a method of all added Game systems in order
|
||||
static void InvokeMethod( GameSystemFunc_t f, char const *timed = 0 );
|
||||
// Used to invoke a method of all added Game systems in order
|
||||
static void InvokeMethodTickProgress( GameSystemFunc_t f, char const *timed = 0 );
|
||||
// Used to invoke a method of all added Game systems in reverse order
|
||||
static void InvokeMethodReverseOrder( GameSystemFunc_t f );
|
||||
|
||||
// Used to invoke a method of all added Game systems in order
|
||||
static void InvokePerFrameMethod( PerFrameGameSystemFunc_t f, char const *timed = 0 );
|
||||
|
||||
static bool s_bSystemsInitted = false;
|
||||
|
||||
// List of all installed Game systems
|
||||
static CUtlVector<IGameSystem*> s_GameSystems( 0, 4 );
|
||||
// List of all installed Game systems
|
||||
static CUtlVector<IGameSystemPerFrame*> s_GameSystemsPerFrame( 0, 4 );
|
||||
|
||||
// The map name
|
||||
static char* s_pMapName = 0;
|
||||
|
||||
static CBasePlayer *s_pRunCommandPlayer = NULL;
|
||||
static CUserCmd *s_pRunCommandUserCmd = NULL;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Auto-registration of game systems
|
||||
//-----------------------------------------------------------------------------
|
||||
static CAutoGameSystem *s_pSystemList = NULL;
|
||||
|
||||
CAutoGameSystem::CAutoGameSystem( char const *name ) :
|
||||
m_pszName( name )
|
||||
{
|
||||
// If s_GameSystems hasn't been initted yet, then add ourselves to the global list
|
||||
// because we don't know if the constructor for s_GameSystems has happened yet.
|
||||
// Otherwise, we can add ourselves right into that list.
|
||||
if ( s_bSystemsInitted )
|
||||
{
|
||||
Add( this );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pNext = s_pSystemList;
|
||||
s_pSystemList = this;
|
||||
}
|
||||
}
|
||||
|
||||
static CAutoGameSystemPerFrame *s_pPerFrameSystemList = NULL;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: This is a CAutoGameSystem which also cares about the "per frame" hooks
|
||||
//-----------------------------------------------------------------------------
|
||||
CAutoGameSystemPerFrame::CAutoGameSystemPerFrame( char const *name ) :
|
||||
m_pszName( name )
|
||||
{
|
||||
// If s_GameSystems hasn't been initted yet, then add ourselves to the global list
|
||||
// because we don't know if the constructor for s_GameSystems has happened yet.
|
||||
// Otherwise, we can add ourselves right into that list.
|
||||
if ( s_bSystemsInitted )
|
||||
{
|
||||
Add( this );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pNext = s_pPerFrameSystemList;
|
||||
s_pPerFrameSystemList = this;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// destructor, cleans up automagically....
|
||||
//-----------------------------------------------------------------------------
|
||||
IGameSystem::~IGameSystem()
|
||||
{
|
||||
Remove( this );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// destructor, cleans up automagically....
|
||||
//-----------------------------------------------------------------------------
|
||||
IGameSystemPerFrame::~IGameSystemPerFrame()
|
||||
{
|
||||
Remove( this );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Adds a system to the list of systems to run
|
||||
//-----------------------------------------------------------------------------
|
||||
void IGameSystem::Add( IGameSystem* pSys )
|
||||
{
|
||||
s_GameSystems.AddToTail( pSys );
|
||||
if ( dynamic_cast< IGameSystemPerFrame * >( pSys ) != NULL )
|
||||
{
|
||||
s_GameSystemsPerFrame.AddToTail( static_cast< IGameSystemPerFrame * >( pSys ) );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Removes a system from the list of systems to update
|
||||
//-----------------------------------------------------------------------------
|
||||
void IGameSystem::Remove( IGameSystem* pSys )
|
||||
{
|
||||
s_GameSystems.FindAndRemove( pSys );
|
||||
if ( dynamic_cast< IGameSystemPerFrame * >( pSys ) != NULL )
|
||||
{
|
||||
s_GameSystemsPerFrame.FindAndRemove( static_cast< IGameSystemPerFrame * >( pSys ) );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Removes *all* systems from the list of systems to update
|
||||
//-----------------------------------------------------------------------------
|
||||
void IGameSystem::RemoveAll( )
|
||||
{
|
||||
s_GameSystems.RemoveAll();
|
||||
s_GameSystemsPerFrame.RemoveAll();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Client systems can use this to get at the map name
|
||||
//-----------------------------------------------------------------------------
|
||||
char const* IGameSystem::MapName()
|
||||
{
|
||||
return s_pMapName;
|
||||
}
|
||||
|
||||
#ifndef CLIENT_DLL
|
||||
CBasePlayer *IGameSystem::RunCommandPlayer()
|
||||
{
|
||||
return s_pRunCommandPlayer;
|
||||
}
|
||||
|
||||
CUserCmd *IGameSystem::RunCommandUserCmd()
|
||||
{
|
||||
return s_pRunCommandUserCmd;
|
||||
}
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Invokes methods on all installed game systems
|
||||
//-----------------------------------------------------------------------------
|
||||
bool IGameSystem::InitAllSystems()
|
||||
{
|
||||
int i;
|
||||
|
||||
{
|
||||
// first add any auto systems to the end
|
||||
CAutoGameSystem *pSystem = s_pSystemList;
|
||||
while ( pSystem )
|
||||
{
|
||||
if ( s_GameSystems.Find( pSystem ) == s_GameSystems.InvalidIndex() )
|
||||
{
|
||||
Add( pSystem );
|
||||
}
|
||||
else
|
||||
{
|
||||
DevWarning( 1, "AutoGameSystem already added to game system list!!!\n" );
|
||||
}
|
||||
pSystem = pSystem->m_pNext;
|
||||
}
|
||||
s_pSystemList = NULL;
|
||||
}
|
||||
|
||||
{
|
||||
CAutoGameSystemPerFrame *pSystem = s_pPerFrameSystemList;
|
||||
while ( pSystem )
|
||||
{
|
||||
if ( s_GameSystems.Find( pSystem ) == s_GameSystems.InvalidIndex() )
|
||||
{
|
||||
Add( pSystem );
|
||||
}
|
||||
else
|
||||
{
|
||||
DevWarning( 1, "AutoGameSystem already added to game system list!!!\n" );
|
||||
}
|
||||
|
||||
pSystem = pSystem->m_pNext;
|
||||
}
|
||||
s_pSystemList = NULL;
|
||||
}
|
||||
// Now remember that we are initted so new CAutoGameSystems will add themselves automatically.
|
||||
s_bSystemsInitted = true;
|
||||
|
||||
for ( i = 0; i < s_GameSystems.Count(); ++i )
|
||||
{
|
||||
MDLCACHE_COARSE_LOCK();
|
||||
MDLCACHE_CRITICAL_SECTION();
|
||||
|
||||
IGameSystem *sys = s_GameSystems[i];
|
||||
|
||||
#if defined( _X360 )
|
||||
char sz[128];
|
||||
Q_snprintf( sz, sizeof( sz ), "%s->Init():Start", sys->Name() );
|
||||
XBX_rTimeStampLog( Plat_FloatTime(), sz );
|
||||
#endif
|
||||
bool valid = sys->Init();
|
||||
|
||||
#if defined( _X360 )
|
||||
Q_snprintf( sz, sizeof( sz ), "%s->Init():Finish", sys->Name() );
|
||||
XBX_rTimeStampLog( Plat_FloatTime(), sz );
|
||||
#endif
|
||||
if ( !valid )
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void IGameSystem::PostInitAllSystems( void )
|
||||
{
|
||||
InvokeMethod( &IGameSystem::PostInit, "PostInit" );
|
||||
}
|
||||
|
||||
void IGameSystem::ShutdownAllSystems()
|
||||
{
|
||||
InvokeMethodReverseOrder( &IGameSystem::Shutdown );
|
||||
}
|
||||
|
||||
void IGameSystem::LevelInitPreEntityAllSystems( char const* pMapName )
|
||||
{
|
||||
// Store off the map name
|
||||
if ( s_pMapName )
|
||||
{
|
||||
delete[] s_pMapName;
|
||||
}
|
||||
|
||||
int len = Q_strlen(pMapName) + 1;
|
||||
s_pMapName = new char [ len ];
|
||||
Q_strncpy( s_pMapName, pMapName, len );
|
||||
|
||||
InvokeMethodTickProgress( &IGameSystem::LevelInitPreEntity, "LevelInitPreEntity" );
|
||||
}
|
||||
|
||||
void IGameSystem::LevelInitPostEntityAllSystems( void )
|
||||
{
|
||||
InvokeMethod( &IGameSystem::LevelInitPostEntity, "LevelInitPostEntity" );
|
||||
}
|
||||
|
||||
void IGameSystem::LevelShutdownPreEntityAllSystems()
|
||||
{
|
||||
InvokeMethodReverseOrder( &IGameSystem::LevelShutdownPreEntity );
|
||||
}
|
||||
|
||||
void IGameSystem::LevelShutdownPostEntityAllSystems()
|
||||
{
|
||||
InvokeMethodReverseOrder( &IGameSystem::LevelShutdownPostEntity );
|
||||
|
||||
if ( s_pMapName )
|
||||
{
|
||||
delete[] s_pMapName;
|
||||
s_pMapName = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void IGameSystem::OnSaveAllSystems()
|
||||
{
|
||||
InvokeMethod( &IGameSystem::OnSave );
|
||||
}
|
||||
|
||||
void IGameSystem::OnRestoreAllSystems()
|
||||
{
|
||||
InvokeMethod( &IGameSystem::OnRestore );
|
||||
}
|
||||
|
||||
void IGameSystem::SafeRemoveIfDesiredAllSystems()
|
||||
{
|
||||
InvokeMethodReverseOrder( &IGameSystem::SafeRemoveIfDesired );
|
||||
}
|
||||
|
||||
#ifdef CLIENT_DLL
|
||||
|
||||
void IGameSystem::PreRenderAllSystems()
|
||||
{
|
||||
VPROF("IGameSystem::PreRenderAllSystems");
|
||||
InvokePerFrameMethod( &IGameSystemPerFrame::PreRender );
|
||||
}
|
||||
|
||||
void IGameSystem::UpdateAllSystems( float frametime )
|
||||
{
|
||||
SafeRemoveIfDesiredAllSystems();
|
||||
|
||||
int i;
|
||||
int c = s_GameSystemsPerFrame.Count();
|
||||
for ( i = 0; i < c; ++i )
|
||||
{
|
||||
IGameSystemPerFrame *sys = s_GameSystemsPerFrame[i];
|
||||
MDLCACHE_CRITICAL_SECTION();
|
||||
sys->Update( frametime );
|
||||
}
|
||||
}
|
||||
|
||||
void IGameSystem::PostRenderAllSystems()
|
||||
{
|
||||
InvokePerFrameMethod( &IGameSystemPerFrame::PostRender );
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
void IGameSystem::FrameUpdatePreEntityThinkAllSystems()
|
||||
{
|
||||
VPROF("FrameUpdatePreEntityThinkAllSystems");
|
||||
InvokePerFrameMethod( &IGameSystemPerFrame::FrameUpdatePreEntityThink );
|
||||
}
|
||||
|
||||
void IGameSystem::FrameUpdatePostEntityThinkAllSystems()
|
||||
{
|
||||
VPROF("FrameUpdatePostEntityThinkAllSystems");
|
||||
SafeRemoveIfDesiredAllSystems();
|
||||
|
||||
InvokePerFrameMethod( &IGameSystemPerFrame::FrameUpdatePostEntityThink );
|
||||
}
|
||||
|
||||
void IGameSystem::PreClientUpdateAllSystems()
|
||||
{
|
||||
VPROF("PreClientUpdateAllSystems");
|
||||
InvokePerFrameMethod( &IGameSystemPerFrame::PreClientUpdate );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Invokes a method on all installed game systems in proper order
|
||||
//-----------------------------------------------------------------------------
|
||||
void InvokeMethod( GameSystemFunc_t f, char const *timed /*=0*/ )
|
||||
{
|
||||
NOTE_UNUSED( timed );
|
||||
|
||||
int i;
|
||||
int c = s_GameSystems.Count();
|
||||
for ( i = 0; i < c ; ++i )
|
||||
{
|
||||
IGameSystem *sys = s_GameSystems[i];
|
||||
|
||||
MDLCACHE_COARSE_LOCK();
|
||||
MDLCACHE_CRITICAL_SECTION();
|
||||
|
||||
(sys->*f)();
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Invokes a method on all installed game systems in proper order
|
||||
//-----------------------------------------------------------------------------
|
||||
void InvokeMethodTickProgress( GameSystemFunc_t f, char const *timed /*=0*/ )
|
||||
{
|
||||
NOTE_UNUSED( timed );
|
||||
|
||||
int i;
|
||||
int c = s_GameSystems.Count();
|
||||
for ( i = 0; i < c ; ++i )
|
||||
{
|
||||
IGameSystem *sys = s_GameSystems[i];
|
||||
|
||||
MDLCACHE_COARSE_LOCK();
|
||||
MDLCACHE_CRITICAL_SECTION();
|
||||
#if defined( CLIENT_DLL )
|
||||
engine->TickProgressBar();
|
||||
#endif
|
||||
(sys->*f)();
|
||||
}
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
// Invokes a method on all installed game systems in proper order
|
||||
//-----------------------------------------------------------------------------
|
||||
void InvokePerFrameMethod( PerFrameGameSystemFunc_t f, char const *timed /*=0*/ )
|
||||
{
|
||||
NOTE_UNUSED( timed );
|
||||
|
||||
int i;
|
||||
int c = s_GameSystemsPerFrame.Count();
|
||||
for ( i = 0; i < c ; ++i )
|
||||
{
|
||||
IGameSystemPerFrame *sys = s_GameSystemsPerFrame[i];
|
||||
#if (VPROF_LEVEL > 0) && defined(VPROF_ACCOUNT_GAMESYSTEMS) // make sure each game system is individually attributed
|
||||
// because vprof nodes must really be constructed with a pointer to a static
|
||||
// string, we can't create a temporary char[] here and sprintf a distinctive
|
||||
// V_snprintf( buf, 63, "gamesys_preframe_%s", sys->Name() ). We'll have to
|
||||
// settle for just the system name, and distinguish between pre and post frame
|
||||
// in hierarchy.
|
||||
VPROF( sys->Name() );
|
||||
#endif
|
||||
MDLCACHE_CRITICAL_SECTION();
|
||||
(sys->*f)();
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Invokes a method on all installed game systems in reverse order
|
||||
//-----------------------------------------------------------------------------
|
||||
void InvokeMethodReverseOrder( GameSystemFunc_t f )
|
||||
{
|
||||
int i;
|
||||
int c = s_GameSystems.Count();
|
||||
for ( i = c; --i >= 0; )
|
||||
{
|
||||
IGameSystem *sys = s_GameSystems[i];
|
||||
#if (VPROF_LEVEL > 0) && defined(VPROF_ACCOUNT_GAMESYSTEMS) // make sure each game system is individually attributed
|
||||
// because vprof nodes must really be constructed with a pointer to a static
|
||||
// string, we can't create a temporary char[] here and sprintf a distinctive
|
||||
// V_snprintf( buf, 63, "gamesys_preframe_%s", sys->Name() ). We'll have to
|
||||
// settle for just the system name, and distinguish between pre and post frame
|
||||
// in hierarchy.
|
||||
VPROF( sys->Name() );
|
||||
#endif
|
||||
MDLCACHE_CRITICAL_SECTION();
|
||||
(sys->*f)();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
@ -11,6 +11,37 @@
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
struct EventGameInit_t;
|
||||
struct EventGameShutdown_t;
|
||||
struct EventGamePostInit_t;
|
||||
struct EventGamePreShutdown_t;
|
||||
struct EventBuildGameSessionManifest_t;
|
||||
struct EventGameActivate_t;
|
||||
struct EventClientFullySignedOn_t;
|
||||
struct EventDisconnect_t;
|
||||
struct EventGameDeactivate_t;
|
||||
struct EventSpawnGroupPrecache_t;
|
||||
struct EventSpawnGroupUncache_t;
|
||||
struct EventPreSpawnGroupLoad_t;
|
||||
struct EventPostSpawnGroupLoad_t;
|
||||
struct EventPreSpawnGroupUnload_t;
|
||||
struct EventPostSpawnGroupUnload_t;
|
||||
struct EventActiveSpawnGroupChanged_t;
|
||||
struct EventClientPostDataUpdate_t;
|
||||
struct EventClientPreRender_t;
|
||||
struct EventClientPreEntityThink_t;
|
||||
struct EventClientUpdate_t;
|
||||
struct EventClientPostRender_t;
|
||||
struct EventServerPreEntityThink_t;
|
||||
struct EventServerPostEntityThink_t;
|
||||
struct EventServerPreClientUpdate_t;
|
||||
struct EventServerGamePostSimulate_t;
|
||||
struct EventClientGamePostSimulate_t;
|
||||
struct EventGameFrameBoundary_t;
|
||||
struct EventOutOfGameFrameBoundary_t;
|
||||
struct EventSaveGame_t;
|
||||
struct EventRestoreGame_t;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Game systems are singleton objects in the client + server codebase responsible for
|
||||
// various tasks
|
||||
@ -18,113 +49,84 @@
|
||||
// order in which they are initialized and updated. They are shut down in
|
||||
// reverse order from which they are initialized.
|
||||
//-----------------------------------------------------------------------------
|
||||
#ifdef GAME_DLL
|
||||
class CBasePlayer;
|
||||
class CUserCmd;
|
||||
#endif
|
||||
|
||||
// UNDONE: Do these need GameInit/GameShutdown as well?
|
||||
// UNDONE: Remove the Pre/Post entity semantics and rely on system ordering?
|
||||
// FIXME: Remove all ifdef CLIENT_DLL if we can...
|
||||
abstract_class IGameSystem
|
||||
{
|
||||
public:
|
||||
// GameSystems are expected to implement these methods.
|
||||
virtual char const *Name() = 0;
|
||||
|
||||
// Init, shutdown
|
||||
// return true on success. false to abort DLL init!
|
||||
virtual bool Init() = 0;
|
||||
virtual void PostInit() = 0;
|
||||
virtual void Shutdown() = 0;
|
||||
|
||||
// Level init, shutdown
|
||||
virtual void LevelInitPreEntity() = 0;
|
||||
// entities are created / spawned / precached here
|
||||
virtual void LevelInitPostEntity() = 0;
|
||||
// Game init, shutdown
|
||||
virtual void GameInit(const EventGameInit_t* const msg) = 0;
|
||||
virtual void GameShutdown(const EventGameShutdown_t* const msg) = 0;
|
||||
virtual void GamePostInit(const EventGamePostInit_t* const msg) = 0;
|
||||
virtual void GamePreShutdown(const EventGamePreShutdown_t* const msg) = 0;
|
||||
|
||||
virtual void LevelShutdownPreEntity() = 0;
|
||||
// Entities are deleted / released here...
|
||||
virtual void LevelShutdownPostEntity() = 0;
|
||||
// end of level shutdown
|
||||
|
||||
// Called during game save
|
||||
virtual void OnSave() = 0;
|
||||
virtual void BuildGameSessionManifest(const EventBuildGameSessionManifest_t* const msg) = 0;
|
||||
|
||||
// Called during game restore, after the local player has connected and entities have been fully restored
|
||||
virtual void OnRestore() = 0;
|
||||
virtual void GameActivate(const EventGameActivate_t* const msg) = 0;
|
||||
|
||||
// Called every frame. It's safe to remove an igamesystem from within this callback.
|
||||
virtual void SafeRemoveIfDesired() = 0;
|
||||
virtual void ClientFullySignedOn(const EventClientFullySignedOn_t* const msg) = 0;
|
||||
virtual void ClientDisconnect(const EventDisconnect_t* const msg) = 0;
|
||||
|
||||
virtual bool IsPerFrame() = 0;
|
||||
virtual void GameDeactivate(const EventGameDeactivate_t* const msg) = 0;
|
||||
|
||||
// destructor, cleans up automagically....
|
||||
virtual ~IGameSystem();
|
||||
virtual void SpawnGroupPrecache(const EventSpawnGroupPrecache_t* const msg) = 0;
|
||||
virtual void SpawnGroupUncache(const EventSpawnGroupUncache_t* const msg) = 0;
|
||||
virtual void PreSpawnGroupLoad(const EventPreSpawnGroupLoad_t* const msg) = 0;
|
||||
virtual void PostSpawnGroupLoad(const EventPostSpawnGroupLoad_t* const msg) = 0;
|
||||
virtual void PreSpawnGroupUnload(const EventPreSpawnGroupUnload_t* const msg) = 0;
|
||||
virtual void PostSpawnGroupUnload(const EventPostSpawnGroupUnload_t* const msg) = 0;
|
||||
virtual void ActiveSpawnGroupChanged(const EventActiveSpawnGroupChanged_t* const msg) = 0;
|
||||
|
||||
// Client systems can use this to get at the map name
|
||||
static char const* MapName();
|
||||
virtual void PostDataUpdate(EventClientPostDataUpdate_t* const msg) = 0;
|
||||
|
||||
// These methods are used to add and remove server systems from the
|
||||
// main server loop. The systems are invoked in the order in which
|
||||
// they are added.
|
||||
static void Add ( IGameSystem* pSys );
|
||||
static void Remove ( IGameSystem* pSys );
|
||||
static void RemoveAll ( );
|
||||
|
||||
// These methods are used to initialize, shutdown, etc all systems
|
||||
static bool InitAllSystems();
|
||||
static void PostInitAllSystems();
|
||||
static void ShutdownAllSystems();
|
||||
static void LevelInitPreEntityAllSystems( char const* pMapName );
|
||||
static void LevelInitPostEntityAllSystems();
|
||||
static void LevelShutdownPreEntityAllSystems();
|
||||
static void LevelShutdownPostEntityAllSystems();
|
||||
|
||||
static void OnSaveAllSystems();
|
||||
static void OnRestoreAllSystems();
|
||||
|
||||
static void SafeRemoveIfDesiredAllSystems();
|
||||
|
||||
#ifdef CLIENT_DLL
|
||||
static void PreRenderAllSystems();
|
||||
static void UpdateAllSystems( float frametime );
|
||||
static void PostRenderAllSystems();
|
||||
#else
|
||||
static void FrameUpdatePreEntityThinkAllSystems();
|
||||
static void FrameUpdatePostEntityThinkAllSystems();
|
||||
static void PreClientUpdateAllSystems();
|
||||
|
||||
// Accessors for the above function
|
||||
#ifdef GAME_DLL
|
||||
static CBasePlayer *RunCommandPlayer();
|
||||
static CUserCmd *RunCommandUserCmd();
|
||||
#endif
|
||||
#endif
|
||||
};
|
||||
|
||||
class IGameSystemPerFrame : public IGameSystem
|
||||
{
|
||||
public:
|
||||
// destructor, cleans up automagically....
|
||||
virtual ~IGameSystemPerFrame();
|
||||
|
||||
#ifdef CLIENT_DLL
|
||||
// Called before rendering
|
||||
virtual void PreRender() = 0;
|
||||
virtual void PreRender(const EventClientPreRender_t* const msg) = 0;
|
||||
|
||||
virtual void ClientPreEntityThink(const EventClientPreEntityThink_t* const msg) = 0;
|
||||
|
||||
virtual void unk_1271(const void* const msg) = 0;
|
||||
|
||||
// Gets called each frame
|
||||
virtual void Update( float frametime ) = 0;
|
||||
virtual void Update(const EventClientUpdate_t* const msg) = 0;
|
||||
|
||||
// Called after rendering
|
||||
virtual void PostRender() = 0;
|
||||
#else
|
||||
virtual void PostRender(const EventClientPostRender_t* const msg) = 0;
|
||||
|
||||
// Called each frame before entities think
|
||||
virtual void FrameUpdatePreEntityThink() = 0;
|
||||
virtual void FrameUpdatePreEntityThink(const EventServerPreEntityThink_t* const msg) = 0;
|
||||
// called after entities think
|
||||
virtual void FrameUpdatePostEntityThink() = 0;
|
||||
virtual void PreClientUpdate() = 0;
|
||||
#endif
|
||||
virtual void FrameUpdatePostEntityThink(const EventServerPostEntityThink_t* const msg) = 0;
|
||||
virtual void PreClientUpdate(const EventServerPreClientUpdate_t* const msg) = 0;
|
||||
|
||||
virtual void unk_1277(const void* const msg) = 0;
|
||||
virtual void unk_1278(const void* const msg) = 0;
|
||||
|
||||
virtual void OnServerGamePostSimulate(const EventServerGamePostSimulate_t* const msg) = 0;
|
||||
virtual void OnClientGamePostSimulate(const EventClientGamePostSimulate_t* const msg) = 0;
|
||||
|
||||
virtual void unk_1281(const void* const msg) = 0;
|
||||
|
||||
virtual void FrameBoundary(const EventGameFrameBoundary_t* const msg) = 0;
|
||||
virtual void OutOfGameFrameBoundary(const EventOutOfGameFrameBoundary_t* const msg) = 0;
|
||||
|
||||
virtual void SaveGame(const EventSaveGame_t* const msg) = 0;
|
||||
virtual void RestoreGame(const EventRestoreGame_t* const msg) = 0;
|
||||
|
||||
virtual void unk_1285(const void* const msg) = 0;
|
||||
virtual void unk_1286(const void* const msg) = 0;
|
||||
virtual void unk_1287(const void* const msg) = 0;
|
||||
virtual void unk_1288(const void* const msg) = 0;
|
||||
virtual void unk_1289(const void* const msg) = 0;
|
||||
|
||||
virtual const char* GetName() = 0;
|
||||
virtual void SetGameSystemGlobalPtrs(void* pValue) = 0;
|
||||
virtual void SetName(const char* pName) = 0;
|
||||
virtual bool DoesGameSystemReallocate() = 0;
|
||||
virtual ~IGameSystem() {}
|
||||
};
|
||||
|
||||
// Quick and dirty server system for users who don't care about precise ordering
|
||||
@ -132,8 +134,10 @@ public:
|
||||
class CBaseGameSystem : public IGameSystem
|
||||
{
|
||||
public:
|
||||
|
||||
virtual char const *Name() { return "unnamed"; }
|
||||
CBaseGameSystem(const char* pszInitName = "unnamed")
|
||||
: m_pName(pszInitName)
|
||||
{
|
||||
}
|
||||
|
||||
// Init, shutdown
|
||||
// return true on success. false to abort DLL init!
|
||||
@ -141,120 +145,84 @@ public:
|
||||
virtual void PostInit() {}
|
||||
virtual void Shutdown() {}
|
||||
|
||||
// Level init, shutdown
|
||||
virtual void LevelInitPreEntity() {}
|
||||
virtual void LevelInitPostEntity() {}
|
||||
virtual void LevelShutdownPreEntity() {}
|
||||
virtual void LevelShutdownPostEntity() {}
|
||||
// Game init, shutdown
|
||||
virtual void GameInit(const EventGameInit_t* const msg) {}
|
||||
virtual void GameShutdown(const EventGameShutdown_t* const msg) {}
|
||||
virtual void GamePostInit(const EventGamePostInit_t* const msg) {}
|
||||
virtual void GamePreShutdown(const EventGamePreShutdown_t* const msg) {}
|
||||
|
||||
virtual void OnSave() {}
|
||||
virtual void OnRestore() {}
|
||||
virtual void SafeRemoveIfDesired() {}
|
||||
virtual void BuildGameSessionManifest(const EventBuildGameSessionManifest_t* const msg) {}
|
||||
|
||||
virtual void GameActivate(const EventGameActivate_t* const msg) {}
|
||||
|
||||
virtual void ClientFullySignedOn(const EventClientFullySignedOn_t* const msg) {}
|
||||
virtual void ClientDisconnect(const EventDisconnect_t* const msg) {}
|
||||
|
||||
virtual void GameDeactivate(const EventGameDeactivate_t* const msg) {}
|
||||
|
||||
virtual void SpawnGroupPrecache(const EventSpawnGroupPrecache_t* const msg) {}
|
||||
virtual void SpawnGroupUncache(const EventSpawnGroupUncache_t* const msg) {}
|
||||
virtual void PreSpawnGroupLoad(const EventPreSpawnGroupLoad_t* const msg) {}
|
||||
virtual void PostSpawnGroupLoad(const EventPostSpawnGroupLoad_t* const msg) {}
|
||||
virtual void PreSpawnGroupUnload(const EventPreSpawnGroupUnload_t* const msg) {}
|
||||
virtual void PostSpawnGroupUnload(const EventPostSpawnGroupUnload_t* const msg) {}
|
||||
virtual void ActiveSpawnGroupChanged(const EventActiveSpawnGroupChanged_t* const msg) {}
|
||||
|
||||
virtual void PostDataUpdate(EventClientPostDataUpdate_t* const msg) {}
|
||||
|
||||
// Called before rendering
|
||||
virtual void PreRender(const EventClientPreRender_t* const msg) {}
|
||||
|
||||
virtual void ClientPreEntityThink(const EventClientPreEntityThink_t* const msg) {}
|
||||
|
||||
virtual void unk_1271(const void* const msg) {}
|
||||
|
||||
// Gets called each frame
|
||||
virtual void Update(const EventClientUpdate_t* const msg) {}
|
||||
|
||||
// Called after rendering
|
||||
virtual void PostRender(const EventClientPostRender_t* const msg) {}
|
||||
|
||||
// Called each frame before entities think
|
||||
virtual void FrameUpdatePreEntityThink(const EventServerPreEntityThink_t* const msg) {}
|
||||
// called after entities think
|
||||
virtual void FrameUpdatePostEntityThink(const EventServerPostEntityThink_t* const msg) {}
|
||||
virtual void PreClientUpdate(const EventServerPreClientUpdate_t* const msg) {}
|
||||
|
||||
virtual void unk_1277(const void* const msg) {}
|
||||
virtual void unk_1278(const void* const msg) {}
|
||||
|
||||
virtual void OnServerGamePostSimulate(const EventServerGamePostSimulate_t* const msg) {}
|
||||
virtual void OnClientGamePostSimulate(const EventClientGamePostSimulate_t* const msg) {}
|
||||
|
||||
virtual void unk_1281(const void* const msg) {}
|
||||
|
||||
virtual void FrameBoundary(const EventGameFrameBoundary_t* const msg) {}
|
||||
virtual void OutOfGameFrameBoundary(const EventOutOfGameFrameBoundary_t* const msg) {}
|
||||
|
||||
virtual void SaveGame(const EventSaveGame_t* const msg) {}
|
||||
virtual void RestoreGame(const EventRestoreGame_t* const msg) {}
|
||||
|
||||
virtual void unk_1285(const void* const msg) {}
|
||||
virtual void unk_1286(const void* const msg) {}
|
||||
virtual void unk_1287(const void* const msg) {}
|
||||
virtual void unk_1288(const void* const msg) {}
|
||||
virtual void unk_1289(const void* const msg) {}
|
||||
|
||||
virtual const char* GetName() { return m_pName; }
|
||||
virtual void SetGameSystemGlobalPtrs(void* pValue) {}
|
||||
virtual void SetName(const char* pName) { m_pName = pName; }
|
||||
virtual bool DoesGameSystemReallocate() { return false; }
|
||||
virtual ~CBaseGameSystem() {}
|
||||
|
||||
virtual bool IsPerFrame() { return false; }
|
||||
private:
|
||||
|
||||
// Prevent anyone derived from CBaseGameSystem from implementing these, they need
|
||||
// to derive from CBaseGameSystemPerFrame below!!!
|
||||
#ifdef CLIENT_DLL
|
||||
// Called before rendering
|
||||
virtual void PreRender() {}
|
||||
|
||||
// Gets called each frame
|
||||
virtual void Update( float frametime ) {}
|
||||
|
||||
// Called after rendering
|
||||
virtual void PostRender() {}
|
||||
#else
|
||||
// Called each frame before entities think
|
||||
virtual void FrameUpdatePreEntityThink() {}
|
||||
// called after entities think
|
||||
virtual void FrameUpdatePostEntityThink() {}
|
||||
virtual void PreClientUpdate() {}
|
||||
#endif
|
||||
const char* m_pName;
|
||||
};
|
||||
|
||||
// Quick and dirty server system for users who don't care about precise ordering
|
||||
// and usually only want to implement a few of the callbacks
|
||||
class CBaseGameSystemPerFrame : public IGameSystemPerFrame
|
||||
{
|
||||
public:
|
||||
virtual char const *Name() { return "unnamed"; }
|
||||
|
||||
// Init, shutdown
|
||||
// return true on success. false to abort DLL init!
|
||||
virtual bool Init() { return true; }
|
||||
virtual void PostInit() {}
|
||||
virtual void Shutdown() {}
|
||||
|
||||
// Level init, shutdown
|
||||
virtual void LevelInitPreEntity() {}
|
||||
virtual void LevelInitPostEntity() {}
|
||||
virtual void LevelShutdownPreEntity() {}
|
||||
virtual void LevelShutdownPostEntity() {}
|
||||
|
||||
virtual void OnSave() {}
|
||||
virtual void OnRestore() {}
|
||||
virtual void SafeRemoveIfDesired() {}
|
||||
|
||||
virtual bool IsPerFrame() { return true; }
|
||||
|
||||
#ifdef CLIENT_DLL
|
||||
// Called before rendering
|
||||
virtual void PreRender () { }
|
||||
|
||||
// Gets called each frame
|
||||
virtual void Update( float frametime ) { }
|
||||
|
||||
// Called after rendering
|
||||
virtual void PostRender () { }
|
||||
#else
|
||||
// Called each frame before entities think
|
||||
virtual void FrameUpdatePreEntityThink() { }
|
||||
// called after entities think
|
||||
virtual void FrameUpdatePostEntityThink() { }
|
||||
virtual void PreClientUpdate() { }
|
||||
#endif
|
||||
};
|
||||
|
||||
// Quick and dirty server system for users who don't care about precise ordering
|
||||
// and usually only want to implement a few of the callbacks
|
||||
class CAutoGameSystem : public CBaseGameSystem
|
||||
{
|
||||
public:
|
||||
CAutoGameSystem( char const *name = NULL ); // hooks in at startup, no need to explicitly add
|
||||
CAutoGameSystem *m_pNext;
|
||||
|
||||
virtual char const *Name() { return m_pszName ? m_pszName : "unnamed"; }
|
||||
|
||||
private:
|
||||
char const *m_pszName;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: This is a CAutoGameSystem which also cares about the "per frame" hooks
|
||||
//-----------------------------------------------------------------------------
|
||||
class CAutoGameSystemPerFrame : public CBaseGameSystemPerFrame
|
||||
{
|
||||
public:
|
||||
CAutoGameSystemPerFrame( char const *name = NULL );
|
||||
CAutoGameSystemPerFrame *m_pNext;
|
||||
|
||||
virtual char const *Name() { return m_pszName ? m_pszName : "unnamed"; }
|
||||
|
||||
private:
|
||||
char const *m_pszName;
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: This interface is here to add more hooks than IGameSystemPerFrame exposes,
|
||||
// so we don't pollute it with hooks that only the tool cares about
|
||||
//-----------------------------------------------------------------------------
|
||||
class IToolFrameworkServer
|
||||
{
|
||||
public:
|
||||
virtual void PreSetupVisibility() = 0;
|
||||
protected:
|
||||
virtual ~CAutoGameSystem() {};
|
||||
};
|
||||
|
||||
#endif // IGAMESYSTEM_H
|
||||
|
||||
167
game/shared/igamesystemfactory.h
Normal file
167
game/shared/igamesystemfactory.h
Normal file
@ -0,0 +1,167 @@
|
||||
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef IGAMESYSTEMFACTORY_H
|
||||
#define IGAMESYSTEMFACTORY_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "string.h"
|
||||
#include "igamesystem.h"
|
||||
|
||||
/*
|
||||
* AMNOTE: To register your own game system, CGameSystemStaticFactory could be used to register it,
|
||||
* but since the actual factory lives inside the game originally and we don't have direct access to it
|
||||
* you need provide the CBaseGameSystemFactory::sm_pFirst by whatever means are possible to you.
|
||||
*
|
||||
* Once CBaseGameSystemFactory::sm_pFirst is initialized and correct address provided,
|
||||
* you can create your own gamesystem (refer to igamesystem.h on what it should be like) and register it
|
||||
* via ``new CGameSystemStaticFactory<YourGameSystemClass>( "YourGameSystemName", &PointerToYourGameSystemInstance )``
|
||||
* the new factory object would be created and if all is done correctly your game system should be viewable to the game
|
||||
* and its callbacks should trigger.
|
||||
*/
|
||||
|
||||
abstract_class IGameSystemFactory
|
||||
{
|
||||
public:
|
||||
virtual bool Init() = 0;
|
||||
virtual void PostInit() = 0;
|
||||
virtual void Shutdown() = 0;
|
||||
virtual IGameSystem* CreateGameSystem() = 0;
|
||||
virtual void DestroyGameSystem(IGameSystem* pGameSystem) = 0;
|
||||
virtual bool ShouldAutoAdd() = 0;
|
||||
virtual int GetPriority() = 0;
|
||||
virtual void SetGlobalPtr(void* pValue) = 0;
|
||||
virtual bool IsReallocating() = 0;
|
||||
virtual IGameSystem* GetStaticGameSystem() = 0;
|
||||
};
|
||||
|
||||
class CBaseGameSystemFactory : public IGameSystemFactory
|
||||
{
|
||||
protected:
|
||||
CBaseGameSystemFactory(const char* pName)
|
||||
{
|
||||
m_pName = pName;
|
||||
m_pNext = *CBaseGameSystemFactory::sm_pFirst;
|
||||
*CBaseGameSystemFactory::sm_pFirst = this;
|
||||
}
|
||||
|
||||
private:
|
||||
CBaseGameSystemFactory* m_pNext;
|
||||
const char* m_pName;
|
||||
|
||||
public:
|
||||
static IGameSystem* GetGlobalPtrByName(const char* pName)
|
||||
{
|
||||
CBaseGameSystemFactory* pFactoryList = *CBaseGameSystemFactory::sm_pFirst;
|
||||
while (pFactoryList)
|
||||
{
|
||||
if (strcmp(pFactoryList->m_pName, pName) == 0)
|
||||
{
|
||||
return pFactoryList->GetStaticGameSystem();
|
||||
}
|
||||
pFactoryList = pFactoryList->m_pNext;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// AMNOTE: This needs to be provided by a thirdparty application,
|
||||
// and is required if you want to register your own gamesystem
|
||||
static CBaseGameSystemFactory** sm_pFirst;
|
||||
};
|
||||
|
||||
template <class T, class U = T>
|
||||
class CGameSystemStaticFactory : public CBaseGameSystemFactory
|
||||
{
|
||||
public:
|
||||
CGameSystemStaticFactory(const char* pName, T* pActualGlobal, U** ppGlobalPointer = nullptr) : CBaseGameSystemFactory(pName)
|
||||
{
|
||||
m_pActualGlobal = pActualGlobal;
|
||||
m_ppGlobalPointer = ppGlobalPointer;
|
||||
pActualGlobal->SetName(pName);
|
||||
}
|
||||
|
||||
bool Init() override { return m_pActualGlobal->Init(); }
|
||||
void PostInit() override { m_pActualGlobal->PostInit(); }
|
||||
void Shutdown() override { m_pActualGlobal->Shutdown(); }
|
||||
|
||||
IGameSystem* CreateGameSystem() override
|
||||
{
|
||||
m_pActualGlobal->SetGameSystemGlobalPtrs(m_pActualGlobal);
|
||||
return m_pActualGlobal;
|
||||
}
|
||||
|
||||
void DestroyGameSystem(IGameSystem* pGameSystem) override
|
||||
{
|
||||
m_pActualGlobal->SetGameSystemGlobalPtrs(nullptr);
|
||||
}
|
||||
|
||||
bool ShouldAutoAdd() override { return true; }
|
||||
int GetPriority() override { return 0; }
|
||||
|
||||
void SetGlobalPtr(void* pValue) override
|
||||
{
|
||||
if (m_ppGlobalPointer)
|
||||
{
|
||||
*m_ppGlobalPointer = reinterpret_cast<T*>(pValue);
|
||||
}
|
||||
}
|
||||
|
||||
bool IsReallocating() override { return false; }
|
||||
IGameSystem* GetStaticGameSystem() override { return m_pActualGlobal; }
|
||||
|
||||
private:
|
||||
T* m_pActualGlobal;
|
||||
U** m_ppGlobalPointer;
|
||||
};
|
||||
|
||||
template <class T, class U = T>
|
||||
class CGameSystemReallocatingFactory : public CBaseGameSystemFactory
|
||||
{
|
||||
public:
|
||||
CGameSystemReallocatingFactory(const char* pName, U** ppGlobalPointer = nullptr) : CBaseGameSystemFactory(pName)
|
||||
{
|
||||
m_ppGlobalPointer = ppGlobalPointer;
|
||||
}
|
||||
|
||||
bool Init() override { return true; }
|
||||
void PostInit() override { }
|
||||
void Shutdown() override { }
|
||||
|
||||
IGameSystem* CreateGameSystem() override
|
||||
{
|
||||
T* pObject = new T();
|
||||
pObject->SetGameSystemGlobalPtrs(pObject);
|
||||
return pObject;
|
||||
}
|
||||
|
||||
void DestroyGameSystem(IGameSystem* pGameSystem) override
|
||||
{
|
||||
pGameSystem->SetGameSystemGlobalPtrs(nullptr);
|
||||
delete pGameSystem;
|
||||
}
|
||||
|
||||
bool ShouldAutoAdd() override { return true; }
|
||||
int GetPriority() override { return 0; }
|
||||
|
||||
void SetGlobalPtr(void* pValue) override
|
||||
{
|
||||
if (m_ppGlobalPointer)
|
||||
{
|
||||
*m_ppGlobalPointer = reinterpret_cast<T*>(pValue);
|
||||
}
|
||||
}
|
||||
|
||||
bool IsReallocating() override { return true; }
|
||||
IGameSystem* GetStaticGameSystem() override { return nullptr; }
|
||||
|
||||
private:
|
||||
U** m_ppGlobalPointer;
|
||||
};
|
||||
|
||||
#endif // IGAMESYSTEMFACTORY_H
|
||||
Loading…
Reference in New Issue
Block a user