Counter Strike : Global Offensive Source Code
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.

281 lines
5.4 KiB

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