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

//========= 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