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.

293 lines
11 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. // $NoKeywords: $
  6. //=============================================================================//
  7. #ifndef PREDICTIONCOPY_H
  8. #define PREDICTIONCOPY_H
  9. #ifdef _WIN32
  10. #pragma once
  11. #endif
  12. #include <memory.h>
  13. #include "datamap.h"
  14. #include "ehandle.h"
  15. #include "tier1/utlstring.h"
  16. #if defined( CLIENT_DLL )
  17. class C_BaseEntity;
  18. typedef CHandle<C_BaseEntity> EHANDLE;
  19. #if defined( _DEBUG )
  20. // #define COPY_CHECK_STRESSTEST
  21. class IGameSystem;
  22. IGameSystem* GetPredictionCopyTester( void );
  23. #endif
  24. #else
  25. class CBaseEntity;
  26. typedef CHandle<CBaseEntity> EHANDLE;
  27. #endif
  28. enum
  29. {
  30. PC_EVERYTHING = 0,
  31. PC_NON_NETWORKED_ONLY,
  32. PC_NETWORKED_ONLY,
  33. };
  34. #define PC_DATA_PACKED true
  35. #define PC_DATA_NORMAL false
  36. typedef void ( *FN_FIELD_COMPARE )( const char *classname, const char *fieldname, const char *fieldtype,
  37. bool networked, bool noterrorchecked, bool differs, bool withintolerance, const char *value );
  38. class CPredictionCopy
  39. {
  40. public:
  41. typedef enum
  42. {
  43. DIFFERS = 0,
  44. IDENTICAL,
  45. WITHINTOLERANCE,
  46. } difftype_t;
  47. CPredictionCopy( int type, void *dest, bool dest_packed, void const *src, bool src_packed,
  48. bool counterrors = false, bool reporterrors = false, bool performcopy = true,
  49. bool describefields = false, FN_FIELD_COMPARE func = NULL );
  50. void CopyShort( difftype_t dt, short *outvalue, const short *invalue, int count );
  51. void CopyInt( difftype_t dt, int *outvalue, const int *invalue, int count ); // Copy an int
  52. void CopyBool( difftype_t dt, bool *outvalue, const bool *invalue, int count ); // Copy a bool
  53. void CopyFloat( difftype_t dt, float *outvalue, const float *invalue, int count ); // Copy a float
  54. void CopyString( difftype_t dt, char *outstring, const char *instring ); // Copy a null-terminated string
  55. void CopyVector( difftype_t dt, Vector& outValue, const Vector &inValue ); // Copy a vector
  56. void CopyVector( difftype_t dt, Vector* outValue, const Vector *inValue, int count ); // Copy a vector array
  57. void CopyQuaternion( difftype_t dt, Quaternion& outValue, const Quaternion &inValue ); // Copy a quaternion
  58. void CopyQuaternion( difftype_t dt, Quaternion* outValue, const Quaternion *inValue, int count ); // Copy a quaternion array
  59. void CopyEHandle( difftype_t dt, EHANDLE *outvalue, EHANDLE const *invalue, int count );
  60. void FORCEINLINE CopyData( difftype_t dt, int size, char *outdata, const char *indata ) // Copy a binary data block
  61. {
  62. if ( !m_bPerformCopy )
  63. return;
  64. if ( dt == IDENTICAL )
  65. return;
  66. memcpy( outdata, indata, size );
  67. }
  68. int TransferData( const char *operation, int entindex, datamap_t *dmap );
  69. private:
  70. void TransferData_R( int chaincount, datamap_t *dmap );
  71. void DetermineWatchField( const char *operation, int entindex, datamap_t *dmap );
  72. void DumpWatchField( typedescription_t *field );
  73. void WatchMsg( PRINTF_FORMAT_STRING const char *fmt, ... );
  74. difftype_t CompareShort( short *outvalue, const short *invalue, int count );
  75. difftype_t CompareInt( int *outvalue, const int *invalue, int count ); // Compare an int
  76. difftype_t CompareBool( bool *outvalue, const bool *invalue, int count ); // Compare a bool
  77. difftype_t CompareFloat( float *outvalue, const float *invalue, int count ); // Compare a float
  78. difftype_t CompareData( int size, char *outdata, const char *indata ); // Compare a binary data block
  79. difftype_t CompareString( char *outstring, const char *instring ); // Compare a null-terminated string
  80. difftype_t CompareVector( Vector& outValue, const Vector &inValue ); // Compare a vector
  81. difftype_t CompareVector( Vector* outValue, const Vector *inValue, int count ); // Compare a vector array
  82. difftype_t CompareQuaternion( Quaternion& outValue, const Quaternion &inValue ); // Compare a Quaternion
  83. difftype_t CompareQuaternion( Quaternion* outValue, const Quaternion *inValue, int count ); // Compare a Quaternion array
  84. difftype_t CompareEHandle( EHANDLE *outvalue, EHANDLE const *invalue, int count );
  85. void DescribeShort( difftype_t dt, short *outvalue, const short *invalue, int count );
  86. void DescribeInt( difftype_t dt, int *outvalue, const int *invalue, int count ); // Compare an int
  87. void DescribeBool( difftype_t dt, bool *outvalue, const bool *invalue, int count ); // Compare a bool
  88. void DescribeFloat( difftype_t dt, float *outvalue, const float *invalue, int count ); // Compare a float
  89. void DescribeData( difftype_t dt, int size, char *outdata, const char *indata ); // Compare a binary data block
  90. void DescribeString( difftype_t dt, char *outstring, const char *instring ); // Compare a null-terminated string
  91. void DescribeVector( difftype_t dt, Vector& outValue, const Vector &inValue ); // Compare a vector
  92. void DescribeVector( difftype_t dt, Vector* outValue, const Vector *inValue, int count ); // Compare a vector array
  93. void DescribeQuaternion( difftype_t dt, Quaternion& outValue, const Quaternion &inValue ); // Compare a Quaternion
  94. void DescribeQuaternion( difftype_t dt, Quaternion* outValue, const Quaternion *inValue, int count ); // Compare a Quaternion array
  95. void DescribeEHandle( difftype_t dt, EHANDLE *outvalue, EHANDLE const *invalue, int count );
  96. void WatchShort( difftype_t dt, short *outvalue, const short *invalue, int count );
  97. void WatchInt( difftype_t dt, int *outvalue, const int *invalue, int count ); // Compare an int
  98. void WatchBool( difftype_t dt, bool *outvalue, const bool *invalue, int count ); // Compare a bool
  99. void WatchFloat( difftype_t dt, float *outvalue, const float *invalue, int count ); // Compare a float
  100. void WatchData( difftype_t dt, int size, char *outdata, const char *indata ); // Compare a binary data block
  101. void WatchString( difftype_t dt, char *outstring, const char *instring ); // Compare a null-terminated string
  102. void WatchVector( difftype_t dt, Vector& outValue, const Vector &inValue ); // Compare a vector
  103. void WatchVector( difftype_t dt, Vector* outValue, const Vector *inValue, int count ); // Compare a vector array
  104. void WatchQuaternion( difftype_t dt, Quaternion& outValue, const Quaternion &inValue ); // Compare a Quaternion
  105. void WatchQuaternion( difftype_t dt, Quaternion* outValue, const Quaternion *inValue, int count ); // Compare a Quaternion array
  106. void WatchEHandle( difftype_t dt, EHANDLE *outvalue, EHANDLE const *invalue, int count );
  107. // Report function
  108. void ReportFieldsDiffer( PRINTF_FORMAT_STRING const char *fmt, ... );
  109. void DescribeFields( difftype_t dt, PRINTF_FORMAT_STRING const char *fmt, ... );
  110. bool CanCheck( void );
  111. void CopyFields( int chaincount, datamap_t *pMap, typedescription_t *pFields, int fieldCount );
  112. private:
  113. int m_nType;
  114. void *m_pDest;
  115. void const *m_pSrc;
  116. int m_nDestOffsetIndex;
  117. int m_nSrcOffsetIndex;
  118. bool m_bErrorCheck;
  119. bool m_bReportErrors;
  120. bool m_bDescribeFields;
  121. typedescription_t *m_pCurrentField;
  122. char const *m_pCurrentClassName;
  123. datamap_t *m_pCurrentMap;
  124. bool m_bShouldReport;
  125. bool m_bShouldDescribe;
  126. int m_nErrorCount;
  127. bool m_bPerformCopy;
  128. FN_FIELD_COMPARE m_FieldCompareFunc;
  129. typedescription_t *m_pWatchField;
  130. char const *m_pOperation;
  131. };
  132. typedef void (*FN_FIELD_DESCRIPTION)( const char *classname, const char *fieldname, const char *fieldtype,
  133. bool networked, const char *value );
  134. //-----------------------------------------------------------------------------
  135. // Purpose: Simply dumps all data fields in object
  136. //-----------------------------------------------------------------------------
  137. class CPredictionDescribeData
  138. {
  139. public:
  140. CPredictionDescribeData( void const *src, bool src_packed, FN_FIELD_DESCRIPTION func = 0 );
  141. void DescribeShort( const short *invalue, int count );
  142. void DescribeInt( const int *invalue, int count );
  143. void DescribeBool( const bool *invalue, int count );
  144. void DescribeFloat( const float *invalue, int count );
  145. void DescribeData( int size, const char *indata );
  146. void DescribeString( const char *instring );
  147. void DescribeVector( const Vector &inValue );
  148. void DescribeVector( const Vector *inValue, int count );
  149. void DescribeQuaternion( const Quaternion &inValue );
  150. void DescribeQuaternion( const Quaternion *inValue, int count );
  151. void DescribeEHandle( EHANDLE const *invalue, int count );
  152. void DumpDescription( datamap_t *pMap );
  153. private:
  154. void DescribeFields_R( int chain_count, datamap_t *pMap, typedescription_t *pFields, int fieldCount );
  155. void const *m_pSrc;
  156. int m_nSrcOffsetIndex;
  157. void Describe( PRINTF_FORMAT_STRING const char *fmt, ... );
  158. typedescription_t *m_pCurrentField;
  159. char const *m_pCurrentClassName;
  160. datamap_t *m_pCurrentMap;
  161. bool m_bShouldReport;
  162. FN_FIELD_DESCRIPTION m_FieldDescFunc;
  163. };
  164. #if defined( CLIENT_DLL )
  165. class CValueChangeTracker
  166. {
  167. public:
  168. CValueChangeTracker();
  169. void Reset();
  170. void StartTrack( char const *pchContext );
  171. void EndTrack();
  172. bool IsActive() const;
  173. void SetupTracking( C_BaseEntity *ent, char const *pchFieldName );
  174. void ClearTracking();
  175. void Spew();
  176. C_BaseEntity *GetEntity();
  177. private:
  178. enum
  179. {
  180. eChangeTrackerBufSize = 128,
  181. };
  182. // Returns field size
  183. void GetValue( char *buf, size_t bufsize );
  184. bool m_bActive : 1;
  185. bool m_bTracking : 1;
  186. EHANDLE m_hEntityToTrack;
  187. CUtlVector< typedescription_t * > m_FieldStack;
  188. CUtlString m_strFieldName;
  189. CUtlString m_strContext;
  190. // First 128 bytes of data is all we will consider
  191. char m_OrigValueBuf[ eChangeTrackerBufSize ];
  192. CUtlVector< CUtlString > m_History;
  193. };
  194. extern CValueChangeTracker *g_pChangeTracker;
  195. class CValueChangeTrackerScope
  196. {
  197. public:
  198. CValueChangeTrackerScope( char const *pchContext )
  199. {
  200. m_bCallEndTrack = true;
  201. g_pChangeTracker->StartTrack( pchContext );
  202. }
  203. // Only calls Start/End if passed in entity matches entity to track
  204. CValueChangeTrackerScope( C_BaseEntity *pEntity, char const *pchContext )
  205. {
  206. m_bCallEndTrack = g_pChangeTracker->GetEntity() == pEntity;
  207. if ( m_bCallEndTrack )
  208. {
  209. g_pChangeTracker->StartTrack( pchContext );
  210. }
  211. }
  212. ~CValueChangeTrackerScope()
  213. {
  214. if ( m_bCallEndTrack )
  215. {
  216. g_pChangeTracker->EndTrack();
  217. }
  218. }
  219. private:
  220. bool m_bCallEndTrack;
  221. };
  222. #if defined( _DEBUG )
  223. #define PREDICTION_TRACKVALUECHANGESCOPE( context ) CValueChangeTrackerScope scope( context );
  224. #define PREDICTION_TRACKVALUECHANGESCOPE_ENTITY( entity, context ) CValueChangeTrackerScope scope( entity, context );
  225. #define PREDICTION_STARTTRACKVALUE( context ) g_pChangeTracker->StartTrack( context );
  226. #define PREDICTION_ENDTRACKVALUE() g_pChangeTracker->EndTrack();
  227. #define PREDICTION_SPEWVALUECHANGES() g_pChangeTracker->Spew();
  228. #else
  229. #define PREDICTION_TRACKVALUECHANGESCOPE( context )
  230. #define PREDICTION_TRACKVALUECHANGESCOPE_ENTITY( entity, context )
  231. #define PREDICTION_STARTTRACKVALUE( context )
  232. #define PREDICTION_ENDTRACKVALUE()
  233. #define PREDICTION_SPEWVALUECHANGES()
  234. #endif
  235. #endif // !CLIENT_DLL
  236. #endif // PREDICTIONCOPY_H