Counter Strike : Global Offensive Source Code
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.

247 lines
7.9 KiB

  1. //========= Copyright (c) 1996-2005, Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. // $NoKeywords: $
  6. //=============================================================================//
  7. #if !defined( FRAMESNAPSHOT_H )
  8. #define FRAMESNAPSHOT_H
  9. #ifdef _WIN32
  10. #pragma once
  11. #endif
  12. #include "tier0/platform.h"
  13. #include <mempool.h>
  14. #include <utllinkedlist.h>
  15. class PackedEntity;
  16. class HLTVEntityData;
  17. class ReplayEntityData;
  18. class ServerClass;
  19. class CEventInfo;
  20. #define INVALID_PACKED_ENTITY_HANDLE (0)
  21. typedef intp PackedEntityHandle_t;
  22. #ifdef _DEBUG
  23. // You can also enable snapshot references debugging in release mode
  24. #define DEBUG_SNAPSHOT_REFERENCES
  25. #endif
  26. //-----------------------------------------------------------------------------
  27. // Purpose: Individual entity data, did the entity exist and what was it's serial number
  28. //-----------------------------------------------------------------------------
  29. class CFrameSnapshotEntry
  30. {
  31. public:
  32. ServerClass* m_pClass;
  33. int m_nSerialNumber;
  34. // Keeps track of the fullpack info for this frame for all entities in any pvs:
  35. PackedEntityHandle_t m_pPackedData;
  36. size_t GetMemSize() const;
  37. };
  38. // HLTV needs some more data per entity
  39. class CHLTVEntityData
  40. {
  41. public:
  42. vec_t origin[3]; // entity position
  43. unsigned int m_nNodeCluster; // if (1<<31) is set it's a node, otherwise a cluster
  44. };
  45. // Replay needs some more data per entity
  46. class CReplayEntityData
  47. {
  48. public:
  49. vec_t origin[3]; // entity position
  50. unsigned int m_nNodeCluster; // if (1<<31) is set it's a node, otherwise a cluster
  51. };
  52. typedef struct
  53. {
  54. PackedEntity *pEntity; // original packed entity
  55. int counter; // increaseing counter to find LRU entries
  56. int bits; // uncompressed data length in bits
  57. ALIGN4 char data[MAX_PACKEDENTITY_DATA] ALIGN4_POST; // uncompressed data cache
  58. } UnpackedDataCache_t;
  59. //-----------------------------------------------------------------------------
  60. // Purpose: For all entities, stores whether the entity existed and what frame the
  61. // snapshot is for. Also tracks whether the snapshot is still referenced. When no
  62. // longer referenced, it's freed
  63. //-----------------------------------------------------------------------------
  64. class CFrameSnapshot
  65. {
  66. DECLARE_FIXEDSIZE_ALLOCATOR( CFrameSnapshot );
  67. public:
  68. // Reference-counting.
  69. void AddReference();
  70. void ReleaseReference();
  71. size_t GetMemSize()const;
  72. public:
  73. // Associated frame.
  74. int m_nTickCount; // = sv.tickcount
  75. // State information
  76. CFrameSnapshotEntry *m_pEntities;
  77. int m_nNumEntities; // = sv.num_edicts
  78. // This list holds the entities that are in use and that also aren't entities for inactive clients.
  79. unsigned short *m_pValidEntities;
  80. int m_nValidEntities;
  81. // Additional HLTV info
  82. CHLTVEntityData *m_pHLTVEntityData; // is NULL if not in HLTV mode or array of m_pValidEntities entries
  83. CReplayEntityData *m_pReplayEntityData; // is NULL if not in replay mode or array of m_pValidEntities entries
  84. CEventInfo **m_pTempEntities; // temp entities
  85. int m_nTempEntities;
  86. CUtlVector<int> m_iExplicitDeleteSlots;
  87. private:
  88. //don't allow for creation/destruction outside of frame snapshot manager and reference counting
  89. friend class CFrameSnapshotManager;
  90. CFrameSnapshot();
  91. ~CFrameSnapshot();
  92. // Index info CFrameSnapshotManager::m_FrameSnapshots.
  93. CInterlockedInt m_ListIndex;
  94. //the set that this snapshot belongs to
  95. uint32 m_nSnapshotSet;
  96. // Snapshots auto-delete themselves when their refcount goes to zero.
  97. CInterlockedInt m_nReferences;
  98. #ifdef DEBUG_SNAPSHOT_REFERENCES
  99. char m_chDebugSnapshotName[128];
  100. #endif
  101. };
  102. class CReferencedSnapshotList
  103. {
  104. public:
  105. ~CReferencedSnapshotList()
  106. {
  107. for ( int i = 0; i < m_vecSnapshots.Count(); ++i )
  108. {
  109. m_vecSnapshots[ i ]->ReleaseReference();
  110. }
  111. m_vecSnapshots.RemoveAll();
  112. }
  113. CUtlVector< CFrameSnapshot * > m_vecSnapshots;
  114. };
  115. //-----------------------------------------------------------------------------
  116. // Purpose: snapshot manager class
  117. //-----------------------------------------------------------------------------
  118. class CFrameSnapshotManager
  119. {
  120. friend class CFrameSnapshot;
  121. public:
  122. CFrameSnapshotManager( void );
  123. virtual ~CFrameSnapshotManager( void );
  124. // IFrameSnapshot implementation.
  125. public:
  126. //the default identifier to use for snapshots that are created
  127. static const uint32 knDefaultSnapshotSet = 0;
  128. // Called when a level change happens
  129. virtual void LevelChanged();
  130. // Called once per frame after simulation to store off all entities.
  131. // Note: the returned snapshot has a recount of 1 so you MUST call ReleaseReference on it. Snapshots are created into different sets,
  132. // so when enumerating snapshots, you only collect those in the desired set
  133. CFrameSnapshot* CreateEmptySnapshot(
  134. #ifdef DEBUG_SNAPSHOT_REFERENCES
  135. char const *szDebugName,
  136. #endif
  137. int ticknumber, int maxEntities, uint32 nSnapshotSet = knDefaultSnapshotSet );
  138. CFrameSnapshot* TakeTickSnapshot(
  139. #ifdef DEBUG_SNAPSHOT_REFERENCES
  140. char const *szDebugName,
  141. #endif
  142. int ticknumber, uint32 nSnapshotSet = knDefaultSnapshotSet );
  143. // Creates pack data for a particular entity for a particular snapshot
  144. PackedEntity* CreatePackedEntity( CFrameSnapshot* pSnapshot, int entity );
  145. //this is similar to the above, but the packed entity is created locally so that it doesn't interfere with the global last sent packet information
  146. PackedEntity* CreateLocalPackedEntity( CFrameSnapshot* pSnapshot, int entity );
  147. // Returns the pack data for a particular entity for a particular snapshot
  148. inline PackedEntity* GetPackedEntity( CFrameSnapshot& Snapshot, int entity );
  149. PackedEntity* GetPackedEntity( PackedEntityHandle_t handle ) { return m_PackedEntities[ handle ]; }
  150. // if we are copying a Packed Entity, we have to increase the reference counter
  151. void AddEntityReference( PackedEntityHandle_t handle );
  152. // if we are removeing a Packed Entity, we have to decrease the reference counter
  153. void RemoveEntityReference( PackedEntityHandle_t handle );
  154. // Uses a previously sent packet
  155. bool UsePreviouslySentPacket( CFrameSnapshot* pSnapshot, int entity, int entSerialNumber );
  156. bool ShouldForceRepack( CFrameSnapshot* pSnapshot, int entity, PackedEntityHandle_t handle );
  157. PackedEntity* GetPreviouslySentPacket( int iEntity, int iSerialNumber );
  158. // Return the entity sitting in iEntity's slot if iSerialNumber matches its number.
  159. UnpackedDataCache_t *GetCachedUncompressedEntity( PackedEntity *pPackedEntity );
  160. // List of entities to explicitly delete
  161. void AddExplicitDelete( int iSlot );
  162. void BuildSnapshotList( CFrameSnapshot *pCurrentSnapshot, CFrameSnapshot *pLastSnapshot, uint32 nSnapshotSet, CReferencedSnapshotList &list );
  163. private:
  164. void DeleteFrameSnapshot( CFrameSnapshot* pSnapshot );
  165. // Non-threadsafe call, used with BuildSnapshotList which acquires the mutex
  166. CFrameSnapshot *NextSnapshot( CFrameSnapshot *pSnapshot );
  167. // Mutex for m_FrameSnapshots array
  168. CThreadFastMutex m_FrameSnapshotsWriteMutex;
  169. CUtlLinkedList<CFrameSnapshot*, unsigned short> m_FrameSnapshots;
  170. CClassMemoryPool< PackedEntity > m_PackedEntitiesPool;
  171. CUtlFixedLinkedList<PackedEntity *> m_PackedEntities;
  172. int m_nPackedEntityCacheCounter; // increase with every cache access
  173. CUtlVector<UnpackedDataCache_t> m_PackedEntityCache; // cache for uncompressed packed entities
  174. // The most recently sent packets for each entity
  175. PackedEntityHandle_t m_pLastPackedData[ MAX_EDICTS ];
  176. int m_pSerialNumber[ MAX_EDICTS ];
  177. CThreadFastMutex m_WriteMutex;
  178. CUtlVector<int> m_iExplicitDeleteSlots;
  179. };
  180. PackedEntity* CFrameSnapshotManager::GetPackedEntity( CFrameSnapshot& Snapshot, int entity )
  181. {
  182. Assert( entity < Snapshot.m_nNumEntities );
  183. PackedEntityHandle_t index = Snapshot.m_pEntities[entity].m_pPackedData;
  184. if ( index == INVALID_PACKED_ENTITY_HANDLE )
  185. return NULL;
  186. Assert( m_PackedEntities[index]->m_nEntityIndex == entity );
  187. return m_PackedEntities[index];
  188. }
  189. extern CFrameSnapshotManager *framesnapshotmanager;
  190. #endif // FRAMESNAPSHOT_H