Team Fortress 2 Source Code as on 22/4/2020
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

146 lines
3.9 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. // $NoKeywords: $
  6. //
  7. //=============================================================================//
  8. #ifndef SERVER_CLASS_H
  9. #define SERVER_CLASS_H
  10. #ifdef _WIN32
  11. #pragma once
  12. #endif
  13. #include "tier0/dbg.h"
  14. #include "dt_send.h"
  15. #include "networkstringtabledefs.h"
  16. class ServerClass;
  17. class SendTable;
  18. extern ServerClass *g_pServerClassHead;
  19. class ServerClass
  20. {
  21. public:
  22. ServerClass( const char *pNetworkName, SendTable *pTable )
  23. {
  24. m_pNetworkName = pNetworkName;
  25. m_pTable = pTable;
  26. m_InstanceBaselineIndex = INVALID_STRING_INDEX;
  27. // g_pServerClassHead is sorted alphabetically, so find the correct place to insert
  28. if ( !g_pServerClassHead )
  29. {
  30. g_pServerClassHead = this;
  31. m_pNext = NULL;
  32. }
  33. else
  34. {
  35. ServerClass *p1 = g_pServerClassHead;
  36. ServerClass *p2 = p1->m_pNext;
  37. // use _stricmp because Q_stricmp isn't hooked up properly yet
  38. if ( _stricmp( p1->GetName(), pNetworkName ) > 0)
  39. {
  40. m_pNext = g_pServerClassHead;
  41. g_pServerClassHead = this;
  42. p1 = NULL;
  43. }
  44. while( p1 )
  45. {
  46. if ( p2 == NULL || _stricmp( p2->GetName(), pNetworkName ) > 0)
  47. {
  48. m_pNext = p2;
  49. p1->m_pNext = this;
  50. break;
  51. }
  52. p1 = p2;
  53. p2 = p2->m_pNext;
  54. }
  55. }
  56. }
  57. const char* GetName() { return m_pNetworkName; }
  58. public:
  59. const char *m_pNetworkName;
  60. SendTable *m_pTable;
  61. ServerClass *m_pNext;
  62. int m_ClassID; // Managed by the engine.
  63. // This is an index into the network string table (sv.GetInstanceBaselineTable()).
  64. int m_InstanceBaselineIndex; // INVALID_STRING_INDEX if not initialized yet.
  65. };
  66. class CBaseNetworkable;
  67. // If you do a DECLARE_SERVERCLASS, you need to do this inside the class definition.
  68. #define DECLARE_SERVERCLASS() \
  69. public: \
  70. virtual ServerClass* GetServerClass(); \
  71. static SendTable *m_pClassSendTable; \
  72. template <typename T> friend int ServerClassInit(T *); \
  73. virtual int YouForgotToImplementOrDeclareServerClass(); \
  74. #define DECLARE_SERVERCLASS_NOBASE() \
  75. public: \
  76. template <typename T> friend int ServerClassInit(T *); \
  77. // Use this macro to expose your class's data across the network.
  78. #define IMPLEMENT_SERVERCLASS( DLLClassName, sendTable ) \
  79. IMPLEMENT_SERVERCLASS_INTERNAL( DLLClassName, sendTable )
  80. // You can use this instead of BEGIN_SEND_TABLE and it will do a DECLARE_SERVERCLASS automatically.
  81. #define IMPLEMENT_SERVERCLASS_ST(DLLClassName, sendTable) \
  82. IMPLEMENT_SERVERCLASS_INTERNAL( DLLClassName, sendTable )\
  83. BEGIN_SEND_TABLE(DLLClassName, sendTable)
  84. #define IMPLEMENT_SERVERCLASS_ST_NOBASE(DLLClassName, sendTable) \
  85. IMPLEMENT_SERVERCLASS_INTERNAL( DLLClassName, sendTable )\
  86. BEGIN_SEND_TABLE_NOBASE( DLLClassName, sendTable )
  87. #ifdef VALIDATE_DECLARE_CLASS
  88. #define CHECK_DECLARE_CLASS( DLLClassName, sendTable ) \
  89. template <typename T> int CheckDeclareClass_Access(T *); \
  90. template <> int CheckDeclareClass_Access<sendTable::ignored>(sendTable::ignored *, const char *pIgnored) \
  91. { \
  92. return DLLClassName::CheckDeclareClass( #DLLClassName ); \
  93. } \
  94. namespace sendTable \
  95. { \
  96. int verifyDeclareClass = CheckDeclareClass_Access( (sendTable::ignored*)0 ); \
  97. }
  98. #else
  99. #define CHECK_DECLARE_CLASS( DLLClassName, sendTable )
  100. #endif
  101. #define IMPLEMENT_SERVERCLASS_INTERNAL( DLLClassName, sendTable ) \
  102. namespace sendTable \
  103. { \
  104. struct ignored; \
  105. extern SendTable g_SendTable; \
  106. } \
  107. CHECK_DECLARE_CLASS( DLLClassName, sendTable ) \
  108. static ServerClass g_##DLLClassName##_ClassReg(\
  109. #DLLClassName, \
  110. &sendTable::g_SendTable\
  111. ); \
  112. \
  113. ServerClass* DLLClassName::GetServerClass() {return &g_##DLLClassName##_ClassReg;} \
  114. SendTable *DLLClassName::m_pClassSendTable = &sendTable::g_SendTable;\
  115. int DLLClassName::YouForgotToImplementOrDeclareServerClass() {return 0;}
  116. #endif