initial
This commit is contained in:
247
engine/framesnapshot.h
Normal file
247
engine/framesnapshot.h
Normal file
@@ -0,0 +1,247 @@
|
||||
//========= Copyright (c) 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
#if !defined( FRAMESNAPSHOT_H )
|
||||
#define FRAMESNAPSHOT_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "tier0/platform.h"
|
||||
|
||||
#include <mempool.h>
|
||||
#include <utllinkedlist.h>
|
||||
|
||||
|
||||
class PackedEntity;
|
||||
class HLTVEntityData;
|
||||
class ReplayEntityData;
|
||||
class ServerClass;
|
||||
class CEventInfo;
|
||||
|
||||
#define INVALID_PACKED_ENTITY_HANDLE (0)
|
||||
typedef intp PackedEntityHandle_t;
|
||||
|
||||
#ifdef _DEBUG
|
||||
// You can also enable snapshot references debugging in release mode
|
||||
#define DEBUG_SNAPSHOT_REFERENCES
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// 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;
|
||||
|
||||
size_t GetMemSize() const;
|
||||
};
|
||||
|
||||
// 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
|
||||
ALIGN4 char data[MAX_PACKEDENTITY_DATA] ALIGN4_POST; // 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:
|
||||
// Reference-counting.
|
||||
void AddReference();
|
||||
void ReleaseReference();
|
||||
|
||||
size_t GetMemSize()const;
|
||||
public:
|
||||
// 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:
|
||||
|
||||
//don't allow for creation/destruction outside of frame snapshot manager and reference counting
|
||||
friend class CFrameSnapshotManager;
|
||||
CFrameSnapshot();
|
||||
~CFrameSnapshot();
|
||||
|
||||
// Index info CFrameSnapshotManager::m_FrameSnapshots.
|
||||
CInterlockedInt m_ListIndex;
|
||||
|
||||
//the set that this snapshot belongs to
|
||||
uint32 m_nSnapshotSet;
|
||||
|
||||
// Snapshots auto-delete themselves when their refcount goes to zero.
|
||||
CInterlockedInt m_nReferences;
|
||||
|
||||
#ifdef DEBUG_SNAPSHOT_REFERENCES
|
||||
char m_chDebugSnapshotName[128];
|
||||
#endif
|
||||
};
|
||||
|
||||
class CReferencedSnapshotList
|
||||
{
|
||||
public:
|
||||
~CReferencedSnapshotList()
|
||||
{
|
||||
for ( int i = 0; i < m_vecSnapshots.Count(); ++i )
|
||||
{
|
||||
m_vecSnapshots[ i ]->ReleaseReference();
|
||||
}
|
||||
m_vecSnapshots.RemoveAll();
|
||||
}
|
||||
|
||||
CUtlVector< CFrameSnapshot * > m_vecSnapshots;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: snapshot manager class
|
||||
//-----------------------------------------------------------------------------
|
||||
class CFrameSnapshotManager
|
||||
{
|
||||
friend class CFrameSnapshot;
|
||||
|
||||
public:
|
||||
CFrameSnapshotManager( void );
|
||||
virtual ~CFrameSnapshotManager( void );
|
||||
|
||||
// IFrameSnapshot implementation.
|
||||
public:
|
||||
|
||||
//the default identifier to use for snapshots that are created
|
||||
static const uint32 knDefaultSnapshotSet = 0;
|
||||
|
||||
// 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. Snapshots are created into different sets,
|
||||
// so when enumerating snapshots, you only collect those in the desired set
|
||||
CFrameSnapshot* CreateEmptySnapshot(
|
||||
#ifdef DEBUG_SNAPSHOT_REFERENCES
|
||||
char const *szDebugName,
|
||||
#endif
|
||||
int ticknumber, int maxEntities, uint32 nSnapshotSet = knDefaultSnapshotSet );
|
||||
CFrameSnapshot* TakeTickSnapshot(
|
||||
#ifdef DEBUG_SNAPSHOT_REFERENCES
|
||||
char const *szDebugName,
|
||||
#endif
|
||||
int ticknumber, uint32 nSnapshotSet = knDefaultSnapshotSet );
|
||||
|
||||
// Creates pack data for a particular entity for a particular snapshot
|
||||
PackedEntity* CreatePackedEntity( CFrameSnapshot* pSnapshot, int entity );
|
||||
//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
|
||||
PackedEntity* CreateLocalPackedEntity( CFrameSnapshot* pSnapshot, int entity );
|
||||
|
||||
// Returns the pack data for a particular entity for a particular snapshot
|
||||
inline PackedEntity* GetPackedEntity( CFrameSnapshot& Snapshot, int entity );
|
||||
PackedEntity* GetPackedEntity( PackedEntityHandle_t handle ) { return m_PackedEntities[ handle ]; }
|
||||
|
||||
// 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 );
|
||||
|
||||
// List of entities to explicitly delete
|
||||
void AddExplicitDelete( int iSlot );
|
||||
|
||||
void BuildSnapshotList( CFrameSnapshot *pCurrentSnapshot, CFrameSnapshot *pLastSnapshot, uint32 nSnapshotSet, CReferencedSnapshotList &list );
|
||||
|
||||
private:
|
||||
void DeleteFrameSnapshot( CFrameSnapshot* pSnapshot );
|
||||
// Non-threadsafe call, used with BuildSnapshotList which acquires the mutex
|
||||
CFrameSnapshot *NextSnapshot( CFrameSnapshot *pSnapshot );
|
||||
|
||||
// Mutex for m_FrameSnapshots array
|
||||
CThreadFastMutex m_FrameSnapshotsWriteMutex;
|
||||
CUtlLinkedList<CFrameSnapshot*, unsigned short> m_FrameSnapshots;
|
||||
|
||||
CClassMemoryPool< PackedEntity > m_PackedEntitiesPool;
|
||||
CUtlFixedLinkedList<PackedEntity *> m_PackedEntities;
|
||||
|
||||
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_pLastPackedData[ MAX_EDICTS ];
|
||||
int m_pSerialNumber[ MAX_EDICTS ];
|
||||
|
||||
CThreadFastMutex m_WriteMutex;
|
||||
|
||||
CUtlVector<int> m_iExplicitDeleteSlots;
|
||||
};
|
||||
|
||||
PackedEntity* CFrameSnapshotManager::GetPackedEntity( CFrameSnapshot& Snapshot, int entity )
|
||||
{
|
||||
Assert( entity < Snapshot.m_nNumEntities );
|
||||
PackedEntityHandle_t index = Snapshot.m_pEntities[entity].m_pPackedData;
|
||||
if ( index == INVALID_PACKED_ENTITY_HANDLE )
|
||||
return NULL;
|
||||
|
||||
Assert( m_PackedEntities[index]->m_nEntityIndex == entity );
|
||||
return m_PackedEntities[index];
|
||||
}
|
||||
|
||||
extern CFrameSnapshotManager *framesnapshotmanager;
|
||||
|
||||
|
||||
#endif // FRAMESNAPSHOT_H
|
||||
Reference in New Issue
Block a user