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
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
|
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#if !defined( FRAMESNAPSHOT_H )
#define FRAMESNAPSHOT_H
#ifdef _WIN32
#pragma once
#endif
#include <mempool.h>
#include <utllinkedlist.h>
class PackedEntity;
class HLTVEntityData;
class ReplayEntityData;
class ServerClass;
class CEventInfo;
#define INVALID_PACKED_ENTITY_HANDLE (0)
typedef intptr_t PackedEntityHandle_t;
//-----------------------------------------------------------------------------
// Purpose: Individual entity data, did the entity exist and what was it's serial number
//-----------------------------------------------------------------------------
class CFrameSnapshotEntry
{
public:
ServerClass* m_pClass;
int m_nSerialNumber;
// Keeps track of the fullpack info for this frame for all entities in any pvs:
PackedEntityHandle_t m_pPackedData;
};
// HLTV needs some more data per entity
class CHLTVEntityData
{
public:
vec_t origin[3]; // entity position
unsigned int m_nNodeCluster; // if (1<<31) is set it's a node, otherwise a cluster
};
// Replay needs some more data per entity
class CReplayEntityData
{
public:
vec_t origin[3]; // entity position
unsigned int m_nNodeCluster; // if (1<<31) is set it's a node, otherwise a cluster
};
typedef struct
{
PackedEntity *pEntity; // original packed entity
int counter; // increaseing counter to find LRU entries
int bits; // uncompressed data length in bits
char data[MAX_PACKEDENTITY_DATA]; // uncompressed data cache
} UnpackedDataCache_t;
//-----------------------------------------------------------------------------
// Purpose: For all entities, stores whether the entity existed and what frame the
// snapshot is for. Also tracks whether the snapshot is still referenced. When no
// longer referenced, it's freed
//-----------------------------------------------------------------------------
class CFrameSnapshot
{
DECLARE_FIXEDSIZE_ALLOCATOR( CFrameSnapshot );
public:
CFrameSnapshot();
~CFrameSnapshot();
// Reference-counting.
void AddReference();
void ReleaseReference();
CFrameSnapshot* NextSnapshot() const;
public:
CInterlockedInt m_ListIndex; // Index info CFrameSnapshotManager::m_FrameSnapshots.
// Associated frame.
int m_nTickCount; // = sv.tickcount
// State information
CFrameSnapshotEntry *m_pEntities;
int m_nNumEntities; // = sv.num_edicts
// This list holds the entities that are in use and that also aren't entities for inactive clients.
unsigned short *m_pValidEntities;
int m_nValidEntities;
// Additional HLTV info
CHLTVEntityData *m_pHLTVEntityData; // is NULL if not in HLTV mode or array of m_pValidEntities entries
CReplayEntityData *m_pReplayEntityData; // is NULL if not in replay mode or array of m_pValidEntities entries
CEventInfo **m_pTempEntities; // temp entities
int m_nTempEntities;
CUtlVector<int> m_iExplicitDeleteSlots;
private:
// Snapshots auto-delete themselves when their refcount goes to zero.
CInterlockedInt m_nReferences;
};
//-----------------------------------------------------------------------------
// Purpose: snapshot manager class
//-----------------------------------------------------------------------------
class CFrameSnapshotManager
{
friend class CFrameSnapshot;
public:
CFrameSnapshotManager( void );
virtual ~CFrameSnapshotManager( void );
// IFrameSnapshot implementation.
public:
// Called when a level change happens
virtual void LevelChanged();
// Called once per frame after simulation to store off all entities.
// Note: the returned snapshot has a recount of 1 so you MUST call ReleaseReference on it.
CFrameSnapshot* CreateEmptySnapshot( int ticknumber, int maxEntities );
CFrameSnapshot* TakeTickSnapshot( int ticknumber );
CFrameSnapshot* NextSnapshot( const CFrameSnapshot *pSnapshot );
// Creates pack data for a particular entity for a particular snapshot
PackedEntity* CreatePackedEntity( CFrameSnapshot* pSnapshot, int entity );
// Returns the pack data for a particular entity for a particular snapshot
PackedEntity* GetPackedEntity( CFrameSnapshot* pSnapshot, int entity );
// if we are copying a Packed Entity, we have to increase the reference counter
void AddEntityReference( PackedEntityHandle_t handle );
// if we are removeing a Packed Entity, we have to decrease the reference counter
void RemoveEntityReference( PackedEntityHandle_t handle );
// Uses a previously sent packet
bool UsePreviouslySentPacket( CFrameSnapshot* pSnapshot, int entity, int entSerialNumber );
bool ShouldForceRepack( CFrameSnapshot* pSnapshot, int entity, PackedEntityHandle_t handle );
PackedEntity* GetPreviouslySentPacket( int iEntity, int iSerialNumber );
// Return the entity sitting in iEntity's slot if iSerialNumber matches its number.
UnpackedDataCache_t *GetCachedUncompressedEntity( PackedEntity *pPackedEntity );
CThreadFastMutex &GetMutex();
// List of entities to explicitly delete
void AddExplicitDelete( int iSlot );
private:
void DeleteFrameSnapshot( CFrameSnapshot* pSnapshot );
CUtlLinkedList<CFrameSnapshot*, unsigned short> m_FrameSnapshots;
CClassMemoryPool< PackedEntity > m_PackedEntitiesPool;
int m_nPackedEntityCacheCounter; // increase with every cache access
CUtlVector<UnpackedDataCache_t> m_PackedEntityCache; // cache for uncompressed packed entities
// The most recently sent packets for each entity
PackedEntityHandle_t m_pPackedData[ MAX_EDICTS ];
int m_pSerialNumber[ MAX_EDICTS ];
CThreadFastMutex m_WriteMutex;
CUtlVector<int> m_iExplicitDeleteSlots;
};
extern CFrameSnapshotManager *framesnapshotmanager;
#endif // FRAMESNAPSHOT_H
|