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.
273 lines
5.3 KiB
273 lines
5.3 KiB
5 years ago
|
//========= 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 );
|
||
|
}
|