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
293 lines
11 KiB
//========= Copyright Valve Corporation, All rights reserved. ============// |
|
// |
|
// Purpose: |
|
// |
|
// $NoKeywords: $ |
|
//=============================================================================// |
|
|
|
#ifndef PREDICTIONCOPY_H |
|
#define PREDICTIONCOPY_H |
|
#ifdef _WIN32 |
|
#pragma once |
|
#endif |
|
|
|
#include <memory.h> |
|
#include "datamap.h" |
|
#include "ehandle.h" |
|
#include "tier1/utlstring.h" |
|
|
|
#if defined( CLIENT_DLL ) |
|
class C_BaseEntity; |
|
typedef CHandle<C_BaseEntity> EHANDLE; |
|
|
|
#if defined( _DEBUG ) |
|
// #define COPY_CHECK_STRESSTEST |
|
class IGameSystem; |
|
IGameSystem* GetPredictionCopyTester( void ); |
|
#endif |
|
|
|
#else |
|
class CBaseEntity; |
|
typedef CHandle<CBaseEntity> EHANDLE; |
|
#endif |
|
|
|
enum |
|
{ |
|
PC_EVERYTHING = 0, |
|
PC_NON_NETWORKED_ONLY, |
|
PC_NETWORKED_ONLY, |
|
}; |
|
|
|
#define PC_DATA_PACKED true |
|
#define PC_DATA_NORMAL false |
|
|
|
typedef void ( *FN_FIELD_COMPARE )( const char *classname, const char *fieldname, const char *fieldtype, |
|
bool networked, bool noterrorchecked, bool differs, bool withintolerance, const char *value ); |
|
|
|
class CPredictionCopy |
|
{ |
|
public: |
|
typedef enum |
|
{ |
|
DIFFERS = 0, |
|
IDENTICAL, |
|
WITHINTOLERANCE, |
|
} difftype_t; |
|
|
|
CPredictionCopy( int type, void *dest, bool dest_packed, void const *src, bool src_packed, |
|
bool counterrors = false, bool reporterrors = false, bool performcopy = true, |
|
bool describefields = false, FN_FIELD_COMPARE func = NULL ); |
|
|
|
void CopyShort( difftype_t dt, short *outvalue, const short *invalue, int count ); |
|
void CopyInt( difftype_t dt, int *outvalue, const int *invalue, int count ); // Copy an int |
|
void CopyBool( difftype_t dt, bool *outvalue, const bool *invalue, int count ); // Copy a bool |
|
void CopyFloat( difftype_t dt, float *outvalue, const float *invalue, int count ); // Copy a float |
|
void CopyString( difftype_t dt, char *outstring, const char *instring ); // Copy a null-terminated string |
|
void CopyVector( difftype_t dt, Vector& outValue, const Vector &inValue ); // Copy a vector |
|
void CopyVector( difftype_t dt, Vector* outValue, const Vector *inValue, int count ); // Copy a vector array |
|
void CopyQuaternion( difftype_t dt, Quaternion& outValue, const Quaternion &inValue ); // Copy a quaternion |
|
void CopyQuaternion( difftype_t dt, Quaternion* outValue, const Quaternion *inValue, int count ); // Copy a quaternion array |
|
void CopyEHandle( difftype_t dt, EHANDLE *outvalue, EHANDLE const *invalue, int count ); |
|
|
|
void FORCEINLINE CopyData( difftype_t dt, int size, char *outdata, const char *indata ) // Copy a binary data block |
|
{ |
|
if ( !m_bPerformCopy ) |
|
return; |
|
|
|
if ( dt == IDENTICAL ) |
|
return; |
|
|
|
memcpy( outdata, indata, size ); |
|
} |
|
|
|
int TransferData( const char *operation, int entindex, datamap_t *dmap ); |
|
|
|
private: |
|
void TransferData_R( int chaincount, datamap_t *dmap ); |
|
|
|
void DetermineWatchField( const char *operation, int entindex, datamap_t *dmap ); |
|
void DumpWatchField( typedescription_t *field ); |
|
void WatchMsg( PRINTF_FORMAT_STRING const char *fmt, ... ); |
|
|
|
difftype_t CompareShort( short *outvalue, const short *invalue, int count ); |
|
difftype_t CompareInt( int *outvalue, const int *invalue, int count ); // Compare an int |
|
difftype_t CompareBool( bool *outvalue, const bool *invalue, int count ); // Compare a bool |
|
difftype_t CompareFloat( float *outvalue, const float *invalue, int count ); // Compare a float |
|
difftype_t CompareData( int size, char *outdata, const char *indata ); // Compare a binary data block |
|
difftype_t CompareString( char *outstring, const char *instring ); // Compare a null-terminated string |
|
difftype_t CompareVector( Vector& outValue, const Vector &inValue ); // Compare a vector |
|
difftype_t CompareVector( Vector* outValue, const Vector *inValue, int count ); // Compare a vector array |
|
difftype_t CompareQuaternion( Quaternion& outValue, const Quaternion &inValue ); // Compare a Quaternion |
|
difftype_t CompareQuaternion( Quaternion* outValue, const Quaternion *inValue, int count ); // Compare a Quaternion array |
|
difftype_t CompareEHandle( EHANDLE *outvalue, EHANDLE const *invalue, int count ); |
|
|
|
void DescribeShort( difftype_t dt, short *outvalue, const short *invalue, int count ); |
|
void DescribeInt( difftype_t dt, int *outvalue, const int *invalue, int count ); // Compare an int |
|
void DescribeBool( difftype_t dt, bool *outvalue, const bool *invalue, int count ); // Compare a bool |
|
void DescribeFloat( difftype_t dt, float *outvalue, const float *invalue, int count ); // Compare a float |
|
void DescribeData( difftype_t dt, int size, char *outdata, const char *indata ); // Compare a binary data block |
|
void DescribeString( difftype_t dt, char *outstring, const char *instring ); // Compare a null-terminated string |
|
void DescribeVector( difftype_t dt, Vector& outValue, const Vector &inValue ); // Compare a vector |
|
void DescribeVector( difftype_t dt, Vector* outValue, const Vector *inValue, int count ); // Compare a vector array |
|
void DescribeQuaternion( difftype_t dt, Quaternion& outValue, const Quaternion &inValue ); // Compare a Quaternion |
|
void DescribeQuaternion( difftype_t dt, Quaternion* outValue, const Quaternion *inValue, int count ); // Compare a Quaternion array |
|
void DescribeEHandle( difftype_t dt, EHANDLE *outvalue, EHANDLE const *invalue, int count ); |
|
|
|
void WatchShort( difftype_t dt, short *outvalue, const short *invalue, int count ); |
|
void WatchInt( difftype_t dt, int *outvalue, const int *invalue, int count ); // Compare an int |
|
void WatchBool( difftype_t dt, bool *outvalue, const bool *invalue, int count ); // Compare a bool |
|
void WatchFloat( difftype_t dt, float *outvalue, const float *invalue, int count ); // Compare a float |
|
void WatchData( difftype_t dt, int size, char *outdata, const char *indata ); // Compare a binary data block |
|
void WatchString( difftype_t dt, char *outstring, const char *instring ); // Compare a null-terminated string |
|
void WatchVector( difftype_t dt, Vector& outValue, const Vector &inValue ); // Compare a vector |
|
void WatchVector( difftype_t dt, Vector* outValue, const Vector *inValue, int count ); // Compare a vector array |
|
void WatchQuaternion( difftype_t dt, Quaternion& outValue, const Quaternion &inValue ); // Compare a Quaternion |
|
void WatchQuaternion( difftype_t dt, Quaternion* outValue, const Quaternion *inValue, int count ); // Compare a Quaternion array |
|
void WatchEHandle( difftype_t dt, EHANDLE *outvalue, EHANDLE const *invalue, int count ); |
|
|
|
// Report function |
|
void ReportFieldsDiffer( PRINTF_FORMAT_STRING const char *fmt, ... ); |
|
void DescribeFields( difftype_t dt, PRINTF_FORMAT_STRING const char *fmt, ... ); |
|
|
|
bool CanCheck( void ); |
|
|
|
void CopyFields( int chaincount, datamap_t *pMap, typedescription_t *pFields, int fieldCount ); |
|
|
|
private: |
|
|
|
int m_nType; |
|
void *m_pDest; |
|
void const *m_pSrc; |
|
int m_nDestOffsetIndex; |
|
int m_nSrcOffsetIndex; |
|
|
|
|
|
bool m_bErrorCheck; |
|
bool m_bReportErrors; |
|
bool m_bDescribeFields; |
|
typedescription_t *m_pCurrentField; |
|
char const *m_pCurrentClassName; |
|
datamap_t *m_pCurrentMap; |
|
bool m_bShouldReport; |
|
bool m_bShouldDescribe; |
|
int m_nErrorCount; |
|
bool m_bPerformCopy; |
|
|
|
FN_FIELD_COMPARE m_FieldCompareFunc; |
|
|
|
typedescription_t *m_pWatchField; |
|
char const *m_pOperation; |
|
}; |
|
|
|
typedef void (*FN_FIELD_DESCRIPTION)( const char *classname, const char *fieldname, const char *fieldtype, |
|
bool networked, const char *value ); |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Simply dumps all data fields in object |
|
//----------------------------------------------------------------------------- |
|
class CPredictionDescribeData |
|
{ |
|
public: |
|
CPredictionDescribeData( void const *src, bool src_packed, FN_FIELD_DESCRIPTION func = 0 ); |
|
|
|
void DescribeShort( const short *invalue, int count ); |
|
void DescribeInt( const int *invalue, int count ); |
|
void DescribeBool( const bool *invalue, int count ); |
|
void DescribeFloat( const float *invalue, int count ); |
|
void DescribeData( int size, const char *indata ); |
|
void DescribeString( const char *instring ); |
|
void DescribeVector( const Vector &inValue ); |
|
void DescribeVector( const Vector *inValue, int count ); |
|
void DescribeQuaternion( const Quaternion &inValue ); |
|
void DescribeQuaternion( const Quaternion *inValue, int count ); |
|
void DescribeEHandle( EHANDLE const *invalue, int count ); |
|
|
|
void DumpDescription( datamap_t *pMap ); |
|
|
|
private: |
|
void DescribeFields_R( int chain_count, datamap_t *pMap, typedescription_t *pFields, int fieldCount ); |
|
|
|
void const *m_pSrc; |
|
int m_nSrcOffsetIndex; |
|
|
|
void Describe( PRINTF_FORMAT_STRING const char *fmt, ... ); |
|
|
|
typedescription_t *m_pCurrentField; |
|
char const *m_pCurrentClassName; |
|
datamap_t *m_pCurrentMap; |
|
|
|
bool m_bShouldReport; |
|
|
|
FN_FIELD_DESCRIPTION m_FieldDescFunc; |
|
}; |
|
|
|
#if defined( CLIENT_DLL ) |
|
class CValueChangeTracker |
|
{ |
|
public: |
|
CValueChangeTracker(); |
|
|
|
void Reset(); |
|
|
|
void StartTrack( char const *pchContext ); |
|
void EndTrack(); |
|
|
|
bool IsActive() const; |
|
|
|
void SetupTracking( C_BaseEntity *ent, char const *pchFieldName ); |
|
void ClearTracking(); |
|
|
|
void Spew(); |
|
|
|
C_BaseEntity *GetEntity(); |
|
|
|
private: |
|
|
|
enum |
|
{ |
|
eChangeTrackerBufSize = 128, |
|
}; |
|
|
|
// Returns field size |
|
void GetValue( char *buf, size_t bufsize ); |
|
|
|
bool m_bActive : 1; |
|
bool m_bTracking : 1; |
|
EHANDLE m_hEntityToTrack; |
|
CUtlVector< typedescription_t * > m_FieldStack; |
|
CUtlString m_strFieldName; |
|
CUtlString m_strContext; |
|
// First 128 bytes of data is all we will consider |
|
char m_OrigValueBuf[ eChangeTrackerBufSize ]; |
|
CUtlVector< CUtlString > m_History; |
|
}; |
|
|
|
extern CValueChangeTracker *g_pChangeTracker; |
|
|
|
class CValueChangeTrackerScope |
|
{ |
|
public: |
|
CValueChangeTrackerScope( char const *pchContext ) |
|
{ |
|
m_bCallEndTrack = true; |
|
g_pChangeTracker->StartTrack( pchContext ); |
|
} |
|
|
|
// Only calls Start/End if passed in entity matches entity to track |
|
CValueChangeTrackerScope( C_BaseEntity *pEntity, char const *pchContext ) |
|
{ |
|
m_bCallEndTrack = g_pChangeTracker->GetEntity() == pEntity; |
|
if ( m_bCallEndTrack ) |
|
{ |
|
g_pChangeTracker->StartTrack( pchContext ); |
|
} |
|
} |
|
|
|
~CValueChangeTrackerScope() |
|
{ |
|
if ( m_bCallEndTrack ) |
|
{ |
|
g_pChangeTracker->EndTrack(); |
|
} |
|
} |
|
private: |
|
|
|
bool m_bCallEndTrack; |
|
}; |
|
|
|
#if defined( _DEBUG ) |
|
#define PREDICTION_TRACKVALUECHANGESCOPE( context ) CValueChangeTrackerScope scope( context ); |
|
#define PREDICTION_TRACKVALUECHANGESCOPE_ENTITY( entity, context ) CValueChangeTrackerScope scope( entity, context ); |
|
#define PREDICTION_STARTTRACKVALUE( context ) g_pChangeTracker->StartTrack( context ); |
|
#define PREDICTION_ENDTRACKVALUE() g_pChangeTracker->EndTrack(); |
|
#define PREDICTION_SPEWVALUECHANGES() g_pChangeTracker->Spew(); |
|
#else |
|
#define PREDICTION_TRACKVALUECHANGESCOPE( context ) |
|
#define PREDICTION_TRACKVALUECHANGESCOPE_ENTITY( entity, context ) |
|
#define PREDICTION_STARTTRACKVALUE( context ) |
|
#define PREDICTION_ENDTRACKVALUE() |
|
#define PREDICTION_SPEWVALUECHANGES() |
|
#endif |
|
|
|
#endif // !CLIENT_DLL |
|
#endif // PREDICTIONCOPY_H
|
|
|