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.
239 lines
4.7 KiB
239 lines
4.7 KiB
//========= Copyright Valve Corporation, All rights reserved. ============// |
|
// |
|
// Purpose: |
|
// |
|
// $NoKeywords: $ |
|
//=============================================================================// |
|
|
|
#if (defined(_WIN32) && (!defined(_X360) ) ) |
|
#include <windows.h> |
|
#endif |
|
#include "tier0/platform.h" |
|
#include "tier0/icommandline.h" |
|
#include "dt_instrumentation.h" |
|
#include "utlvector.h" |
|
#include "utllinkedlist.h" |
|
#include "tier0/fasttimer.h" |
|
#include "utllinkedlist.h" |
|
#include "tier0/dbg.h" |
|
#include "tier1/utlstring.h" |
|
#include "dt_recv_decoder.h" |
|
#include "filesystem.h" |
|
#include "filesystem_engine.h" |
|
#include "cdll_int.h" |
|
#include "client.h" |
|
#include "common.h" |
|
|
|
// memdbgon must be the last include file in a .cpp file!!! |
|
#include "tier0/memdbgon.h" |
|
|
|
bool g_bDTIEnabled = false; |
|
const char *g_pDTIFilename; |
|
|
|
|
|
class CDTIProp |
|
{ |
|
public: |
|
CDTIProp() |
|
{ |
|
m_nDecodes = m_nDataBits = m_nIndexBits = 0; |
|
} |
|
|
|
CUtlString m_Name; |
|
int m_nDecodes; |
|
int m_nDataBits; |
|
int m_nIndexBits; |
|
}; |
|
|
|
|
|
class CDTIRecvTable |
|
{ |
|
public: |
|
CDTIRecvTable() |
|
{ |
|
m_bSawAction = false; |
|
} |
|
|
|
CUtlString m_Name; |
|
CUtlVector<CDTIProp> m_Props; |
|
bool m_bSawAction; |
|
}; |
|
|
|
|
|
CUtlLinkedList<CDTIRecvTable*, int> g_DTIRecvTables; |
|
|
|
|
|
void DTI_Init() |
|
{ |
|
#if ( defined( IS_WINDOWS_PC ) && (! defined( SWDS ) ) ) |
|
extern IVEngineClient *engineClient; |
|
if ( CommandLine()->FindParm( "-dti" ) && !g_bDTIEnabled ) |
|
{ |
|
g_bDTIEnabled = true; |
|
|
|
SYSTEMTIME systemTime; |
|
GetLocalTime( &systemTime ); |
|
|
|
char dtiFileName[MAX_PATH]; |
|
char dtiLevelName[MAX_PATH]; |
|
V_FileBase( engineClient->GetLevelName(), dtiLevelName, ARRAYSIZE( dtiLevelName ) ); |
|
V_snprintf( dtiFileName, ARRAYSIZE( dtiFileName ), "dti_client_%s_%02d%02d%02d-%02d%02d%02d.csv", |
|
dtiLevelName, |
|
systemTime.wYear % 100, systemTime.wMonth, systemTime.wDay, |
|
systemTime.wHour, systemTime.wMinute, systemTime.wSecond ); |
|
g_pDTIFilename = COM_StringCopy( dtiFileName ); |
|
} |
|
#endif |
|
} |
|
|
|
|
|
void DTI_Term() |
|
{ |
|
if ( g_bDTIEnabled ) |
|
{ |
|
DTI_Flush(); |
|
g_DTIRecvTables.PurgeAndDeleteElements(); |
|
delete g_pDTIFilename; |
|
g_pDTIFilename = NULL; |
|
g_bDTIEnabled = false; |
|
} |
|
} |
|
|
|
|
|
void DTI_Flush() |
|
{ |
|
if ( !g_bDTIEnabled ) |
|
return; |
|
|
|
FileHandle_t fp = g_pFileSystem->Open( g_pDTIFilename, "wt" ); |
|
if( fp != FILESYSTEM_INVALID_HANDLE ) |
|
{ |
|
// Write the header. |
|
g_pFileSystem->FPrintf( fp, |
|
"Class" |
|
",Prop" |
|
",Decode Count" |
|
",Total Bits" |
|
",Avg Bits" |
|
",Total Index Bits" |
|
",Avg Index Bits" |
|
",=SUM(D:D)" |
|
"\n" ); |
|
|
|
int row = 2; |
|
|
|
FOR_EACH_LL( g_DTIRecvTables, iTable ) |
|
{ |
|
CDTIRecvTable *pTable = g_DTIRecvTables[iTable]; |
|
|
|
if ( !pTable->m_bSawAction ) |
|
continue; |
|
|
|
for ( int iProp=0; iProp < pTable->m_Props.Count(); iProp++ ) |
|
{ |
|
CDTIProp *pProp = &pTable->m_Props[iProp]; |
|
|
|
if ( pProp->m_nDecodes == 0 ) |
|
continue; |
|
|
|
g_pFileSystem->FPrintf( fp, |
|
// Class/Prop names |
|
"%s" |
|
",%s" |
|
|
|
// Decode count |
|
",%d" |
|
|
|
// Total/Avg bits |
|
",%d" |
|
",%.3f" |
|
|
|
// Total/Avg index bits |
|
",%d" |
|
",%.3f" |
|
",=D%d/H$1" |
|
|
|
"\n", |
|
|
|
// Class/Prop names |
|
pTable->m_Name.String(), |
|
pProp->m_Name.String(), |
|
|
|
// Decode count |
|
pProp->m_nDecodes, |
|
|
|
// Total/Avg bits |
|
pProp->m_nDataBits, |
|
(float)pProp->m_nDataBits / pProp->m_nDecodes, |
|
|
|
// Total/Avg index bits |
|
pProp->m_nIndexBits, |
|
(float)pProp->m_nIndexBits / pProp->m_nDecodes, |
|
row++ |
|
); |
|
} |
|
} |
|
|
|
g_pFileSystem->Close( fp ); |
|
|
|
Msg( "DTI: wrote client stats into %s.\n", g_pDTIFilename ); |
|
} |
|
} |
|
|
|
|
|
void DTI_HookRecvDecoder( CRecvDecoder *pDecoder ) |
|
{ |
|
if ( !g_bDTIEnabled ) |
|
return; |
|
|
|
bool dtiEnabled = CommandLine()->FindParm("-dti" ) > 0; |
|
|
|
CDTIRecvTable *pTable = new CDTIRecvTable; |
|
pTable->m_Name.Set( pDecoder->GetName() ); |
|
|
|
pTable->m_Props.SetSize( pDecoder->GetNumProps() ); |
|
for ( int i=0; i < pTable->m_Props.Count(); i++ ) |
|
{ |
|
const SendProp *pSendProp = pDecoder->GetSendProp( i ); |
|
if ( !dtiEnabled ) |
|
{ |
|
pTable->m_Props[i].m_Name.Set( pSendProp->GetName() ); |
|
} |
|
else |
|
{ |
|
char *parentArrayPropName = const_cast< char * >(const_cast< SendProp * >(pSendProp)->GetParentArrayPropName()); |
|
if ( parentArrayPropName ) |
|
{ |
|
char temp[256]; |
|
V_snprintf( temp, sizeof( temp ), "%s:%s", parentArrayPropName, pSendProp->GetName() ); |
|
pTable->m_Props[i].m_Name.Set( temp ); |
|
} |
|
else |
|
{ |
|
pTable->m_Props[i].m_Name.Set( pSendProp->GetName() ); |
|
} |
|
} |
|
} |
|
|
|
g_DTIRecvTables.AddToTail( pTable ); |
|
|
|
pDecoder->m_pDTITable = pTable; |
|
} |
|
|
|
|
|
void _DTI_HookDeltaBits( CRecvDecoder *pDecoder, int iProp, int nDataBits, int nIndexBits ) |
|
{ |
|
CDTIRecvTable *pTable = pDecoder->m_pDTITable; |
|
if ( !pTable ) |
|
return; |
|
|
|
CDTIProp *pProp = &pTable->m_Props[iProp]; |
|
pProp->m_nDecodes++; |
|
pProp->m_nDataBits += nDataBits; |
|
pProp->m_nIndexBits += nIndexBits; |
|
|
|
pTable->m_bSawAction = true; |
|
} |
|
|
|
|
|
|
|
|