summaryrefslogtreecommitdiff
path: root/public/gcsdk/directory.h
blob: dfdef85f0c5df5e1913d64e4e8ea8d5b83475934 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
//====== 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<CGCDirTypeInstance *>	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<CGCDirProcess *>			m_vecProcesses;
	CUtlVector<CGCDirTypeInstance *>	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