256 lines
6.1 KiB
C++
256 lines
6.1 KiB
C++
//========= Copyright <20> 1996-2008, Valve Corporation, All rights reserved. ============//
|
||
//
|
||
// Purpose:
|
||
//
|
||
// $NoKeywords: $
|
||
//
|
||
//=============================================================================//
|
||
#include "cbase.h"
|
||
|
||
#if !defined( NO_ENTITY_PREDICTION )
|
||
|
||
#include "igamesystem.h"
|
||
#ifndef _PS3
|
||
#ifdef WIN32
|
||
#include <typeinfo.h>
|
||
#else
|
||
#include <typeinfo>
|
||
#endif
|
||
#endif
|
||
#include "cdll_int.h"
|
||
#endif
|
||
#ifndef _PS3
|
||
#include <memory.h>
|
||
#endif
|
||
#include <stdarg.h>
|
||
#include "tier0/dbg.h"
|
||
#include "tier1/strtools.h"
|
||
#include "predictioncopy.h"
|
||
#include "engine/ivmodelinfo.h"
|
||
#include "tier1/fmtstr.h"
|
||
#include "utlvector.h"
|
||
|
||
// memdbgon must be the last include file in a .cpp file!!!
|
||
#include "tier0/memdbgon.h"
|
||
|
||
#if defined( COPY_CHECK_STRESSTEST )
|
||
|
||
class CPredictionCopyTester : public CBaseGameSystem
|
||
{
|
||
public:
|
||
|
||
virtual char const *Name() { return "CPredictionCopyTester"; }
|
||
// Init, shutdown
|
||
virtual bool Init()
|
||
{
|
||
RunTests();
|
||
Remove( this );
|
||
return true;
|
||
}
|
||
|
||
virtual void Shutdown() {}
|
||
|
||
// Level init, shutdown
|
||
virtual void LevelInit() {}
|
||
// The level is shutdown in two parts
|
||
virtual void LevelShutdownPreEntity() {}
|
||
// Entities are deleted / released here...
|
||
virtual void LevelShutdownPostEntity() {}
|
||
// end of level shutdown
|
||
|
||
// Called before rendering
|
||
virtual void PreRender ( ) {}
|
||
|
||
// Called after rendering
|
||
virtual void PostRender() {}
|
||
|
||
// Gets called each frame
|
||
virtual void Update( float frametime ) {}
|
||
|
||
private:
|
||
|
||
void RunTests( void );
|
||
};
|
||
|
||
IGameSystem* GetPredictionCopyTester( void )
|
||
{
|
||
static CPredictionCopyTester s_PredictionCopyTesterSystem;
|
||
return &s_PredictionCopyTesterSystem;
|
||
}
|
||
|
||
class CCopyTesterData
|
||
{
|
||
public:
|
||
|
||
CCopyTesterData()
|
||
{
|
||
m_CharValue = 'a';
|
||
m_ShortValue = (short)100;
|
||
m_IntValue = (int)100;
|
||
m_FloatValue = 1.0f;
|
||
Q_strncpy( m_szValue, "primarydata", sizeof( m_szValue ) );
|
||
m_Vector = Vector( 100, 100, 100 );
|
||
AngleQuaternion( QAngle( 0, 45, 0 ), m_Quaternion );
|
||
m_Bool = false;
|
||
m_Clr.r = m_Clr.g = m_Clr.b = m_Clr.a = 255;
|
||
|
||
m_Ptr = (void *)0xfedcba98;
|
||
// m_hEHandle = NULL;
|
||
}
|
||
|
||
void MakeDifferent( void )
|
||
{
|
||
m_CharValue = 'd';
|
||
m_ShortValue = (short)400;
|
||
m_IntValue = (int)400;
|
||
m_FloatValue = 4.0f;
|
||
Q_strncpy( m_szValue, "secondarydata", sizeof( m_szValue ) );
|
||
m_Vector = Vector( 400, 400, 400 );
|
||
AngleQuaternion( QAngle( 60, 0, 0 ), m_Quaternion );
|
||
m_Bool = true;
|
||
m_Clr.r = m_Clr.g = m_Clr.b = m_Clr.a = 1;
|
||
m_Ptr = (void *)0x00000001;
|
||
// m_hEHandle = (C_BaseEntity *)0x00000001;
|
||
}
|
||
|
||
DECLARE_PREDICTABLE();
|
||
|
||
int m_IntValue;
|
||
float m_FloatValue;
|
||
Vector m_Vector;
|
||
char m_CharValue;
|
||
Quaternion m_Quaternion;
|
||
color32 m_Clr;
|
||
bool m_Bool;
|
||
void *m_Ptr;
|
||
short m_ShortValue;
|
||
char m_szValue[ 128 ];
|
||
|
||
// EHANDLE m_hEHandle;
|
||
|
||
};
|
||
|
||
BEGIN_PREDICTION_DATA_NO_BASE( CCopyTesterData )
|
||
|
||
DEFINE_FIELD( m_CharValue, FIELD_CHARACTER ),
|
||
DEFINE_FIELD( m_ShortValue, FIELD_SHORT ),
|
||
DEFINE_FIELD( m_IntValue, FIELD_INTEGER ),
|
||
DEFINE_FIELD( m_FloatValue, FIELD_FLOAT ),
|
||
DEFINE_FIELD( m_szValue, FIELD_STRING ),
|
||
DEFINE_FIELD( m_Vector, FIELD_VECTOR ),
|
||
DEFINE_FIELD( m_Quaternion, FIELD_QUATERNION ),
|
||
DEFINE_FIELD( m_Bool, FIELD_BOOLEAN ),
|
||
DEFINE_FIELD( m_Clr, FIELD_COLOR32 ),
|
||
// DEFINE_FIELD( m_hEHandle, FIELD_EHANDLE ),
|
||
|
||
END_PREDICTION_DATA()
|
||
|
||
class CCopyTesterData2 : public C_BaseEntity
|
||
{
|
||
DECLARE_CLASS( CCopyTesterData2, C_BaseEntity );
|
||
|
||
public:
|
||
CCopyTesterData2()
|
||
{
|
||
m_CharValueA = 'b';
|
||
m_ShortValueA = (short)200;
|
||
m_IntValueA = (int)200;
|
||
m_FloatValueA = 2.0f;
|
||
}
|
||
|
||
void MakeDifferent( void )
|
||
{
|
||
m_CharValueA = 'e';
|
||
m_ShortValueA = (short)500;
|
||
m_IntValueA = (int)500;
|
||
m_FloatValueA = 5.0f;
|
||
m_FooData.MakeDifferent();
|
||
}
|
||
|
||
DECLARE_PREDICTABLE();
|
||
|
||
char m_CharValueA;
|
||
CCopyTesterData m_FooData;
|
||
int m_IntValueA;
|
||
short m_ShortValueA;
|
||
float m_FloatValueA;
|
||
|
||
};
|
||
|
||
BEGIN_PREDICTION_DATA_NO_BASE( CCopyTesterData2 )
|
||
|
||
DEFINE_FIELD( m_CharValueA, FIELD_CHARACTER ),
|
||
DEFINE_FIELD( m_ShortValueA, FIELD_SHORT ),
|
||
DEFINE_PRED_TYPEDESCRIPTION( m_FooData, CCopyTesterData ),
|
||
DEFINE_FIELD( m_IntValueA, FIELD_INTEGER ),
|
||
DEFINE_FIELD( m_FloatValueA, FIELD_FLOAT ),
|
||
|
||
END_PREDICTION_DATA()
|
||
|
||
void CPredictionCopyTester::RunTests( void )
|
||
{
|
||
CCopyTesterData2 *foo1, *foo2, *foo3;
|
||
|
||
foo1 = new CCopyTesterData2;
|
||
foo2 = new CCopyTesterData2;
|
||
foo3 = new CCopyTesterData2;
|
||
|
||
foo2->MakeDifferent();
|
||
|
||
CPredictionCopy::PrepareDataMap( foo1->GetPredDescMap() );
|
||
CPredictionCopy::PrepareDataMap( foo2->GetPredDescMap() );
|
||
CPredictionCopy::PrepareDataMap( foo2->GetPredDescMap() );
|
||
|
||
// foo1 == foo3
|
||
// foo1 != foo2
|
||
{
|
||
Msg( "Comparing and copying == objects, should have zero diffcount\n" );
|
||
|
||
// Compare foo1 and foo3, should be equal
|
||
CPredictionCopy tester( PC_NON_NETWORKED_ONLY, foo1, false, foo3, false, CPredictionCopy::TRANSFERDATA_ERRORCHECK_SPEW );
|
||
int diff_count = 0;
|
||
diff_count = tester.TransferData( "test1", -1, foo3->GetPredDescMap() );
|
||
|
||
Msg( "diff_count == %i\n", diff_count );
|
||
Assert( !diff_count );
|
||
}
|
||
|
||
{
|
||
Msg( "Simple compare of != objects, should spew and have non-zero diffcount\n" );
|
||
|
||
// Compare foo1 and foo2, should differ
|
||
CPredictionCopy tester( PC_NON_NETWORKED_ONLY, foo1, false, foo2, false, CPredictionCopy::TRANSFERDATA_ERRORCHECK_SPEW );
|
||
int diff_count = 0;
|
||
diff_count = tester.TransferData( "test2", -1, foo2->GetPredDescMap() );
|
||
|
||
Msg( "diff_count == %i (should be 13)\n", diff_count );
|
||
Assert( diff_count == 13 );
|
||
}
|
||
|
||
{
|
||
Msg( "Comparing and copying same objects, should spew and have non-zero diffcount\n" );
|
||
|
||
// Compare foo1 and foo2 while overriting foo2, should have differences but leave objects ==
|
||
CPredictionCopy tester( PC_NON_NETWORKED_ONLY, foo1, false, foo2, false, CPredictionCopy::TRANSFERDATA_COPYONLY );
|
||
tester.TransferData( "test2", -1, foo1->GetPredDescMap() );
|
||
}
|
||
|
||
{
|
||
Msg( "Comparing and copying objects which were just made to coincide, should have zero diffcount\n" );
|
||
|
||
// Make sure foo1 is now == foo2
|
||
CPredictionCopy tester( PC_NON_NETWORKED_ONLY, foo1, false, foo2, false, CPredictionCopy::TRANSFERDATA_ERRORCHECK_SPEW );
|
||
int diff_count = 0;
|
||
diff_count = tester.TransferData( "test4", -1, foo2->GetPredDescMap() );
|
||
|
||
Msg( "diff_count == %i\n", diff_count );
|
||
Assert( !diff_count );
|
||
}
|
||
|
||
delete foo3;
|
||
delete foo2;
|
||
delete foo1;
|
||
|
||
}
|
||
|
||
#endif // COPY_CHECK_STRESSTEST
|