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.
272 lines
5.3 KiB
272 lines
5.3 KiB
//========= Copyright Valve Corporation, All rights reserved. ============// |
|
// |
|
// Purpose: |
|
// |
|
//=============================================================================// |
|
|
|
#include "tier0/platform.h" |
|
#include "tier0/dbg.h" |
|
#include "clientframe.h" |
|
#include "framesnapshot.h" |
|
|
|
// memdbgon must be the last include file in a .cpp file!!! |
|
#include "tier0/memdbgon.h" |
|
|
|
CClientFrame::CClientFrame( CFrameSnapshot *pSnapshot ) |
|
{ |
|
last_entity = 0; |
|
transmit_always = NULL; // bit array used only by HLTV and replay client |
|
from_baseline = NULL; |
|
tick_count = pSnapshot->m_nTickCount; |
|
m_pSnapshot = NULL; |
|
SetSnapshot( pSnapshot ); |
|
m_pNext = NULL; |
|
} |
|
|
|
CClientFrame::CClientFrame( int tickcount ) |
|
{ |
|
last_entity = 0; |
|
transmit_always = NULL; // bit array used only by HLTV and replay client |
|
from_baseline = NULL; |
|
tick_count = tickcount; |
|
m_pSnapshot = NULL; |
|
m_pNext = NULL; |
|
} |
|
|
|
CClientFrame::CClientFrame( void ) |
|
{ |
|
last_entity = 0; |
|
transmit_always = NULL; // bit array used only by HLTV and replay client |
|
from_baseline = NULL; |
|
tick_count = 0; |
|
m_pSnapshot = NULL; |
|
m_pNext = NULL; |
|
} |
|
|
|
void CClientFrame::Init( int tickcount ) |
|
{ |
|
tick_count = tickcount; |
|
} |
|
|
|
void CClientFrame::Init( CFrameSnapshot *pSnapshot ) |
|
{ |
|
tick_count = pSnapshot->m_nTickCount; |
|
SetSnapshot( pSnapshot ); |
|
} |
|
|
|
CClientFrame::~CClientFrame() |
|
{ |
|
SetSnapshot( NULL ); // Release our reference to the snapshot. |
|
|
|
if ( transmit_always != NULL ) |
|
{ |
|
delete transmit_always; |
|
transmit_always = NULL; |
|
} |
|
} |
|
|
|
void CClientFrame::SetSnapshot( CFrameSnapshot *pSnapshot ) |
|
{ |
|
if ( m_pSnapshot == pSnapshot ) |
|
return; |
|
|
|
if( pSnapshot ) |
|
pSnapshot->AddReference(); |
|
|
|
if ( m_pSnapshot ) |
|
m_pSnapshot->ReleaseReference(); |
|
|
|
m_pSnapshot = pSnapshot; |
|
} |
|
|
|
void CClientFrame::CopyFrame( CClientFrame &frame ) |
|
{ |
|
tick_count = frame.tick_count; |
|
last_entity = frame.last_entity; |
|
|
|
SetSnapshot( frame.GetSnapshot() ); // adds reference to snapshot |
|
|
|
transmit_entity = frame.transmit_entity; |
|
|
|
if ( frame.transmit_always ) |
|
{ |
|
Assert( transmit_always == NULL ); |
|
transmit_always = new CBitVec<MAX_EDICTS>; |
|
*transmit_always = *(frame.transmit_always); |
|
} |
|
} |
|
|
|
CClientFrame *CClientFrameManager::GetClientFrame( int nTick, bool bExact ) |
|
{ |
|
if ( nTick < 0 ) |
|
return NULL; |
|
|
|
CClientFrame *frame = m_Frames; |
|
CClientFrame *lastFrame = frame; |
|
|
|
while ( frame != NULL ) |
|
{ |
|
if ( frame->tick_count >= nTick ) |
|
{ |
|
if ( frame->tick_count == nTick ) |
|
return frame; |
|
|
|
if ( bExact ) |
|
return NULL; |
|
|
|
return lastFrame; |
|
} |
|
|
|
lastFrame = frame; |
|
frame = frame->m_pNext; |
|
} |
|
|
|
if ( bExact ) |
|
return NULL; |
|
|
|
return lastFrame; |
|
} |
|
|
|
int CClientFrameManager::CountClientFrames( void ) |
|
{ |
|
|
|
#if _DEBUG |
|
int count = 0; |
|
CClientFrame *f = m_Frames; |
|
while ( f ) |
|
{ |
|
count++; |
|
f = f->m_pNext; |
|
} |
|
Assert( m_nFrames == count ); |
|
#endif |
|
|
|
return m_nFrames; |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
// Input : *cl - |
|
//----------------------------------------------------------------------------- |
|
int CClientFrameManager::AddClientFrame( CClientFrame *frame) |
|
{ |
|
Assert( frame->tick_count > 0 ); |
|
|
|
if ( !m_Frames ) |
|
{ |
|
// first client frame at all |
|
Assert( m_LastFrame == NULL && m_nFrames == 0 ); |
|
m_Frames = frame; |
|
m_LastFrame = frame; |
|
m_nFrames = 1; |
|
return 1; |
|
} |
|
|
|
Assert( m_Frames != NULL && m_nFrames > 0 ); |
|
Assert( m_LastFrame->m_pNext == NULL ); |
|
m_LastFrame->m_pNext = frame; |
|
m_LastFrame = frame; |
|
return ++m_nFrames; |
|
} |
|
|
|
void CClientFrameManager::RemoveOldestFrame( void ) |
|
{ |
|
CClientFrame *frame = m_Frames; // first |
|
|
|
if ( !frame ) |
|
return; // no frames at all |
|
|
|
Assert( m_nFrames > 0 ); |
|
m_Frames = frame->m_pNext; // unlink head |
|
// deleting frame will decrease global reference counter |
|
FreeFrame( frame ); |
|
|
|
if ( --m_nFrames == 0 ) |
|
{ |
|
Assert( m_LastFrame == frame && m_Frames == NULL ); |
|
m_LastFrame = NULL; |
|
} |
|
} |
|
|
|
void CClientFrameManager::DeleteClientFrames(int nTick) |
|
{ |
|
|
|
if ( nTick < 0 ) |
|
{ |
|
while ( m_nFrames > 0 ) |
|
{ |
|
RemoveOldestFrame(); |
|
} |
|
} |
|
else |
|
{ |
|
CClientFrame *frame = m_Frames; |
|
// rebuild m_LastFrame while iterating forward through the list |
|
m_LastFrame = NULL; |
|
while ( frame ) |
|
{ |
|
if ( frame->tick_count < nTick ) |
|
{ |
|
// Delete this frame |
|
CClientFrame* next = frame->m_pNext; |
|
if ( m_Frames == frame ) |
|
m_Frames = next; |
|
FreeFrame( frame ); |
|
if ( --m_nFrames == 0 ) |
|
{ |
|
Assert( next == NULL ); |
|
m_LastFrame = m_Frames = NULL; |
|
break; |
|
} |
|
Assert( m_LastFrame != frame && m_nFrames > 0 ); |
|
frame = next; |
|
if ( m_LastFrame ) |
|
m_LastFrame->m_pNext = next; |
|
} |
|
else |
|
{ |
|
Assert( m_LastFrame == NULL || m_LastFrame->m_pNext == frame ); |
|
m_LastFrame = frame; |
|
frame = frame->m_pNext; |
|
} |
|
} |
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Class factory for frames |
|
//----------------------------------------------------------------------------- |
|
CClientFrame* CClientFrameManager::AllocateFrame() |
|
{ |
|
return m_ClientFramePool.Alloc(); |
|
} |
|
|
|
void CClientFrameManager::FreeFrame( CClientFrame* pFrame ) |
|
{ |
|
if ( pFrame->IsMemPoolAllocated() ) |
|
{ |
|
m_ClientFramePool.Free( pFrame ); |
|
} |
|
else |
|
{ |
|
delete pFrame; |
|
} |
|
} |
|
|
|
CClientFrameManager::CClientFrameManager( void ) |
|
: m_ClientFramePool( MAX_CLIENT_FRAMES, CUtlMemoryPool::GROW_SLOW ), |
|
m_Frames(NULL), |
|
m_LastFrame(NULL), |
|
m_nFrames(0) |
|
{ |
|
} |
|
|
|
CClientFrameManager::~CClientFrameManager( void ) |
|
{ |
|
DeleteClientFrames( -1 ); |
|
Assert( m_nFrames == 0 ); |
|
}
|
|
|