diff options
Diffstat (limited to 'engine/clientframe.cpp')
| -rw-r--r-- | engine/clientframe.cpp | 272 |
1 files changed, 272 insertions, 0 deletions
diff --git a/engine/clientframe.cpp b/engine/clientframe.cpp new file mode 100644 index 0000000..97a6c68 --- /dev/null +++ b/engine/clientframe.cpp @@ -0,0 +1,272 @@ +//========= 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 ); +} |