//====== Copyright ©, Valve Corporation, All rights reserved. ================= // // Purpose: Defines a directory for all the GC processes for an app // //============================================================================= #ifndef DIRECTORY_H #define DIRECTORY_H #ifdef _WIN32 #pragma once #endif #include "tier1/utlvector.h" #include "tier1/utlsortvector.h" #include "tier1/utlmap.h" #include "tier1/keyvalues.h" #include "gamecoordinator/igamecoordinator.h" namespace GCSDK { class CGCDirProcess; //----------------------------------------------------------------------------- // Purpose: Entry for a GC instance //----------------------------------------------------------------------------- class CGCDirTypeInstance { public: CGCDirTypeInstance( const char* pszTypeName, uint32 nType, uint32 nInstance, const KeyValues *pKVConfig, const CGCDirProcess* pProcess ); ~CGCDirTypeInstance(); uint32 GetType() const; const char* GetTypeName() const; uint32 GetInstance() const; KeyValues * GetConfig() const; const CGCDirProcess* GetProcess() const; private: int32 m_nType; uint32 m_nInstance; KeyValues * m_pConfig; CUtlConstString m_sTypeName; const CGCDirProcess* m_pProcess; }; //----------------------------------------------------------------------------- // Purpose: Entry for a physical machine hosting one or more GC instances //----------------------------------------------------------------------------- class CGCDirProcess { public: CGCDirProcess( uint32 nDirIndex, const char *pchProcessName, const char* pchProcessType, const KeyValues *pKVConfig ); ~CGCDirProcess( ); //determines if this process has any GC's of the specified type bool HasInstanceOfType( uint32 nType ) const; uint32 GetGCDirIndex() const; const char * GetName() const; const char * GetProcessType() const; uint32 GetTypeInstanceCount() const; KeyValues * GetConfig() const; const CGCDirTypeInstance * GetTypeInstance( uint32 nGCIndex ) const; //gets the list of unique types contained within this process as IDs (note order does not match) const CUtlSortVector< uint32 >& GetUniqueTypeList() const; private: friend class CDirectory; void AddGC( CGCDirTypeInstance *pGC ); uint32 m_iDirGC; CUtlConstString m_sName; CUtlConstString m_sType; KeyValues * m_pConfig; CUtlVector m_vecGCs; //a bit mask of which types exist on this GC uint64 m_nTypeMask; //optimized list for fast searching of which types this process has CUtlSortVector< uint32 > m_vecUniqueTypeList; }; //----------------------------------------------------------------------------- // Purpose: Defines what kind of GCs exist for this app in the current universe, // the types that exist, and what machines they run on //----------------------------------------------------------------------------- class CDirectory { public: typedef CGCBase *(*GCFactory_t)( const CGCDirProcess *pGCDirProcess ); static const int s_nInvalidGCType = -1; CDirectory(); ~CDirectory(); bool BInit( KeyValues *pKVDirectory ); void RegisterGCType( int32 nTypeID, const char *pchName ); uint32 GetProcessCount() const; const CGCDirProcess *GetProcess( int32 nIndex ) const; uint32 GetGCTypeInstanceCount() const; const CGCDirTypeInstance *GetGCTypeInstance( uint32 nTypeInst ) const; int32 GetGCCountForType( int32 nTypeID ) const; const CGCDirTypeInstance *GetGCInstanceForType( int32 nTypeID, int32 nInstance ) const; const char *GetNameForGCType( int32 nTypeID ) const; int32 GetGCTypeForName( const char *pchName ) const; void RegisterProcessTypeFactory( const char* pszProcessType, GCFactory_t pfnFactory ); GCFactory_t GetFactoryForProcessType( const char* pszProcessType ) const; //given a GC type, and an instance number, this will return the GC directory index used for routing. If the instance number //is greater than what is available, it will be modulo'd into the acceptable range. If no match for that type can be found, -1 will //be returned int32 GetGCDirIndexForInstance( int32 nTypeID, uint32 nInstanceIndex ) const; //given a GC type, this will add all of the GC indices associated with that type onto the provided vector void GetGCDirIndicesForType( int32 nTypeID, CUtlVector< uint32 >& nIndices ) const; private: bool m_bInitialized; CUtlVector m_vecProcesses; CUtlVector m_vecTypeInstances; CUtlMap< int32, CCopyableUtlVector< CGCDirTypeInstance *> > m_mapGCsByType; struct RegisteredGCType_t { CUtlConstString m_strName; }; CUtlMap< int32, RegisteredGCType_t > m_mapRegisteredGCTypes; CUtlDict< int32 > m_dictRegisteredGCNameToType; CUtlDict< GCFactory_t > m_dictProcessTypeToFactory; }; // Gets the global directory singleton extern CDirectory *GDirectory(); //the maximum value that a GC type can use. This is to enable bit masks to encode type information primarily (also don't allow the high bit to avoid SQL signed issues) #define GC_TYPE_MAX_NUMBER 62 // Registration macro for GC types #define REG_GC_TYPE( typeNum, typeName ) \ static class CRegGC_##typeName \ { \ public: \ CRegGC_##typeName() { \ COMPILE_TIME_ASSERT( typeNum <= GC_TYPE_MAX_NUMBER ); \ GDirectory()->RegisterGCType( ( typeNum ), ( #typeName ) ); } \ } g_RegGC_##typeName; #define REG_GC_PROCESS_TYPE( gcClass, typeName ) \ static class CRegProcessType_##typeName \ { \ public: \ static CGCBase *Factory( const CGCDirProcess *pDirGC ) { return new gcClass( pDirGC ); } \ CRegProcessType_##typeName() { GDirectory()->RegisterProcessTypeFactory( ( #typeName ), &Factory ); } \ } g_RegProcessType_##typeName; } // namespace GCSDK #endif // DIRECTORY_H