//========= Copyright Valve Corporation, All rights reserved. ============// // // Purpose: // // $NoKeywords: $ //=============================================================================// #ifndef IGAMESYSTEM_H #define IGAMESYSTEM_H #ifdef _WIN32 #pragma once #endif //----------------------------------------------------------------------------- // Game systems are singleton objects in the client + server codebase // responsible for various tasks The order in which the server systems appear in // this list are the order in which they are initialized and updated. They are // shut down in reverse order from which they are initialized. //----------------------------------------------------------------------------- // 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; virtual void LevelShutdownPreClearSteamAPIContext(){}; 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; // Called during game restore, after the local player has connected and // entities have been fully restored virtual void OnRestore() = 0; // Called every frame. It's safe to remove an igamesystem from within this // callback. virtual void SafeRemoveIfDesired() = 0; virtual bool IsPerFrame() = 0; // destructor, cleans up automagically.... virtual ~IGameSystem(); // Client systems can use this to get at the map name static char const *MapName(); // 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 LevelShutdownPreClearSteamAPIContextAllSystems(); // Called prior to // steamgameserverapicontext->Clear() 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 static CBasePlayer *RunCommandPlayer(); static CUserCmd *RunCommandUserCmd(); #endif }; class IGameSystemPerFrame : public IGameSystem { public: // destructor, cleans up automagically.... virtual ~IGameSystemPerFrame(); #ifdef CLIENT_DLL // Called before rendering virtual void PreRender() = 0; // Gets called each frame virtual void Update(float frametime) = 0; // Called after rendering virtual void PostRender() = 0; #else // Called each frame before entities think virtual void FrameUpdatePreEntityThink() = 0; // called after entities think virtual void FrameUpdatePostEntityThink() = 0; virtual void PreClientUpdate() = 0; #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 CBaseGameSystem : public IGameSystem { 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 LevelShutdownPreClearSteamAPIContext() {} virtual void LevelShutdownPreEntity() {} virtual void LevelShutdownPostEntity() {} virtual void OnSave() {} virtual void OnRestore() {} virtual void SafeRemoveIfDesired() {} 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 }; // 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 LevelShutdownPreClearSteamAPIContext() {} 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; }; #endif // IGAMESYSTEM_H