Team Fortress 2 Source Code as on 22/4/2020
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

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. //=============================================================================//
  6. #include "tier0/platform.h"
  7. #include "tier0/dbg.h"
  8. #include "clientframe.h"
  9. #include "framesnapshot.h"
  10. // memdbgon must be the last include file in a .cpp file!!!
  11. #include "tier0/memdbgon.h"
  12. CClientFrame::CClientFrame( CFrameSnapshot *pSnapshot )
  13. {
  14. last_entity = 0;
  15. transmit_always = NULL; // bit array used only by HLTV and replay client
  16. from_baseline = NULL;
  17. tick_count = pSnapshot->m_nTickCount;
  18. m_pSnapshot = NULL;
  19. SetSnapshot( pSnapshot );
  20. m_pNext = NULL;
  21. }
  22. CClientFrame::CClientFrame( int tickcount )
  23. {
  24. last_entity = 0;
  25. transmit_always = NULL; // bit array used only by HLTV and replay client
  26. from_baseline = NULL;
  27. tick_count = tickcount;
  28. m_pSnapshot = NULL;
  29. m_pNext = NULL;
  30. }
  31. CClientFrame::CClientFrame( void )
  32. {
  33. last_entity = 0;
  34. transmit_always = NULL; // bit array used only by HLTV and replay client
  35. from_baseline = NULL;
  36. tick_count = 0;
  37. m_pSnapshot = NULL;
  38. m_pNext = NULL;
  39. }
  40. void CClientFrame::Init( int tickcount )
  41. {
  42. tick_count = tickcount;
  43. }
  44. void CClientFrame::Init( CFrameSnapshot *pSnapshot )
  45. {
  46. tick_count = pSnapshot->m_nTickCount;
  47. SetSnapshot( pSnapshot );
  48. }
  49. CClientFrame::~CClientFrame()
  50. {
  51. SetSnapshot( NULL ); // Release our reference to the snapshot.
  52. if ( transmit_always != NULL )
  53. {
  54. delete transmit_always;
  55. transmit_always = NULL;
  56. }
  57. }
  58. void CClientFrame::SetSnapshot( CFrameSnapshot *pSnapshot )
  59. {
  60. if ( m_pSnapshot == pSnapshot )
  61. return;
  62. if( pSnapshot )
  63. pSnapshot->AddReference();
  64. if ( m_pSnapshot )
  65. m_pSnapshot->ReleaseReference();
  66. m_pSnapshot = pSnapshot;
  67. }
  68. void CClientFrame::CopyFrame( CClientFrame &frame )
  69. {
  70. tick_count = frame.tick_count;
  71. last_entity = frame.last_entity;
  72. SetSnapshot( frame.GetSnapshot() ); // adds reference to snapshot
  73. transmit_entity = frame.transmit_entity;
  74. if ( frame.transmit_always )
  75. {
  76. Assert( transmit_always == NULL );
  77. transmit_always = new CBitVec<MAX_EDICTS>;
  78. *transmit_always = *(frame.transmit_always);
  79. }
  80. }
  81. CClientFrame *CClientFrameManager::GetClientFrame( int nTick, bool bExact )
  82. {
  83. if ( nTick < 0 )
  84. return NULL;
  85. CClientFrame *frame = m_Frames;
  86. CClientFrame *lastFrame = frame;
  87. while ( frame != NULL )
  88. {
  89. if ( frame->tick_count >= nTick )
  90. {
  91. if ( frame->tick_count == nTick )
  92. return frame;
  93. if ( bExact )
  94. return NULL;
  95. return lastFrame;
  96. }
  97. lastFrame = frame;
  98. frame = frame->m_pNext;
  99. }
  100. if ( bExact )
  101. return NULL;
  102. return lastFrame;
  103. }
  104. int CClientFrameManager::CountClientFrames( void )
  105. {
  106. #if _DEBUG
  107. int count = 0;
  108. CClientFrame *f = m_Frames;
  109. while ( f )
  110. {
  111. count++;
  112. f = f->m_pNext;
  113. }
  114. Assert( m_nFrames == count );
  115. #endif
  116. return m_nFrames;
  117. }
  118. //-----------------------------------------------------------------------------
  119. // Purpose:
  120. // Input : *cl -
  121. //-----------------------------------------------------------------------------
  122. int CClientFrameManager::AddClientFrame( CClientFrame *frame)
  123. {
  124. Assert( frame->tick_count > 0 );
  125. if ( !m_Frames )
  126. {
  127. // first client frame at all
  128. Assert( m_LastFrame == NULL && m_nFrames == 0 );
  129. m_Frames = frame;
  130. m_LastFrame = frame;
  131. m_nFrames = 1;
  132. return 1;
  133. }
  134. Assert( m_Frames != NULL && m_nFrames > 0 );
  135. Assert( m_LastFrame->m_pNext == NULL );
  136. m_LastFrame->m_pNext = frame;
  137. m_LastFrame = frame;
  138. return ++m_nFrames;
  139. }
  140. void CClientFrameManager::RemoveOldestFrame( void )
  141. {
  142. CClientFrame *frame = m_Frames; // first
  143. if ( !frame )
  144. return; // no frames at all
  145. Assert( m_nFrames > 0 );
  146. m_Frames = frame->m_pNext; // unlink head
  147. // deleting frame will decrease global reference counter
  148. FreeFrame( frame );
  149. if ( --m_nFrames == 0 )
  150. {
  151. Assert( m_LastFrame == frame && m_Frames == NULL );
  152. m_LastFrame = NULL;
  153. }
  154. }
  155. void CClientFrameManager::DeleteClientFrames(int nTick)
  156. {
  157. if ( nTick < 0 )
  158. {
  159. while ( m_nFrames > 0 )
  160. {
  161. RemoveOldestFrame();
  162. }
  163. }
  164. else
  165. {
  166. CClientFrame *frame = m_Frames;
  167. // rebuild m_LastFrame while iterating forward through the list
  168. m_LastFrame = NULL;
  169. while ( frame )
  170. {
  171. if ( frame->tick_count < nTick )
  172. {
  173. // Delete this frame
  174. CClientFrame* next = frame->m_pNext;
  175. if ( m_Frames == frame )
  176. m_Frames = next;
  177. FreeFrame( frame );
  178. if ( --m_nFrames == 0 )
  179. {
  180. Assert( next == NULL );
  181. m_LastFrame = m_Frames = NULL;
  182. break;
  183. }
  184. Assert( m_LastFrame != frame && m_nFrames > 0 );
  185. frame = next;
  186. if ( m_LastFrame )
  187. m_LastFrame->m_pNext = next;
  188. }
  189. else
  190. {
  191. Assert( m_LastFrame == NULL || m_LastFrame->m_pNext == frame );
  192. m_LastFrame = frame;
  193. frame = frame->m_pNext;
  194. }
  195. }
  196. }
  197. }
  198. //-----------------------------------------------------------------------------
  199. // Class factory for frames
  200. //-----------------------------------------------------------------------------
  201. CClientFrame* CClientFrameManager::AllocateFrame()
  202. {
  203. return m_ClientFramePool.Alloc();
  204. }
  205. void CClientFrameManager::FreeFrame( CClientFrame* pFrame )
  206. {
  207. if ( pFrame->IsMemPoolAllocated() )
  208. {
  209. m_ClientFramePool.Free( pFrame );
  210. }
  211. else
  212. {
  213. delete pFrame;
  214. }
  215. }
  216. CClientFrameManager::CClientFrameManager( void )
  217. : m_ClientFramePool( MAX_CLIENT_FRAMES, CUtlMemoryPool::GROW_SLOW ),
  218. m_Frames(NULL),
  219. m_LastFrame(NULL),
  220. m_nFrames(0)
  221. {
  222. }
  223. CClientFrameManager::~CClientFrameManager( void )
  224. {
  225. DeleteClientFrames( -1 );
  226. Assert( m_nFrames == 0 );
  227. }