added VS2019 support

debug build requires a little bit of work
This commit is contained in:
EnderZip
2021-09-24 14:52:32 +07:00
parent d248074290
commit 07f0467707
269 changed files with 150556 additions and 30263 deletions

View File

@@ -1 +1,2 @@
devtools\bin\vpc.exe /episodic +game +shaders /mksln games.sln
devtools\bin\vpc.exe /2019 /episodic +game +coolsource +shaders /mksln games.sln
pause

File diff suppressed because it is too large Load Diff

23
external/crypto++-5.6.3/adhoc.cpp vendored Normal file
View File

@@ -0,0 +1,23 @@
#include "config.h"
#include <iosfwd>
#if CRYPTOPP_MSC_VERSION
# pragma warning(disable: 4100 4189 4996)
#endif
#if CRYPTOPP_GCC_DIAGNOSTIC_AVAILABLE
# pragma GCC diagnostic ignored "-Wunused-variable"
#endif
USING_NAMESPACE(CryptoPP)
USING_NAMESPACE(std)
extern int (*AdhocTest)(int argc, char *argv[]);
int MyAdhocTest(int argc, char *argv[])
{
CRYPTOPP_UNUSED(argc), CRYPTOPP_UNUSED(argv);
return 0;
}
static int s_i = (AdhocTest = &MyAdhocTest, 0);

View File

@@ -0,0 +1,2 @@

17
external/crypto++-5.61/adhoc.cpp vendored Normal file
View File

@@ -0,0 +1,17 @@
#include "filters.h"
#include "files.h"
#include "base64.h"
#include "hex.h"
#include <iostream>
USING_NAMESPACE(CryptoPP)
USING_NAMESPACE(std)
extern int (*AdhocTest)(int argc, char *argv[]);
int MyAdhocTest(int argc, char *argv[])
{
return 0;
}
static int s_i = (AdhocTest = &MyAdhocTest, 0);

View File

@@ -0,0 +1,2 @@

28
external/vpc/devtools/base.xcconfig vendored Normal file
View File

@@ -0,0 +1,28 @@
ALWAYS_SEARCH_USER_PATHS = YES
HEADER_SEARCH_PATHS = $(HEADER_SEARCH_PATHS) $(SDKROOT)/usr/include/malloc
ARCHS = i386
ONLY_ACTIVE_ARCH = NO
COPY_PHASE_STRIP = NO
DEBUG_INFORMATION_FORMAT = dwarf-with-dsym
DEAD_CODE_STRIPPING = YES
PRESERVE_DEAD_CODE_INITS_AND_TERMS = YES
GCC_C_LANGUAGE_STANDARD = gnu99
GCC_ENABLE_OBJC_EXCEPTIONS = YES
GCC_PREPROCESSOR_DEFINITIONS = _DLL_EXT=.dylib
GCC_SYMBOLS_PRIVATE_EXTERN = YES
GCC_WARN_ABOUT_INVALID_OFFSETOF_MACRO = NO
// CLANG - and use the ccache wrapper
GCC_VERSION = com.apple.compilers.llvm.clang.1_0
CC = $(SOURCE_ROOT)/devtools/bin/osx32/xcode_ccache_wrapper
LDPLUSPLUS = $(DT_TOOLCHAIN_DIR)/usr/bin/clang++
WARNING_CFLAGS = -Wno-deprecated-writable-strings
CLANG_WARN_CXX0X_EXTENSIONS = NO
// this combination of sdk and deploy target allows building on 10.7 (lion) targeting 10.5
SDKROOT = macosx10.6
MACOSX_DEPLOYMENT_TARGET=10.5

0
external/vpc/devtools/bin/.empty vendored Normal file
View File

46
external/vpc/devtools/bin/vpc vendored Normal file
View File

@@ -0,0 +1,46 @@
#!/bin/bash
OS=`uname`
SCRIPTPATH=`dirname $0`
FORCEARG=""
case $OS in
"Darwin")
BINNAME=vpc_osx
;;
"Linux")
BINNAME=vpc_linux
;;
*)
echo "Couldn't find appropriate VPC binary, fix the script."
exit -1
;;
esac
CWD=`pwd`
cd $SCRIPTPATH/../../external/vpc/utils/vpc
# ask make if we need to do any work, returns 0 if we don't,
# non zero if we do.
make -q
RC=$?
if [ $RC -eq 1 ]; then
FORCEARG="/f"
elif [ $RC -eq 2 ]; then
FORCEARG="/f"
make clean
fi
make -j4
if [ $? -ne 0 ]; then
exit -1
fi
cd $CWD
if [ $OS == "Darwin" ]; then
$SCRIPTPATH/$BINNAME $FORCEARG $@
elif [ $OS == "Linux" ]; then
$SCRIPTPATH/$BINNAME $FORCEARG $@
else
echo "Couldn't find appropriate VPC binary, fix the script."
exit -1
fi

2
external/vpc/devtools/debug.xcconfig vendored Normal file
View File

@@ -0,0 +1,2 @@
#include "base.xcconfig"
GCC_OPTIMIZATION_LEVEL = 0

View File

@@ -0,0 +1 @@
#include "base.xcconfig"

294
external/vpc/interfaces/interfaces.cpp vendored Normal file
View File

@@ -0,0 +1,294 @@
//===== Copyright <20> 2005-2005, Valve Corporation, All rights reserved. ======//
//
// Purpose: A higher level link library for general use in the game and tools.
//
//===========================================================================//
#include "tier0/platform.h"
#include "tier0/dbg.h"
#include "interfaces/interfaces.h"
//-----------------------------------------------------------------------------
// Tier 1 libraries
//-----------------------------------------------------------------------------
ICvar *cvar = 0;
ICvar *g_pCVar = 0;
IProcessUtils *g_pProcessUtils = 0;
static bool s_bConnected = false;
IPhysics2 *g_pPhysics2 = 0;
IPhysics2ActorManager *g_pPhysics2ActorManager = 0;
IPhysics2ResourceManager *g_pPhysics2ResourceManager = 0;
IEventSystem *g_pEventSystem = 0;
ILocalize *g_pLocalize = 0;
// for utlsortvector.h
#ifndef _WIN32
void *g_pUtlSortVectorQSortContext = NULL;
#endif
//-----------------------------------------------------------------------------
// Tier 2 libraries
//-----------------------------------------------------------------------------
IResourceSystem *g_pResourceSystem = 0;
IRenderDeviceMgr *g_pRenderDeviceMgr = 0;
IFileSystem *g_pFullFileSystem = 0;
IAsyncFileSystem *g_pAsyncFileSystem = 0;
IMaterialSystem *materials = 0;
IMaterialSystem *g_pMaterialSystem = 0;
IMaterialSystem2 *g_pMaterialSystem2 = 0;
IInputSystem *g_pInputSystem = 0;
IInputStackSystem *g_pInputStackSystem = 0;
INetworkSystem *g_pNetworkSystem = 0;
ISoundSystem *g_pSoundSystem = 0;
IMaterialSystemHardwareConfig *g_pMaterialSystemHardwareConfig = 0;
IDebugTextureInfo *g_pMaterialSystemDebugTextureInfo = 0;
IVBAllocTracker *g_VBAllocTracker = 0;
IColorCorrectionSystem *colorcorrection = 0;
IP4 *p4 = 0;
IMdlLib *mdllib = 0;
IQueuedLoader *g_pQueuedLoader = 0;
IResourceAccessControl *g_pResourceAccessControl = 0;
IPrecacheSystem *g_pPrecacheSystem = 0;
ISceneSystem *g_pSceneSystem = 0;
#if defined( PLATFORM_X360 )
IXboxInstaller *g_pXboxInstaller = 0;
#endif
IMatchFramework *g_pMatchFramework = 0;
IGameUISystemMgr *g_pGameUISystemMgr = 0;
//-----------------------------------------------------------------------------
// Not exactly a global, but we're going to keep track of these here anyways
//-----------------------------------------------------------------------------
IRenderDevice *g_pRenderDevice = 0;
IRenderHardwareConfig *g_pRenderHardwareConfig = 0;
//-----------------------------------------------------------------------------
// Tier3 libraries
//-----------------------------------------------------------------------------
IMeshSystem *g_pMeshSystem = 0;
IStudioRender *g_pStudioRender = 0;
IStudioRender *studiorender = 0;
IMatSystemSurface *g_pMatSystemSurface = 0;
vgui::IInput *g_pVGuiInput = 0;
vgui::ISurface *g_pVGuiSurface = 0;
vgui::IPanel *g_pVGuiPanel = 0;
vgui::IVGui *g_pVGui = 0;
vgui::IVGUILocalize *g_pVGuiLocalize = 0;
vgui::ISchemeManager *g_pVGuiSchemeManager = 0;
vgui::ISystem *g_pVGuiSystem = 0;
IDataCache *g_pDataCache = 0;
IMDLCache *g_pMDLCache = 0;
IMDLCache *mdlcache = 0;
IAvi *g_pAVI = 0;
IBik *g_pBIK = 0;
IDmeMakefileUtils *g_pDmeMakefileUtils = 0;
IPhysicsCollision *g_pPhysicsCollision = 0;
ISoundEmitterSystemBase *g_pSoundEmitterSystem = 0;
IWorldRendererMgr *g_pWorldRendererMgr = 0;
IVGuiRenderSurface *g_pVGuiRenderSurface = 0;
//-----------------------------------------------------------------------------
// Mapping of interface string to globals
//-----------------------------------------------------------------------------
struct InterfaceGlobals_t
{
const char *m_pInterfaceName;
void *m_ppGlobal;
};
static InterfaceGlobals_t g_pInterfaceGlobals[] =
{
{ CVAR_INTERFACE_VERSION, &cvar },
{ CVAR_INTERFACE_VERSION, &g_pCVar },
{ EVENTSYSTEM_INTERFACE_VERSION, &g_pEventSystem },
{ PROCESS_UTILS_INTERFACE_VERSION, &g_pProcessUtils },
{ VPHYSICS2_INTERFACE_VERSION, &g_pPhysics2 },
{ VPHYSICS2_ACTOR_MGR_INTERFACE_VERSION, &g_pPhysics2ActorManager },
{ VPHYSICS2_RESOURCE_MGR_INTERFACE_VERSION, &g_pPhysics2ResourceManager },
{ FILESYSTEM_INTERFACE_VERSION, &g_pFullFileSystem },
{ ASYNCFILESYSTEM_INTERFACE_VERSION, &g_pAsyncFileSystem },
{ RESOURCESYSTEM_INTERFACE_VERSION, &g_pResourceSystem },
{ MATERIAL_SYSTEM_INTERFACE_VERSION, &g_pMaterialSystem },
{ MATERIAL_SYSTEM_INTERFACE_VERSION, &materials },
{ MATERIAL_SYSTEM2_INTERFACE_VERSION, &g_pMaterialSystem2 },
{ INPUTSYSTEM_INTERFACE_VERSION, &g_pInputSystem },
{ INPUTSTACKSYSTEM_INTERFACE_VERSION, &g_pInputStackSystem },
{ NETWORKSYSTEM_INTERFACE_VERSION, &g_pNetworkSystem },
{ RENDER_DEVICE_MGR_INTERFACE_VERSION, &g_pRenderDeviceMgr },
{ MATERIALSYSTEM_HARDWARECONFIG_INTERFACE_VERSION, &g_pMaterialSystemHardwareConfig },
{ SOUNDSYSTEM_INTERFACE_VERSION, &g_pSoundSystem },
{ DEBUG_TEXTURE_INFO_VERSION, &g_pMaterialSystemDebugTextureInfo },
{ VB_ALLOC_TRACKER_INTERFACE_VERSION, &g_VBAllocTracker },
{ COLORCORRECTION_INTERFACE_VERSION, &colorcorrection },
{ P4_INTERFACE_VERSION, &p4 },
{ MDLLIB_INTERFACE_VERSION, &mdllib },
{ QUEUEDLOADER_INTERFACE_VERSION, &g_pQueuedLoader },
{ RESOURCE_ACCESS_CONTROL_INTERFACE_VERSION, &g_pResourceAccessControl },
{ PRECACHE_SYSTEM_INTERFACE_VERSION, &g_pPrecacheSystem },
{ STUDIO_RENDER_INTERFACE_VERSION, &g_pStudioRender },
{ STUDIO_RENDER_INTERFACE_VERSION, &studiorender },
{ VGUI_IVGUI_INTERFACE_VERSION, &g_pVGui },
{ VGUI_INPUT_INTERFACE_VERSION, &g_pVGuiInput },
{ VGUI_PANEL_INTERFACE_VERSION, &g_pVGuiPanel },
{ VGUI_SURFACE_INTERFACE_VERSION, &g_pVGuiSurface },
{ VGUI_SCHEME_INTERFACE_VERSION, &g_pVGuiSchemeManager },
{ VGUI_SYSTEM_INTERFACE_VERSION, &g_pVGuiSystem },
{ LOCALIZE_INTERFACE_VERSION, &g_pLocalize },
{ LOCALIZE_INTERFACE_VERSION, &g_pVGuiLocalize },
{ MAT_SYSTEM_SURFACE_INTERFACE_VERSION, &g_pMatSystemSurface },
{ DATACACHE_INTERFACE_VERSION, &g_pDataCache },
{ MDLCACHE_INTERFACE_VERSION, &g_pMDLCache },
{ MDLCACHE_INTERFACE_VERSION, &mdlcache },
{ AVI_INTERFACE_VERSION, &g_pAVI },
{ BIK_INTERFACE_VERSION, &g_pBIK },
{ DMEMAKEFILE_UTILS_INTERFACE_VERSION, &g_pDmeMakefileUtils },
{ VPHYSICS_COLLISION_INTERFACE_VERSION, &g_pPhysicsCollision },
{ SOUNDEMITTERSYSTEM_INTERFACE_VERSION, &g_pSoundEmitterSystem },
{ MESHSYSTEM_INTERFACE_VERSION, &g_pMeshSystem },
{ RENDER_DEVICE_INTERFACE_VERSION, &g_pRenderDevice },
{ RENDER_HARDWARECONFIG_INTERFACE_VERSION, &g_pRenderHardwareConfig },
{ SCENESYSTEM_INTERFACE_VERSION, &g_pSceneSystem },
{ WORLD_RENDERER_MGR_INTERFACE_VERSION, &g_pWorldRendererMgr },
{ RENDER_SYSTEM_SURFACE_INTERFACE_VERSION, &g_pVGuiRenderSurface },
#if defined( _X360 )
{ XBOXINSTALLER_INTERFACE_VERSION, &g_pXboxInstaller },
#endif
{ MATCHFRAMEWORK_INTERFACE_VERSION, &g_pMatchFramework },
{ GAMEUISYSTEMMGR_INTERFACE_VERSION, &g_pGameUISystemMgr },
};
//-----------------------------------------------------------------------------
// The # of times this DLL has been connected
//-----------------------------------------------------------------------------
static int s_nConnectionCount = 0;
//-----------------------------------------------------------------------------
// At each level of connection, we're going to keep track of which interfaces
// we filled in. When we disconnect, we'll clear those interface pointers out.
//-----------------------------------------------------------------------------
struct ConnectionRegistration_t
{
void *m_ppGlobalStorage;
int m_nConnectionPhase;
};
static int s_nRegistrationCount = 0;
static ConnectionRegistration_t s_pConnectionRegistration[ ARRAYSIZE(g_pInterfaceGlobals) + 1 ];
void RegisterInterface( CreateInterfaceFn factory, const char *pInterfaceName, void **ppGlobal )
{
if ( !(*ppGlobal) )
{
*ppGlobal = factory( pInterfaceName, NULL );
if ( *ppGlobal )
{
Assert( s_nRegistrationCount < ARRAYSIZE(s_pConnectionRegistration) );
ConnectionRegistration_t &reg = s_pConnectionRegistration[s_nRegistrationCount++];
reg.m_ppGlobalStorage = ppGlobal;
reg.m_nConnectionPhase = s_nConnectionCount;
}
}
}
void ReconnectInterface( CreateInterfaceFn factory, const char *pInterfaceName, void **ppGlobal )
{
*ppGlobal = factory( pInterfaceName, NULL );
bool bFound = false;
Assert( s_nRegistrationCount < ARRAYSIZE(s_pConnectionRegistration) );
for ( int i = 0; i < s_nRegistrationCount; ++i )
{
ConnectionRegistration_t &reg = s_pConnectionRegistration[i];
if ( reg.m_ppGlobalStorage != ppGlobal )
continue;
reg.m_ppGlobalStorage = ppGlobal;
bFound = true;
}
if ( !bFound && *ppGlobal )
{
Assert( s_nRegistrationCount < ARRAYSIZE(s_pConnectionRegistration) );
ConnectionRegistration_t &reg = s_pConnectionRegistration[s_nRegistrationCount++];
reg.m_ppGlobalStorage = ppGlobal;
reg.m_nConnectionPhase = s_nConnectionCount;
}
}
//-----------------------------------------------------------------------------
// Call this to connect to all tier 1 libraries.
// It's up to the caller to check the globals it cares about to see if ones are missing
//-----------------------------------------------------------------------------
void ConnectInterfaces( CreateInterfaceFn *pFactoryList, int nFactoryCount )
{
if ( s_nRegistrationCount < 0 )
{
Error( "APPSYSTEM: In ConnectInterfaces(), s_nRegistrationCount is %d!\n", s_nRegistrationCount );
}
else if ( s_nRegistrationCount == 0 )
{
for ( int i = 0; i < nFactoryCount; ++i )
{
for ( int j = 0; j < ARRAYSIZE( g_pInterfaceGlobals ); ++j )
{
RegisterInterface( pFactoryList[i], g_pInterfaceGlobals[j].m_pInterfaceName, (void**)g_pInterfaceGlobals[j].m_ppGlobal );
}
}
}
else
{
// This is no longer questionable: ConnectInterfaces() is expected to be called multiple times for a file that exports multiple interfaces.
// Warning("APPSYSTEM: ConnectInterfaces() was called twice for the same DLL.\nThis is expected behavior in building reslists, but questionable otherwise.\n");
for ( int i = 0; i < nFactoryCount; ++i )
{
for ( int j = 0; j < ARRAYSIZE( g_pInterfaceGlobals ); ++j )
{
ReconnectInterface( pFactoryList[i], g_pInterfaceGlobals[j].m_pInterfaceName, (void**)g_pInterfaceGlobals[j].m_ppGlobal );
}
}
}
++s_nConnectionCount;
}
void DisconnectInterfaces()
{
Assert( s_nConnectionCount > 0 );
if ( --s_nConnectionCount < 0 )
return;
for ( int i = 0; i < s_nRegistrationCount; ++i )
{
if ( s_pConnectionRegistration[i].m_nConnectionPhase != s_nConnectionCount )
continue;
// Disconnect!
*(void**)(s_pConnectionRegistration[i].m_ppGlobalStorage) = 0;
}
}
//-----------------------------------------------------------------------------
// Reloads an interface
//-----------------------------------------------------------------------------
void ReconnectInterface( CreateInterfaceFn factory, const char *pInterfaceName )
{
for ( int i = 0; i < ARRAYSIZE( g_pInterfaceGlobals ); ++i )
{
if ( strcmp( g_pInterfaceGlobals[i].m_pInterfaceName, pInterfaceName ) )
continue;
ReconnectInterface( factory, g_pInterfaceGlobals[i].m_pInterfaceName, (void**)g_pInterfaceGlobals[i].m_ppGlobal );
}
}

BIN
external/vpc/lib/common/libclient.lib vendored Normal file

Binary file not shown.

BIN
external/vpc/lib/common/libp4sslstub.lib vendored Normal file

Binary file not shown.

BIN
external/vpc/lib/common/librpc.lib vendored Normal file

Binary file not shown.

BIN
external/vpc/lib/common/libsupp.lib vendored Normal file

Binary file not shown.

2556
external/vpc/p4lib/p4.cpp vendored Normal file

File diff suppressed because it is too large Load Diff

43
external/vpc/p4lib/p4lib.vpc vendored Normal file
View File

@@ -0,0 +1,43 @@
//-----------------------------------------------------------------------------
// P4LIB.VPC
//
// Project Script
//-----------------------------------------------------------------------------
$Macro SRCDIR ".."
$Macro OUTBINDIR "$SRCDIR\..\game\bin"
$Include "$SRCDIR\vpc_scripts\source_dll_base.vpc"
$Configuration
{
$Compiler
{
$AdditionalIncludeDirectories "$BASE,$SRCDIR\common\p4api"
}
$Linker
{
$AdditionalDependencies "$BASE wsock32.lib"
}
}
$Project "P4lib"
{
$Folder "Source Files"
{
$File "p4.cpp"
}
$Folder "Header Files"
{
$File "$SRCDIR/public/p4lib/ip4.h"
}
$Folder "Link Libraries"
{
$File "$SRCDIR/lib/common/libclient.lib"
$File "$SRCDIR/lib/common/librpc.lib"
$File "$SRCDIR/lib/common/libsupp.lib"
}
}

View File

@@ -0,0 +1,121 @@
//===== Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ======//
//
// Purpose: An application framework
//
// $Revision: $
// $NoKeywords: $
//===========================================================================//
#ifndef IAPPSYSTEM_H
#define IAPPSYSTEM_H
#ifdef COMPILER_MSVC
#pragma once
#endif
#include "tier1/interface.h"
#include "interfaces/interfaces.h"
//-----------------------------------------------------------------------------
// Specifies a module + interface name for initialization
//-----------------------------------------------------------------------------
struct AppSystemInfo_t
{
const char *m_pModuleName;
const char *m_pInterfaceName;
};
//-----------------------------------------------------------------------------
// Client systems are singleton objects in the client codebase responsible for
// various tasks
// The order in which the client systems appear in this list are the
// order in which they are initialized and updated. They are shut down in
// reverse order from which they are initialized.
//-----------------------------------------------------------------------------
enum InitReturnVal_t
{
INIT_FAILED = 0,
INIT_OK,
INIT_LAST_VAL,
};
enum AppSystemTier_t
{
APP_SYSTEM_TIER0 = 0,
APP_SYSTEM_TIER1,
APP_SYSTEM_TIER2,
APP_SYSTEM_TIER3,
APP_SYSTEM_TIER_OTHER,
};
abstract_class IAppSystem
{
public:
// Here's where the app systems get to learn about each other
virtual bool Connect( CreateInterfaceFn factory ) = 0;
virtual void Disconnect() = 0;
// Here's where systems can access other interfaces implemented by this object
// Returns NULL if it doesn't implement the requested interface
virtual void *QueryInterface( const char *pInterfaceName ) = 0;
// Init, shutdown
virtual InitReturnVal_t Init() = 0;
virtual void Shutdown() = 0;
// Returns all dependent libraries
virtual const AppSystemInfo_t* GetDependencies() = 0;
// Returns the tier
virtual AppSystemTier_t GetTier() = 0;
// Reconnect to a particular interface
virtual void Reconnect( CreateInterfaceFn factory, const char *pInterfaceName ) = 0;
};
//-----------------------------------------------------------------------------
// Helper empty implementation of an IAppSystem
//-----------------------------------------------------------------------------
template< class IInterface >
class CBaseAppSystem : public IInterface
{
public:
// Here's where the app systems get to learn about each other
virtual bool Connect( CreateInterfaceFn factory ) { return true; }
virtual void Disconnect() {}
// Here's where systems can access other interfaces implemented by this object
// Returns NULL if it doesn't implement the requested interface
virtual void *QueryInterface( const char *pInterfaceName ) { return NULL; }
// Init, shutdown
virtual InitReturnVal_t Init() { return INIT_OK; }
virtual void Shutdown() {}
virtual const AppSystemInfo_t* GetDependencies() { return NULL; }
virtual AppSystemTier_t GetTier() { return APP_SYSTEM_TIER_OTHER; }
virtual void Reconnect( CreateInterfaceFn factory, const char *pInterfaceName )
{
ReconnectInterface( factory, pInterfaceName );
}
};
//-----------------------------------------------------------------------------
// Helper implementation of an IAppSystem for tier0
//-----------------------------------------------------------------------------
template< class IInterface >
class CTier0AppSystem : public CBaseAppSystem< IInterface >
{
};
#endif // IAPPSYSTEM_H

124
external/vpc/public/color.h vendored Normal file
View File

@@ -0,0 +1,124 @@
//========= Copyright (c) 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#ifndef COLOR_H
#define COLOR_H
#ifdef _WIN32
#pragma once
#endif
#include "tier0/basetypes.h"
//-----------------------------------------------------------------------------
// Purpose: Basic handler for an rgb set of colors
// This class is fully inline
//-----------------------------------------------------------------------------
class Color
{
public:
// constructors
Color()
{
*((int *)this) = 0;
}
Color(int _r,int _g,int _b)
{
SetColor(_r, _g, _b, 0);
}
Color(int _r,int _g,int _b,int _a)
{
SetColor(_r, _g, _b, _a);
}
// set the color
// r - red component (0-255)
// g - green component (0-255)
// b - blue component (0-255)
// a - alpha component, controls transparency (0 - transparent, 255 - opaque);
void SetColor(int _r, int _g, int _b, int _a = 0)
{
_color[0] = (unsigned char)_r;
_color[1] = (unsigned char)_g;
_color[2] = (unsigned char)_b;
_color[3] = (unsigned char)_a;
}
void GetColor(int &_r, int &_g, int &_b, int &_a) const
{
_r = _color[0];
_g = _color[1];
_b = _color[2];
_a = _color[3];
}
void SetRawColor( int color32 )
{
*((int *)this) = color32;
}
int GetRawColor() const
{
return *((int *)this);
}
inline int r() const { return _color[0]; }
inline int g() const { return _color[1]; }
inline int b() const { return _color[2]; }
inline int a() const { return _color[3]; }
unsigned char &operator[](int index)
{
return _color[index];
}
const unsigned char &operator[](int index) const
{
return _color[index];
}
bool operator == (const Color &rhs) const
{
return ( *((int *)this) == *((int *)&rhs) );
}
bool operator != (const Color &rhs) const
{
return !(operator==(rhs));
}
Color &operator=( const Color &rhs )
{
SetRawColor( rhs.GetRawColor() );
return *this;
}
Color &operator=( const color32 &rhs )
{
_color[0] = rhs.r;
_color[1] = rhs.g;
_color[2] = rhs.b;
_color[3] = rhs.a;
return *this;
}
color32 ToColor32() const
{
color32 newColor;
newColor.r = _color[0];
newColor.g = _color[1];
newColor.b = _color[2];
newColor.a = _color[3];
return newColor;
}
private:
unsigned char _color[4];
};
#endif // COLOR_H

521
external/vpc/public/datamap.h vendored Normal file
View File

@@ -0,0 +1,521 @@
//========= Copyright 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#ifndef DATAMAP_H
#define DATAMAP_H
#ifdef _WIN32
#pragma once
#endif
#ifndef VECTOR_H
#include "mathlib/vector.h"
#endif
#include "tier1/utlvector.h"
#include "tier0/memdbgon.h"
// SINGLE_INHERITANCE restricts the size of CBaseEntity pointers-to-member-functions to 4 bytes
class SINGLE_INHERITANCE CBaseEntity;
struct inputdata_t;
#define INVALID_TIME (FLT_MAX * -1.0) // Special value not rebased on save/load
typedef enum _fieldtypes
{
FIELD_VOID = 0, // No type or value
FIELD_FLOAT, // Any floating point value
FIELD_STRING, // A string ID (return from ALLOC_STRING)
FIELD_VECTOR, // Any vector, QAngle, or AngularImpulse
FIELD_QUATERNION, // A quaternion
FIELD_INTEGER, // Any integer or enum
FIELD_BOOLEAN, // boolean, implemented as an int, I may use this as a hint for compression
FIELD_SHORT, // 2 byte integer
FIELD_CHARACTER, // a byte
FIELD_COLOR32, // 8-bit per channel r,g,b,a (32bit color)
FIELD_EMBEDDED, // an embedded object with a datadesc, recursively traverse and embedded class/structure based on an additional typedescription
FIELD_CUSTOM, // special type that contains function pointers to it's read/write/parse functions
FIELD_CLASSPTR, // CBaseEntity *
FIELD_EHANDLE, // Entity handle
FIELD_EDICT, // edict_t *
FIELD_POSITION_VECTOR, // A world coordinate (these are fixed up across level transitions automagically)
FIELD_TIME, // a floating point time (these are fixed up automatically too!)
FIELD_TICK, // an integer tick count( fixed up similarly to time)
FIELD_MODELNAME, // Engine string that is a model name (needs precache)
FIELD_SOUNDNAME, // Engine string that is a sound name (needs precache)
FIELD_INPUT, // a list of inputed data fields (all derived from CMultiInputVar)
FIELD_FUNCTION, // A class function pointer (Think, Use, etc)
FIELD_VMATRIX, // a vmatrix (output coords are NOT worldspace)
// NOTE: Use float arrays for local transformations that don't need to be fixed up.
FIELD_VMATRIX_WORLDSPACE,// A VMatrix that maps some local space to world space (translation is fixed up on level transitions)
FIELD_MATRIX3X4_WORLDSPACE, // matrix3x4_t that maps some local space to world space (translation is fixed up on level transitions)
FIELD_INTERVAL, // a start and range floating point interval ( e.g., 3.2->3.6 == 3.2 and 0.4 )
FIELD_MODELINDEX, // a model index
FIELD_MATERIALINDEX, // a material index (using the material precache string table)
FIELD_VECTOR2D, // 2 floats
FIELD_INTEGER64, // 64bit integer
FIELD_VECTOR4D, // 4 floats
FIELD_TYPECOUNT, // MUST BE LAST
} fieldtype_t;
//-----------------------------------------------------------------------------
// Field sizes...
//-----------------------------------------------------------------------------
template <int FIELD_TYPE>
class CDatamapFieldSizeDeducer
{
public:
enum
{
SIZE = 0
};
static int FieldSize( )
{
return 0;
}
};
#define DECLARE_FIELD_SIZE( _fieldType, _fieldSize ) \
template< > class CDatamapFieldSizeDeducer<_fieldType> { public: enum { SIZE = _fieldSize }; static int FieldSize() { return _fieldSize; } };
#define FIELD_SIZE( _fieldType ) CDatamapFieldSizeDeducer<_fieldType>::SIZE
#define FIELD_BITS( _fieldType ) (FIELD_SIZE( _fieldType ) * 8)
DECLARE_FIELD_SIZE( FIELD_FLOAT, sizeof(float) )
DECLARE_FIELD_SIZE( FIELD_STRING, sizeof(int) )
DECLARE_FIELD_SIZE( FIELD_VECTOR, 3 * sizeof(float) )
DECLARE_FIELD_SIZE( FIELD_VECTOR2D, 2 * sizeof(float) )
DECLARE_FIELD_SIZE( FIELD_VECTOR4D, 4 * sizeof( float ) )
DECLARE_FIELD_SIZE( FIELD_QUATERNION, 4 * sizeof(float))
DECLARE_FIELD_SIZE( FIELD_INTEGER, sizeof(int))
DECLARE_FIELD_SIZE( FIELD_INTEGER64, sizeof(int64))
DECLARE_FIELD_SIZE( FIELD_BOOLEAN, sizeof(char))
DECLARE_FIELD_SIZE( FIELD_SHORT, sizeof(short))
DECLARE_FIELD_SIZE( FIELD_CHARACTER, sizeof(char))
DECLARE_FIELD_SIZE( FIELD_COLOR32, sizeof(int))
DECLARE_FIELD_SIZE( FIELD_CLASSPTR, sizeof(int))
DECLARE_FIELD_SIZE( FIELD_EHANDLE, sizeof(int))
DECLARE_FIELD_SIZE( FIELD_EDICT, sizeof(int))
DECLARE_FIELD_SIZE( FIELD_POSITION_VECTOR, 3 * sizeof(float))
DECLARE_FIELD_SIZE( FIELD_TIME, sizeof(float))
DECLARE_FIELD_SIZE( FIELD_TICK, sizeof(int))
DECLARE_FIELD_SIZE( FIELD_MODELNAME, sizeof(int))
DECLARE_FIELD_SIZE( FIELD_SOUNDNAME, sizeof(int))
DECLARE_FIELD_SIZE( FIELD_INPUT, sizeof(int))
#if defined(_WIN32)
DECLARE_FIELD_SIZE( FIELD_FUNCTION, sizeof(void *))
#elif defined(POSIX)
// pointer to members under gnuc are 8bytes if you have a virtual func
DECLARE_FIELD_SIZE( FIELD_FUNCTION, 2 * sizeof(void *))
#else
#error
#endif
DECLARE_FIELD_SIZE( FIELD_VMATRIX, 16 * sizeof(float))
DECLARE_FIELD_SIZE( FIELD_VMATRIX_WORLDSPACE, 16 * sizeof(float))
DECLARE_FIELD_SIZE( FIELD_MATRIX3X4_WORLDSPACE, 12 * sizeof(float))
DECLARE_FIELD_SIZE( FIELD_INTERVAL, 2 * sizeof( float) ) // NOTE: Must match interval.h definition
DECLARE_FIELD_SIZE( FIELD_MODELINDEX, sizeof(int) )
DECLARE_FIELD_SIZE( FIELD_MATERIALINDEX, sizeof(int) )
#define ARRAYSIZE2D(p) (sizeof(p)/sizeof(p[0][0]))
#define SIZE_OF_ARRAY(p) _ARRAYSIZE(p)
#define _FIELD(name,fieldtype,count,flags,mapname,tolerance) { fieldtype, #name, offsetof(classNameTypedef, name), count, flags, mapname, NULL, NULL, NULL, sizeof( ((classNameTypedef *)0)->name ), NULL, 0, tolerance }
#define DEFINE_FIELD_NULL { FIELD_VOID,0,0,0,0,0,0,0,0}
#define DEFINE_FIELD(name,fieldtype) _FIELD(name, fieldtype, 1, FTYPEDESC_SAVE, NULL, 0 )
#define DEFINE_FIELD_NOT_SAVED(name,fieldtype) _FIELD(name, fieldtype, 1, 0, NULL, 0 )
#define DEFINE_KEYFIELD(name,fieldtype, mapname) _FIELD(name, fieldtype, 1, FTYPEDESC_KEY | FTYPEDESC_SAVE, mapname, 0 )
#define DEFINE_KEYFIELD_NOT_SAVED(name,fieldtype, mapname)_FIELD(name, fieldtype, 1, FTYPEDESC_KEY, mapname, 0 )
#define DEFINE_AUTO_ARRAY(name,fieldtype) _FIELD(name, fieldtype, SIZE_OF_ARRAY(((classNameTypedef *)0)->name), FTYPEDESC_SAVE, NULL, 0 )
#define DEFINE_AUTO_ARRAY_KEYFIELD(name,fieldtype,mapname) _FIELD(name, fieldtype, SIZE_OF_ARRAY(((classNameTypedef *)0)->name), FTYPEDESC_SAVE, mapname, 0 )
#define DEFINE_ARRAY(name,fieldtype, count) _FIELD(name, fieldtype, count, FTYPEDESC_SAVE, NULL, 0 )
#define DEFINE_ARRAY_NOT_SAVED(name,fieldtype, count) _FIELD(name, fieldtype, count, 0, NULL, 0 )
#define DEFINE_ENTITY_FIELD(name,fieldtype) _FIELD(edict_t, name, fieldtype, 1, FTYPEDESC_KEY | FTYPEDESC_SAVE, #name, 0 )
#define DEFINE_ENTITY_GLOBAL_FIELD(name,fieldtype) _FIELD(edict_t, name, fieldtype, 1, FTYPEDESC_KEY | FTYPEDESC_SAVE | FTYPEDESC_GLOBAL, #name, 0 )
#define DEFINE_GLOBAL_FIELD(name,fieldtype) _FIELD(name, fieldtype, 1, FTYPEDESC_GLOBAL | FTYPEDESC_SAVE, NULL, 0 )
#define DEFINE_GLOBAL_KEYFIELD(name,fieldtype, mapname) _FIELD(name, fieldtype, 1, FTYPEDESC_GLOBAL | FTYPEDESC_KEY | FTYPEDESC_SAVE, mapname, 0 )
#define DEFINE_CUSTOM_FIELD(name,datafuncs) { FIELD_CUSTOM, #name, offsetof(classNameTypedef, name), 1, FTYPEDESC_SAVE, NULL, datafuncs, NULL }
#define DEFINE_CUSTOM_KEYFIELD(name,datafuncs,mapname) { FIELD_CUSTOM, #name, offsetof(classNameTypedef, name), 1, FTYPEDESC_SAVE | FTYPEDESC_KEY, mapname, datafuncs, NULL }
#define DEFINE_AUTO_ARRAY2D(name,fieldtype) _FIELD(name, fieldtype, ARRAYSIZE2D(((classNameTypedef *)0)->name), FTYPEDESC_SAVE, NULL, 0 )
// Used by byteswap datadescs
#define DEFINE_BITFIELD(name,fieldtype,bitcount) DEFINE_ARRAY(name,fieldtype,((bitcount+FIELD_BITS(fieldtype)-1)&~(FIELD_BITS(fieldtype)-1)) / FIELD_BITS(fieldtype) )
#define DEFINE_INDEX(name,fieldtype) _FIELD(name, fieldtype, 1, FTYPEDESC_INDEX, NULL, 0 )
#define DEFINE_EMBEDDED( name ) \
{ FIELD_EMBEDDED, #name, offsetof(classNameTypedef, name), 1, FTYPEDESC_SAVE, NULL, NULL, NULL, &(((classNameTypedef *)0)->name.m_DataMap), sizeof( ((classNameTypedef *)0)->name ), NULL, 0, 0.0f }
#define DEFINE_EMBEDDED_OVERRIDE( name, overridetype ) \
{ FIELD_EMBEDDED, #name, offsetof(classNameTypedef, name), 1, FTYPEDESC_SAVE, NULL, NULL, NULL, &((overridetype *)0)->m_DataMap, sizeof( ((classNameTypedef *)0)->name ), NULL, 0, 0.0f }
#define DEFINE_EMBEDDEDBYREF( name ) \
{ FIELD_EMBEDDED, #name, offsetof(classNameTypedef, name), 1, FTYPEDESC_SAVE | FTYPEDESC_PTR, NULL, NULL, NULL, &(((classNameTypedef *)0)->name->m_DataMap), sizeof( *(((classNameTypedef *)0)->name) ), NULL, 0, 0.0f }
#define DEFINE_EMBEDDED_ARRAY( name, count ) \
{ FIELD_EMBEDDED, #name, offsetof(classNameTypedef, name), count, FTYPEDESC_SAVE, NULL, NULL, NULL, &(((classNameTypedef *)0)->name->m_DataMap), sizeof( ((classNameTypedef *)0)->name[0] ), NULL, 0, 0.0f }
#define DEFINE_EMBEDDED_AUTO_ARRAY( name ) \
{ FIELD_EMBEDDED, #name, offsetof(classNameTypedef, name), SIZE_OF_ARRAY( ((classNameTypedef *)0)->name ), FTYPEDESC_SAVE, NULL, NULL, NULL, &(((classNameTypedef *)0)->name->m_DataMap), sizeof( ((classNameTypedef *)0)->name[0] ), NULL, 0, 0.0f }
#ifndef NO_ENTITY_PREDICTION
// FTYPEDESC_KEY tells the prediction copy system to report the full nameof the field when reporting errors
#define DEFINE_PRED_TYPEDESCRIPTION( name, fieldtype ) \
{ FIELD_EMBEDDED, #name, offsetof(classNameTypedef, name), 1, FTYPEDESC_SAVE | FTYPEDESC_KEY, NULL, NULL, NULL, &fieldtype::m_PredMap }
#define DEFINE_PRED_TYPEDESCRIPTION_PTR( name, fieldtype ) \
{ FIELD_EMBEDDED, #name, offsetof(classNameTypedef, name), 1, FTYPEDESC_SAVE | FTYPEDESC_PTR | FTYPEDESC_KEY, NULL, NULL, NULL, &fieldtype::m_PredMap }
#else
#define DEFINE_PRED_TYPEDESCRIPTION( name, fieldtype ) DEFINE_FIELD_NULL
#define DEFINE_PRED_TYPEDESCRIPTION_PTR( name, fieldtype ) DEFINE_FIELD_NULL
#endif
// Extensions to datamap.h macros for predicted entities only
#define DEFINE_PRED_FIELD(name,fieldtype, flags) _FIELD(name, fieldtype, 1, flags, NULL, 0.0f )
#define DEFINE_PRED_ARRAY(name,fieldtype, count,flags) _FIELD(name, fieldtype, count, flags, NULL, 0.0f )
#define DEFINE_FIELD_NAME(localname,netname,fieldtype) _FIELD(localname, fieldtype, 1, 0, #netname, 0.0f )
// Predictable macros, which include a tolerance for floating point values...
#define DEFINE_PRED_FIELD_TOL(name,fieldtype, flags,tolerance) _FIELD(name, fieldtype, 1, flags, NULL, tolerance )
#define DEFINE_PRED_ARRAY_TOL(name,fieldtype, count,flags,tolerance) _FIELD(name, fieldtype, count, flags, NULL, tolerance)
#define DEFINE_FIELD_NAME_TOL(localname,netname,fieldtolerance) _FIELD(localname, fieldtype, 1, 0, #netname, tolerance )
//#define DEFINE_DATA( name, fieldextname, flags ) _FIELD(name, fieldtype, 1, flags, extname )
// INPUTS
#define DEFINE_INPUT( name, fieldtype, inputname ) { fieldtype, #name, offsetof(classNameTypedef, name), 1, FTYPEDESC_INPUT | FTYPEDESC_SAVE | FTYPEDESC_KEY, inputname, NULL, NULL, NULL, sizeof( ((classNameTypedef *)0)->name ) }
#define DEFINE_INPUTFUNC( fieldtype, inputname, inputfunc ) { fieldtype, #inputfunc, NULL, 1, FTYPEDESC_INPUT, inputname, NULL, static_cast <inputfunc_t> (&classNameTypedef::inputfunc) }
// OUTPUTS
// the variable 'name' MUST BE derived from CBaseOutput
// we know the output type from the variable itself, so it doesn't need to be specified here
class ISaveRestoreOps;
extern ISaveRestoreOps *eventFuncs;
#define DEFINE_OUTPUT( name, outputname ) { FIELD_CUSTOM, #name, offsetof(classNameTypedef, name), 1, FTYPEDESC_OUTPUT | FTYPEDESC_SAVE | FTYPEDESC_KEY, outputname, eventFuncs }
// replaces EXPORT table for portability and non-DLL based systems (xbox)
#define DEFINE_FUNCTION_RAW( function, func_type ) { FIELD_VOID, nameHolder.GenerateName(#function), NULL, 1, FTYPEDESC_FUNCTIONTABLE, NULL, NULL, (inputfunc_t)((func_type)(&classNameTypedef::function)) }
#define DEFINE_FUNCTION( function ) DEFINE_FUNCTION_RAW( function, inputfunc_t )
#define FTYPEDESC_GLOBAL 0x0001 // This field is masked for global entity save/restore
#define FTYPEDESC_SAVE 0x0002 // This field is saved to disk
#define FTYPEDESC_KEY 0x0004 // This field can be requested and written to by string name at load time
#define FTYPEDESC_INPUT 0x0008 // This field can be written to by string name at run time, and a function called
#define FTYPEDESC_OUTPUT 0x0010 // This field propagates its value to all targets whenever it changes
#define FTYPEDESC_FUNCTIONTABLE 0x0020 // This is a table entry for a member function pointer
#define FTYPEDESC_PTR 0x0040 // This field is a pointer, not an embedded object
#define FTYPEDESC_OVERRIDE 0x0080 // The field is an override for one in a base class (only used by prediction system for now)
// Flags used by other systems (e.g., prediction system)
#define FTYPEDESC_INSENDTABLE 0x0100 // This field is present in a network SendTable
#define FTYPEDESC_PRIVATE 0x0200 // The field is local to the client or server only (not referenced by prediction code and not replicated by networking)
#define FTYPEDESC_NOERRORCHECK 0x0400 // The field is part of the prediction typedescription, but doesn't get compared when checking for errors
#define FTYPEDESC_MODELINDEX 0x0800 // The field is a model index (used for debugging output)
#define FTYPEDESC_INDEX 0x1000 // The field is an index into file data, used for byteswapping.
// These flags apply to C_BasePlayer derived objects only
#define FTYPEDESC_VIEW_OTHER_PLAYER 0x2000 // By default you can only view fields on the local player (yourself),
// but if this is set, then we allow you to see fields on other players
#define FTYPEDESC_VIEW_OWN_TEAM 0x4000 // Only show this data if the player is on the same team as the local player
#define FTYPEDESC_VIEW_NEVER 0x8000 // Never show this field to anyone, even the local player (unusual)
#define TD_MSECTOLERANCE 0.001f // This is a FIELD_FLOAT and should only be checked to be within 0.001 of the networked info
struct typedescription_t;
class ISaveRestoreOps;
//
// Function prototype for all input handlers.
//
typedef void (CBaseEntity::*inputfunc_t)(inputdata_t &data);
struct datamap_t;
struct typedescription_t;
enum
{
PC_NON_NETWORKED_ONLY = 0,
PC_NETWORKED_ONLY,
PC_COPYTYPE_COUNT,
PC_EVERYTHING = PC_COPYTYPE_COUNT,
};
enum
{
TD_OFFSET_NORMAL = 0,
TD_OFFSET_PACKED = 1,
// Must be last
TD_OFFSET_COUNT,
};
struct typedescription_t
{
fieldtype_t fieldType;
const char *fieldName;
int fieldOffset; // Local offset value
unsigned short fieldSize;
short flags;
// the name of the variable in the map/fgd data, or the name of the action
const char *externalName;
// pointer to the function set for save/restoring of custom data types
ISaveRestoreOps *pSaveRestoreOps;
// for associating function with string names
inputfunc_t inputFunc;
// For embedding additional datatables inside this one
datamap_t *td;
// Stores the actual member variable size in bytes
int fieldSizeInBytes;
// FTYPEDESC_OVERRIDE point to first baseclass instance if chains_validated has occurred
struct typedescription_t *override_field;
// Used to track exclusion of baseclass fields
int override_count;
// Tolerance for field errors for float fields
float fieldTolerance;
// For raw fields (including children of embedded stuff) this is the flattened offset
int flatOffset[ TD_OFFSET_COUNT ];
unsigned short flatGroup;
};
// See predictioncopy.h for implementation and notes
struct optimized_datamap_t;
//-----------------------------------------------------------------------------
// Purpose: stores the list of objects in the hierarchy
// used to iterate through an object's data descriptions
//-----------------------------------------------------------------------------
struct datamap_t
{
typedescription_t *dataDesc;
int dataNumFields;
char const *dataClassName;
datamap_t *baseMap;
int m_nPackedSize;
optimized_datamap_t *m_pOptimizedDataMap;
#if defined( _DEBUG )
bool bValidityChecked;
#endif // _DEBUG
};
//-----------------------------------------------------------------------------
//
// Macros used to implement datadescs
//
#define DECLARE_FRIEND_DATADESC_ACCESS() \
template <typename T> friend void DataMapAccess(T *, datamap_t **p); \
template <typename T> friend datamap_t *DataMapInit(T *);
#define DECLARE_SIMPLE_DATADESC() \
static datamap_t m_DataMap; \
static datamap_t *GetBaseMap(); \
template <typename T> friend void DataMapAccess(T *, datamap_t **p); \
template <typename T> friend datamap_t *DataMapInit(T *);
#if defined(POSIX) && !defined(_PS3)
#define DECLARE_SIMPLE_DATADESC_INSIDE_NAMESPACE() \
static datamap_t m_DataMap; \
static datamap_t *GetBaseMap(); \
template <typename T> friend void ::DataMapAccess(T *, datamap_t **p);
#else
#define DECLARE_SIMPLE_DATADESC_INSIDE_NAMESPACE() \
static datamap_t m_DataMap; \
static datamap_t *GetBaseMap(); \
template <typename T> friend void ::DataMapAccess(T *, datamap_t **p); \
template <typename T> friend datamap_t *::DataMapInit(T *);
#endif
#define DECLARE_DATADESC() \
DECLARE_SIMPLE_DATADESC() \
virtual datamap_t *GetDataDescMap( void );
#define BEGIN_DATADESC( className ) \
datamap_t className::m_DataMap = { 0, 0, #className, NULL }; \
datamap_t *className::GetDataDescMap( void ) { return &m_DataMap; } \
datamap_t *className::GetBaseMap() { datamap_t *pResult; DataMapAccess((BaseClass *)NULL, &pResult); return pResult; } \
BEGIN_DATADESC_GUTS( className )
#define BEGIN_DATADESC_NO_BASE( className ) \
datamap_t className::m_DataMap = { 0, 0, #className, NULL }; \
datamap_t *className::GetDataDescMap( void ) { return &m_DataMap; } \
datamap_t *className::GetBaseMap() { return NULL; } \
BEGIN_DATADESC_GUTS( className )
#define BEGIN_SIMPLE_DATADESC( className ) \
datamap_t className::m_DataMap = { 0, 0, #className, NULL }; \
datamap_t *className::GetBaseMap() { return NULL; } \
BEGIN_DATADESC_GUTS( className )
#define BEGIN_SIMPLE_DATADESC_( className, BaseClass ) \
datamap_t className::m_DataMap = { 0, 0, #className, NULL }; \
datamap_t *className::GetBaseMap() { datamap_t *pResult; DataMapAccess((BaseClass *)NULL, &pResult); return pResult; } \
BEGIN_DATADESC_GUTS( className )
#define BEGIN_DATADESC_GUTS( className ) \
template <typename T> datamap_t *DataMapInit(T *); \
template <> datamap_t *DataMapInit<className>( className * ); \
namespace className##_DataDescInit \
{ \
datamap_t *g_DataMapHolder = DataMapInit<className>( (className *)NULL ); /* This can/will be used for some clean up duties later */ \
} \
\
template <> datamap_t *DataMapInit<className>( className * ) \
{ \
typedef className classNameTypedef; \
static CDatadescGeneratedNameHolder nameHolder(#className); \
className::m_DataMap.baseMap = className::GetBaseMap(); \
static typedescription_t dataDesc[] = \
{ \
{ FIELD_VOID,0,0,0,0,0,0,0,0}, /* so you can define "empty" tables */
#define BEGIN_DATADESC_GUTS_NAMESPACE( className, nameSpace ) \
template <typename T> datamap_t *nameSpace::DataMapInit(T *); \
template <> datamap_t *nameSpace::DataMapInit<className>( className * ); \
namespace className##_DataDescInit \
{ \
datamap_t *g_DataMapHolder = nameSpace::DataMapInit( (className *)NULL ); /* This can/will be used for some clean up duties later */ \
} \
\
template <> datamap_t *nameSpace::DataMapInit<className>( className * ) \
{ \
typedef className classNameTypedef; \
static CDatadescGeneratedNameHolder nameHolder(#className); \
className::m_DataMap.baseMap = className::GetBaseMap(); \
static typedescription_t dataDesc[] = \
{ \
{ FIELD_VOID,0,0,0,0,0,0,0,0}, /* so you can define "empty" tables */
#define END_DATADESC() \
}; \
\
if ( sizeof( dataDesc ) > sizeof( dataDesc[0] ) ) \
{ \
classNameTypedef::m_DataMap.dataNumFields = SIZE_OF_ARRAY( dataDesc ) - 1; \
classNameTypedef::m_DataMap.dataDesc = &dataDesc[1]; \
} \
else \
{ \
classNameTypedef::m_DataMap.dataNumFields = 1; \
classNameTypedef::m_DataMap.dataDesc = dataDesc; \
} \
return &classNameTypedef::m_DataMap; \
}
// used for when there is no data description
#define IMPLEMENT_NULL_SIMPLE_DATADESC( derivedClass ) \
BEGIN_SIMPLE_DATADESC( derivedClass ) \
END_DATADESC()
#define IMPLEMENT_NULL_SIMPLE_DATADESC_( derivedClass, baseClass ) \
BEGIN_SIMPLE_DATADESC_( derivedClass, baseClass ) \
END_DATADESC()
#define IMPLEMENT_NULL_DATADESC( derivedClass ) \
BEGIN_DATADESC( derivedClass ) \
END_DATADESC()
// helps get the offset of a bitfield
#define BEGIN_BITFIELD( name ) \
union \
{ \
char name; \
struct \
{
#define END_BITFIELD() \
}; \
};
//-----------------------------------------------------------------------------
// Forward compatability with potential separate byteswap datadescs
#define DECLARE_BYTESWAP_DATADESC() DECLARE_SIMPLE_DATADESC()
#define BEGIN_BYTESWAP_DATADESC(name) BEGIN_SIMPLE_DATADESC(name)
#define BEGIN_BYTESWAP_DATADESC_(name,base) BEGIN_SIMPLE_DATADESC_(name,base)
#define END_BYTESWAP_DATADESC() END_DATADESC()
//-----------------------------------------------------------------------------
template <typename T>
inline void DataMapAccess(T *ignored, datamap_t **p)
{
*p = &T::m_DataMap;
}
//-----------------------------------------------------------------------------
class CDatadescGeneratedNameHolder
{
public:
CDatadescGeneratedNameHolder( const char *pszBase )
: m_pszBase(pszBase)
{
m_nLenBase = strlen( m_pszBase );
}
~CDatadescGeneratedNameHolder()
{
for ( int i = 0; i < m_Names.Count(); i++ )
{
delete m_Names[i];
}
}
const char *GenerateName( const char *pszIdentifier )
{
char *pBuf = new char[m_nLenBase + strlen(pszIdentifier) + 1];
strcpy( pBuf, m_pszBase );
strcat( pBuf, pszIdentifier );
m_Names.AddToTail( pBuf );
return pBuf;
}
private:
const char *m_pszBase;
size_t m_nLenBase;
CUtlVector<char *> m_Names;
};
//-----------------------------------------------------------------------------
// Compiler can require the global-namespace template friend to be declared
// before DECLARE_SIMPLE_DATADESC_INSIDE_NAMESPACE() can be used
template <typename T> datamap_t *DataMapInit(T *);
#include "tier0/memdbgoff.h"
#endif // DATAMAP_H

958
external/vpc/public/filesystem.h vendored Normal file
View File

@@ -0,0 +1,958 @@
//===== Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ======//
//
// Purpose:
//
// $NoKeywords: $
//===========================================================================//
#ifndef FILESYSTEM_H
#define FILESYSTEM_H
#ifdef _WIN32
#pragma once
#endif
#include <limits.h>
#include "tier0/threadtools.h"
#include "tier0/memalloc.h"
#include "tier0/tslist.h"
#include "tier1/interface.h"
#include "tier1/utlsymbol.h"
#include "tier1/utlstring.h"
#include "tier1/functors.h"
#include "tier1/checksum_crc.h"
#include "tier1/utlqueue.h"
#include "appframework/iappsystem.h"
#include "tier2/tier2.h"
#ifdef _PS3
#include <sysutil/sysutil_syscache.h>
#include <sysutil/sysutil_gamecontent.h>
struct HddCacheFileStatus;
extern char gSrcGameDataPath[];
class CFileGroupSystem;
#endif
//-----------------------------------------------------------------------------
// Forward declarations
//-----------------------------------------------------------------------------
class CUtlBuffer;
class KeyValues;
class IFileList;
typedef void * FileHandle_t;
typedef int FileFindHandle_t;
typedef void (*FileSystemLoggingFunc_t)( const char *fileName, const char *accessType );
typedef int WaitForResourcesHandle_t;
#ifdef _X360
typedef void* HANDLE;
#endif
//-----------------------------------------------------------------------------
// Enums used by the interface
//-----------------------------------------------------------------------------
#define FILESYSTEM_MAX_SEARCH_PATHS 128
enum FileSystemSeek_t
{
FILESYSTEM_SEEK_HEAD = SEEK_SET,
FILESYSTEM_SEEK_CURRENT = SEEK_CUR,
FILESYSTEM_SEEK_TAIL = SEEK_END,
};
enum
{
FILESYSTEM_INVALID_FIND_HANDLE = -1
};
enum FileWarningLevel_t
{
// A problem!
FILESYSTEM_WARNING = -1,
// Don't print anything
FILESYSTEM_WARNING_QUIET = 0,
// On shutdown, report names of files left unclosed
FILESYSTEM_WARNING_REPORTUNCLOSED,
// Report number of times a file was opened, closed
FILESYSTEM_WARNING_REPORTUSAGE,
// Report all open/close events to console ( !slow! )
FILESYSTEM_WARNING_REPORTALLACCESSES,
// Report all open/close/read events to the console ( !slower! )
FILESYSTEM_WARNING_REPORTALLACCESSES_READ,
// Report all open/close/read/write events to the console ( !slower! )
FILESYSTEM_WARNING_REPORTALLACCESSES_READWRITE,
// Report all open/close/read/write events and all async I/O file events to the console ( !slower(est)! )
FILESYSTEM_WARNING_REPORTALLACCESSES_ASYNC,
};
// search path filtering
enum PathTypeFilter_t
{
FILTER_NONE = 0, // no filtering, all search path types match
FILTER_CULLPACK = 1, // pack based search paths are culled (maps and zips)
FILTER_CULLNONPACK = 2, // non-pack based search paths are culled
FILTER_CULLLOCALIZED = 3, // Ignore localized paths, assumes CULLNONPACK
FILTER_CULLLOCALIZED_ANY = 4, // Ignore any localized paths
};
// search path querying (bit flags)
enum
{
PATH_IS_NORMAL = 0x00, // normal path, not pack based
PATH_IS_PACKFILE = 0x01, // path is a pack file
PATH_IS_MAPPACKFILE = 0x02, // path is a map pack file
PATH_IS_DVDDEV = 0x04, // path is the dvddev cache
};
typedef uint32 PathTypeQuery_t;
#define IS_PACKFILE( n ) ( n & ( PATH_IS_PACKFILE | PATH_IS_MAPPACKFILE ) )
#define IS_DVDDEV( n ) ( n & PATH_IS_DVDDEV )
enum DVDMode_t
{
DVDMODE_OFF = 0, // not using dvd
DVDMODE_STRICT = 1, // dvd device only
DVDMODE_DEV = 2, // dev mode, mutiple devices ok
DVDMODE_DEV_VISTA = 3, // dev mode from a vista host, mutiple devices ok
};
#ifdef _PS3
enum FsState_t
{
FS_STATE_INIT = 0,
FS_STATE_LEVEL_LOAD = 1,
FS_STATE_LEVEL_RUN = 2,
FS_STATE_LEVEL_RESTORE = 3,
FS_STATE_LEVEL_LOAD_END = 4,
FS_STATE_EXITING = 5
};
enum Ps3FileType_t
{
PS3_FILETYPE_WAV,
PS3_FILETYPE_ANI,
PS3_FILETYPE_BSP,
PS3_FILETYPE_VMT,
PS3_FILETYPE_QPRE,
PS3_FILETYPE_OTHER,
PS3_FILETYPE_DIR,
PS3_FILETYPE_UNKNOWN
};
#endif
// In non-retail builds, enable the file blocking access tracking stuff...
#if defined( TRACK_BLOCKING_IO )
enum FileBlockingWarning_t
{
// Report how long synchronous i/o took to complete
FILESYSTEM_BLOCKING_SYNCHRONOUS = 0,
// Report how long async i/o took to complete if AsyncFileFinished caused it to load via "blocking" i/o
FILESYSTEM_BLOCKING_ASYNCHRONOUS_BLOCK,
// Report how long async i/o took to complete
FILESYSTEM_BLOCKING_ASYNCHRONOUS,
// Report how long the async "callback" took
FILESYSTEM_BLOCKING_CALLBACKTIMING,
FILESYSTEM_BLOCKING_NUMBINS,
};
#pragma pack(1)
class FileBlockingItem
{
public:
enum
{
FB_ACCESS_OPEN = 1,
FB_ACCESS_CLOSE = 2,
FB_ACCESS_READ = 3,
FB_ACCESS_WRITE = 4,
FB_ACCESS_APPEND = 5,
FB_ACCESS_SIZE = 6
};
FileBlockingItem() :
m_ItemType( (FileBlockingWarning_t)0 ),
m_flElapsed( 0.0f ),
m_nAccessType( 0 )
{
SetFileName( NULL );
}
FileBlockingItem( int type, char const *filename, float elapsed, int accessType ) :
m_ItemType( (FileBlockingWarning_t)type ),
m_flElapsed( elapsed ),
m_nAccessType( accessType )
{
SetFileName( filename );
}
void SetFileName( char const *filename )
{
if ( !filename )
{
m_szFilename[ 0 ] = 0;
return;
}
int len = V_strlen( filename );
if ( len >= sizeof( m_szFilename ) )
{
V_strncpy( m_szFilename, &filename[ len - sizeof( m_szFilename ) + 1 ], sizeof( m_szFilename ) );
}
else
{
V_strncpy( m_szFilename, filename, sizeof( m_szFilename ) );
}
}
char const *GetFileName() const
{
return m_szFilename;
}
FileBlockingWarning_t m_ItemType;
float m_flElapsed;
byte m_nAccessType;
private:
char m_szFilename[ 32 ];
};
#pragma pack()
class IBlockingFileItemList
{
public:
// You can't call any of the below calls without locking first
virtual void LockMutex() = 0;
virtual void UnlockMutex() = 0;
virtual int First() const = 0;
virtual int Next( int i ) const = 0;
virtual int InvalidIndex() const = 0;
virtual const FileBlockingItem& Get( int index ) const = 0;
virtual void Reset() = 0;
};
#endif // TRACK_BLOCKING_IO
enum FilesystemMountRetval_t
{
FILESYSTEM_MOUNT_OK = 0,
FILESYSTEM_MOUNT_FAILED,
};
enum SearchPathAdd_t
{
PATH_ADD_TO_HEAD, // First path searched
PATH_ADD_TO_TAIL, // Last path searched
PATH_ADD_TO_TAIL_ATINDEX, // First path searched
};
enum FilesystemOpenExFlags_t
{
FSOPEN_UNBUFFERED = (1 << 0),
FSOPEN_FORCE_TRACK_CRC = (1 << 1), // This makes it calculate a CRC for the file (if the file came from disk) regardless
// of the IFileList passed to RegisterFileWhitelist.
FSOPEN_NEVERINPACK = (1 << 2), // 360 only, hint to FS that file is not allowed to be in pack file
};
#define FILESYSTEM_INVALID_HANDLE ( FileHandle_t )0
//-----------------------------------------------------------------------------
// Structures used by the interface
//-----------------------------------------------------------------------------
struct FileSystemStatistics
{
CInterlockedUInt nReads,
nWrites,
nBytesRead,
nBytesWritten,
nSeeks;
};
//-----------------------------------------------------------------------------
// File system allocation functions. Client must free on failure
//-----------------------------------------------------------------------------
typedef void *(*FSAllocFunc_t)( const char *pszFilename, unsigned nBytes );
//-----------------------------------------------------------------------------
// Used to display dirty disk error functions
//-----------------------------------------------------------------------------
typedef void (*FSDirtyDiskReportFunc_t)();
//-----------------------------------------------------------------------------
// Asynchronous support types
//-----------------------------------------------------------------------------
DECLARE_POINTER_HANDLE(FSAsyncControl_t);
DECLARE_POINTER_HANDLE(FSAsyncFile_t);
const FSAsyncFile_t FS_INVALID_ASYNC_FILE = (FSAsyncFile_t)(0x0000ffff);
//---------------------------------------------------------
// Async file status
//---------------------------------------------------------
enum FSAsyncStatus_t
{
FSASYNC_ERR_ALIGNMENT = -6, // read parameters invalid for unbuffered IO
FSASYNC_ERR_FAILURE = -5, // hard subsystem failure
FSASYNC_ERR_READING = -4, // read error on file
FSASYNC_ERR_NOMEMORY = -3, // out of memory for file read
FSASYNC_ERR_UNKNOWNID = -2, // caller's provided id is not recognized
FSASYNC_ERR_FILEOPEN = -1, // filename could not be opened (bad path, not exist, etc)
FSASYNC_OK = 0, // operation is successful
FSASYNC_STATUS_PENDING, // file is properly queued, waiting for service
FSASYNC_STATUS_INPROGRESS, // file is being accessed
FSASYNC_STATUS_ABORTED, // file was aborted by caller
FSASYNC_STATUS_UNSERVICED, // file is not yet queued
};
//---------------------------------------------------------
// Async request flags
//---------------------------------------------------------
enum FSAsyncFlags_t
{
FSASYNC_FLAGS_ALLOCNOFREE = ( 1 << 0 ), // do the allocation for dataPtr, but don't free
FSASYNC_FLAGS_FREEDATAPTR = ( 1 << 1 ), // free the memory for the dataPtr post callback
FSASYNC_FLAGS_SYNC = ( 1 << 2 ), // Actually perform the operation synchronously. Used to simplify client code paths
FSASYNC_FLAGS_NULLTERMINATE = ( 1 << 3 ), // allocate an extra byte and null terminate the buffer read in
};
//---------------------------------------------------------
// Return value for CheckFileCRC.
//---------------------------------------------------------
enum EFileCRCStatus
{
k_eFileCRCStatus_CantOpenFile, // We don't have this file.
k_eFileCRCStatus_GotCRC
};
// Used in CacheFileCRCs.
enum ECacheCRCType
{
k_eCacheCRCType_SingleFile,
k_eCacheCRCType_Directory,
k_eCacheCRCType_Directory_Recursive
};
//---------------------------------------------------------
// Optional completion callback for each async file serviced (or failed)
// call is not reentrant, async i/o guaranteed suspended until return
// Note: If you change the signature of the callback, you will have to account for it in FileSystemV12 (toml [4/18/2005] )
//---------------------------------------------------------
struct FileAsyncRequest_t;
typedef void (*FSAsyncCallbackFunc_t)(const FileAsyncRequest_t &request, int nBytesRead, FSAsyncStatus_t err);
//-----------------------------------------------------------------------------
// Used to add results from async directory scans
//-----------------------------------------------------------------------------
typedef void (*FSAsyncScanAddFunc_t)( void* pContext, char* pFoundPath, char* pFoundFile );
typedef void (*FSAsyncScanCompleteFunc_t)( void* pContext, FSAsyncStatus_t err );
//---------------------------------------------------------
// Description of an async request
//---------------------------------------------------------
struct FileAsyncRequest_t
{
FileAsyncRequest_t() { memset( this, 0, sizeof(*this) ); hSpecificAsyncFile = FS_INVALID_ASYNC_FILE; }
const char * pszFilename; // file system name
void * pData; // optional, system will alloc/free if NULL
int nOffset; // optional initial seek_set, 0=beginning
int nBytes; // optional read clamp, -1=exist test, 0=full read
FSAsyncCallbackFunc_t pfnCallback; // optional completion callback
void * pContext; // caller's unique file identifier
int priority; // inter list priority, 0=lowest
unsigned flags; // behavior modifier
const char * pszPathID; // path ID (NOTE: this field is here to remain binary compatible with release HL2 filesystem interface)
FSAsyncFile_t hSpecificAsyncFile; // Optional hint obtained using AsyncBeginRead()
FSAllocFunc_t pfnAlloc; // custom allocator. can be null. not compatible with FSASYNC_FLAGS_FREEDATAPTR
};
class CUnverifiedCRCFile
{
public:
char m_PathID[MAX_PATH];
char m_Filename[MAX_PATH];
CRC32_t m_CRC;
};
// Spew flags for SetWhitelistSpewFlags (set with the fs_whitelist_spew_flags cvar).
// Update the comment for the fs_whitelist_spew_flags cvar if you change these.
#define WHITELIST_SPEW_WHILE_LOADING 0x0001 // list files as they are added to the CRC tracker
#define WHITELIST_SPEW_RELOAD_FILES 0x0002 // show files the filesystem is telling the engine to reload
#define WHITELIST_SPEW_DONT_RELOAD_FILES 0x0004 // show files the filesystem is NOT telling the engine to reload
// DLC license mask flags is 32 publisher defined bits
// MSW 16 bits in 8.8: Type.SubVersion
// LSW 16 bits: Flags
// return id component
#define DLC_LICENSE_ID( x ) ( ( ( (unsigned int)( x ) ) >> 24 ) & 0x000000FF )
// returns minor version component (not generally used, i.e. we dont rev dlc's yet)
#define DLC_LICENSE_MINORVERSION( x ) ( ( ( (unsigned int)( x ) ) >> 16 ) & 0x000000FF )
// returns license flags
#define DLC_LICENSE_FLAGS( x ) ( ( ( (unsigned int)( x ) ) & 0x0000FFFF ) )
#define DLCFLAGS_PRESENCE_ONLY 0x0001 // causes no search path loadout
//-----------------------------------------------------------------------------
// Base file system interface
//-----------------------------------------------------------------------------
// This is the minimal interface that can be implemented to provide access to
// a named set of files.
#define BASEFILESYSTEM_INTERFACE_VERSION "VBaseFileSystem011"
abstract_class IBaseFileSystem
{
public:
virtual int Read( void* pOutput, int size, FileHandle_t file ) = 0;
virtual int Write( void const* pInput, int size, FileHandle_t file ) = 0;
// if pathID is NULL, all paths will be searched for the file
virtual FileHandle_t Open( const char *pFileName, const char *pOptions, const char *pathID = 0 ) = 0;
virtual void Close( FileHandle_t file ) = 0;
virtual void Seek( FileHandle_t file, int pos, FileSystemSeek_t seekType ) = 0;
virtual unsigned int Tell( FileHandle_t file ) = 0;
virtual unsigned int Size( FileHandle_t file ) = 0;
virtual unsigned int Size( const char *pFileName, const char *pPathID = 0 ) = 0;
virtual void Flush( FileHandle_t file ) = 0;
virtual bool Precache( const char *pFileName, const char *pPathID = 0 ) = 0;
virtual bool FileExists( const char *pFileName, const char *pPathID = 0 ) = 0;
virtual bool IsFileWritable( char const *pFileName, const char *pPathID = 0 ) = 0;
virtual bool SetFileWritable( char const *pFileName, bool writable, const char *pPathID = 0 ) = 0;
virtual long GetFileTime( const char *pFileName, const char *pPathID = 0 ) = 0;
//--------------------------------------------------------
// Reads/writes files to utlbuffers. Use this for optimal read performance when doing open/read/close
//--------------------------------------------------------
virtual bool ReadFile( const char *pFileName, const char *pPath, CUtlBuffer &buf, int nMaxBytes = 0, int nStartingByte = 0, FSAllocFunc_t pfnAlloc = NULL ) = 0;
virtual bool WriteFile( const char *pFileName, const char *pPath, CUtlBuffer &buf ) = 0;
virtual bool UnzipFile( const char *pFileName, const char *pPath, const char *pDestination ) = 0;
};
abstract_class IIoStats
{
public:
virtual void OnFileSeek( int nTimeInMs ) = 0;
virtual void OnFileRead( int nTimeInMs, int nBytesRead ) = 0;
virtual void OnFileOpen( const char * pFileName ) = 0;
virtual int GetNumberOfFileSeeks() = 0;
virtual int GetTimeInFileSeek() = 0;
virtual int GetNumberOfFileReads() = 0;
virtual int GetTimeInFileReads() = 0;
virtual int GetFileReadTotalSize() = 0;
virtual int GetNumberOfFileOpens() = 0;
virtual void Reset() = 0;
protected:
virtual ~IIoStats()
{
// Do nothing...
}
};
//-----------------------------------------------------------------------------
// Main file system interface
//-----------------------------------------------------------------------------
abstract_class IFileSystem : public IAppSystem, public IBaseFileSystem
{
public:
//--------------------------------------------------------
// Steam operations
//--------------------------------------------------------
virtual bool IsSteam() const = 0;
// Supplying an extra app id will mount this app in addition
// to the one specified in the environment variable "steamappid"
//
// If nExtraAppId is < -1, then it will mount that app ID only.
// (Was needed by the dedicated server b/c the "SteamAppId" env var only gets passed to steam.dll
// at load time, so the dedicated couldn't pass it in that way).
virtual FilesystemMountRetval_t MountSteamContent( int nExtraAppId = -1 ) = 0;
//--------------------------------------------------------
// Search path manipulation
//--------------------------------------------------------
// Add paths in priority order (mod dir, game dir, ....)
// If one or more .pak files are in the specified directory, then they are
// added after the file system path
// If the path is the relative path to a .bsp file, then any previous .bsp file
// override is cleared and the current .bsp is searched for an embedded PAK file
// and this file becomes the highest priority search path ( i.e., it's looked at first
// even before the mod's file system path ).
virtual void AddSearchPath( const char *pPath, const char *pathID, SearchPathAdd_t addType = PATH_ADD_TO_TAIL ) = 0;
virtual bool RemoveSearchPath( const char *pPath, const char *pathID = 0 ) = 0;
// Remove all search paths (including write path?)
virtual void RemoveAllSearchPaths( void ) = 0;
// Remove search paths associated with a given pathID
virtual void RemoveSearchPaths( const char *szPathID ) = 0;
// This is for optimization. If you mark a path ID as "by request only", then files inside it
// will only be accessed if the path ID is specifically requested. Otherwise, it will be ignored.
// If there are currently no search paths with the specified path ID, then it will still
// remember it in case you add search paths with this path ID.
virtual void MarkPathIDByRequestOnly( const char *pPathID, bool bRequestOnly ) = 0;
// converts a partial path into a full path
virtual const char *RelativePathToFullPath( const char *pFileName, const char *pPathID, char *pLocalPath, int localPathBufferSize, PathTypeFilter_t pathFilter = FILTER_NONE, PathTypeQuery_t *pPathType = NULL ) = 0;
#if IsGameConsole()
// Given a relative path, gets the PACK file that contained this file and its offset and size. Can be used to prefetch a file to a HDD for caching reason.
virtual bool GetPackFileInfoFromRelativePath( const char *pFileName, const char *pPathID, char *pPackPath, int nPackPathBufferSize, int64 &nPosition, int64 &nLength ) = 0;
#endif
// Returns the search path, each path is separated by ;s. Returns the length of the string returned
virtual int GetSearchPath( const char *pathID, bool bGetPackFiles, char *pPath, int nMaxLen ) = 0;
// interface for custom pack files > 4Gb
virtual bool AddPackFile( const char *fullpath, const char *pathID ) = 0;
//--------------------------------------------------------
// File manipulation operations
//--------------------------------------------------------
// Deletes a file (on the WritePath)
virtual void RemoveFile( char const* pRelativePath, const char *pathID = 0 ) = 0;
// Renames a file (on the WritePath)
virtual bool RenameFile( char const *pOldPath, char const *pNewPath, const char *pathID = 0 ) = 0;
// create a local directory structure
virtual void CreateDirHierarchy( const char *path, const char *pathID = 0 ) = 0;
// File I/O and info
virtual bool IsDirectory( const char *pFileName, const char *pathID = 0 ) = 0;
virtual void FileTimeToString( char* pStrip, int maxCharsIncludingTerminator, long fileTime ) = 0;
//--------------------------------------------------------
// Open file operations
//--------------------------------------------------------
virtual void SetBufferSize( FileHandle_t file, unsigned nBytes ) = 0;
virtual bool IsOk( FileHandle_t file ) = 0;
virtual bool EndOfFile( FileHandle_t file ) = 0;
virtual char *ReadLine( char *pOutput, int maxChars, FileHandle_t file ) = 0;
virtual int FPrintf( FileHandle_t file, const char *pFormat, ... ) FMTFUNCTION( 3, 4 ) = 0;
//--------------------------------------------------------
// Dynamic library operations
//--------------------------------------------------------
// load/unload modules
virtual CSysModule *LoadModule( const char *pFileName, const char *pPathID = 0, bool bValidatedDllOnly = true ) = 0;
virtual void UnloadModule( CSysModule *pModule ) = 0;
//--------------------------------------------------------
// File searching operations
//--------------------------------------------------------
// FindFirst/FindNext. Also see FindFirstEx.
virtual const char *FindFirst( const char *pWildCard, FileFindHandle_t *pHandle ) = 0;
virtual const char *FindNext( FileFindHandle_t handle ) = 0;
virtual bool FindIsDirectory( FileFindHandle_t handle ) = 0;
virtual void FindClose( FileFindHandle_t handle ) = 0;
// Same as FindFirst, but you can filter by path ID, which can make it faster.
virtual const char *FindFirstEx(
const char *pWildCard,
const char *pPathID,
FileFindHandle_t *pHandle
) = 0;
// Searches for a file in all paths and results absolute path names for the file, works in pack files (zip and vpk) too
// Lets you search for something like sound/sound.cache and get a list of every sound cache
virtual void FindFileAbsoluteList( CUtlVector< CUtlString > &outAbsolutePathNames, const char *pWildCard, const char *pPathID ) = 0;
//--------------------------------------------------------
// File name and directory operations
//--------------------------------------------------------
// FIXME: This method is obsolete! Use RelativePathToFullPath instead!
// converts a partial path into a full path
virtual const char *GetLocalPath( const char *pFileName, char *pLocalPath, int localPathBufferSize ) = 0;
// Returns true on success ( based on current list of search paths, otherwise false if
// it can't be resolved )
virtual bool FullPathToRelativePath( const char *pFullpath, char *pRelative, int maxlen ) = 0;
// Gets the current working directory
virtual bool GetCurrentDirectory( char* pDirectory, int maxlen ) = 0;
//--------------------------------------------------------
// Filename dictionary operations
//--------------------------------------------------------
virtual FileNameHandle_t FindOrAddFileName( char const *pFileName ) = 0;
virtual bool String( const FileNameHandle_t& handle, char *buf, int buflen ) = 0;
//--------------------------------------------------------
// Asynchronous file operations
//--------------------------------------------------------
//------------------------------------
// Global operations
//------------------------------------
FSAsyncStatus_t AsyncRead( const FileAsyncRequest_t &request, FSAsyncControl_t *phControl = NULL ) { return AsyncReadMultiple( &request, 1, phControl ); }
virtual FSAsyncStatus_t AsyncReadMultiple( const FileAsyncRequest_t *pRequests, int nRequests, FSAsyncControl_t *phControls = NULL ) = 0;
virtual FSAsyncStatus_t AsyncAppend(const char *pFileName, const void *pSrc, int nSrcBytes, bool bFreeMemory, FSAsyncControl_t *pControl = NULL ) = 0;
virtual FSAsyncStatus_t AsyncAppendFile(const char *pAppendToFileName, const char *pAppendFromFileName, FSAsyncControl_t *pControl = NULL ) = 0;
virtual void AsyncFinishAll( int iToPriority = 0 ) = 0;
virtual void AsyncFinishAllWrites() = 0;
virtual FSAsyncStatus_t AsyncFlush() = 0;
virtual bool AsyncSuspend() = 0;
virtual bool AsyncResume() = 0;
//------------------------------------
// Functions to hold a file open if planning on doing mutiple reads. Use is optional,
// and is taken only as a hint
//------------------------------------
virtual FSAsyncStatus_t AsyncBeginRead( const char *pszFile, FSAsyncFile_t *phFile ) = 0;
virtual FSAsyncStatus_t AsyncEndRead( FSAsyncFile_t hFile ) = 0;
//------------------------------------
// Request management
//------------------------------------
virtual FSAsyncStatus_t AsyncFinish( FSAsyncControl_t hControl, bool wait = true ) = 0;
virtual FSAsyncStatus_t AsyncGetResult( FSAsyncControl_t hControl, void **ppData, int *pSize ) = 0;
virtual FSAsyncStatus_t AsyncAbort( FSAsyncControl_t hControl ) = 0;
virtual FSAsyncStatus_t AsyncStatus( FSAsyncControl_t hControl ) = 0;
// set a new priority for a file already in the queue
virtual FSAsyncStatus_t AsyncSetPriority(FSAsyncControl_t hControl, int newPriority) = 0;
virtual void AsyncAddRef( FSAsyncControl_t hControl ) = 0;
virtual void AsyncRelease( FSAsyncControl_t hControl ) = 0;
//--------------------------------------------------------
// Remote resource management
//--------------------------------------------------------
// starts waiting for resources to be available
// returns FILESYSTEM_INVALID_HANDLE if there is nothing to wait on
virtual WaitForResourcesHandle_t WaitForResources( const char *resourcelist ) = 0;
// get progress on waiting for resources; progress is a float [0, 1], complete is true on the waiting being done
// returns false if no progress is available
// any calls after complete is true or on an invalid handle will return false, 0.0f, true
virtual bool GetWaitForResourcesProgress( WaitForResourcesHandle_t handle, float *progress /* out */ , bool *complete /* out */ ) = 0;
// cancels a progress call
virtual void CancelWaitForResources( WaitForResourcesHandle_t handle ) = 0;
// hints that a set of files will be loaded in near future
// HintResourceNeed() is not to be confused with resource precaching.
virtual int HintResourceNeed( const char *hintlist, int forgetEverything ) = 0;
// returns true if a file is on disk
virtual bool IsFileImmediatelyAvailable(const char *pFileName) = 0;
// copies file out of pak/bsp/steam cache onto disk (to be accessible by third-party code)
virtual void GetLocalCopy( const char *pFileName ) = 0;
//--------------------------------------------------------
// Debugging operations
//--------------------------------------------------------
// Dump to printf/OutputDebugString the list of files that have not been closed
virtual void PrintOpenedFiles( void ) = 0;
virtual void PrintSearchPaths( void ) = 0;
// output
virtual void SetWarningFunc( void (*pfnWarning)( const char *fmt, ... ) ) = 0;
virtual void SetWarningLevel( FileWarningLevel_t level ) = 0;
virtual void AddLoggingFunc( void (*pfnLogFunc)( const char *fileName, const char *accessType ) ) = 0;
virtual void RemoveLoggingFunc( FileSystemLoggingFunc_t logFunc ) = 0;
// Returns the file system statistics retreived by the implementation. Returns NULL if not supported.
virtual const FileSystemStatistics *GetFilesystemStatistics() = 0;
#if defined( _PS3 )
// EA cruft not used: virtual Ps3FileType_t GetPs3FileType(const char* path) = 0;
virtual void LogFileAccess( const char *pFullFileName ) = 0;
// Prefetches a full file in the HDD cache.
virtual bool PrefetchFile( const char *pFileName, int nPriority, bool bPersist ) = 0;
// Prefetches a file portion in the HDD cache.
virtual bool PrefetchFile( const char *pFileName, int nPriority, bool bPersist, int64 nOffset, int64 nSize ) = 0;
// Flushes the HDD cache.
virtual void FlushCache() = 0;
// Suspends all prefetches (like when the game is doing a file intensive operation not controlled by the HDD cache, like Bink movies).
virtual void SuspendPrefetches( const char *pWhy ) = 0;
// Resumes prefetches. This function has to to be called as many time as SuspendPrefetches() to effectively resumes prefetches.
virtual void ResumePrefetches( const char * pWhy ) = 0;
// Gets called when we are starting / ending a save (it allows the file system to reduce its HDD usage and use BluRay instead).
virtual void OnSaveStateChanged( bool bSaving ) = 0;
// Returns the prefetching state. If true, everything has been prefetched on the HDD.
virtual bool IsPrefetchingDone() = 0;
#endif //_PS3
//--------------------------------------------------------
// Start of new functions after Lost Coast release (7/05)
//--------------------------------------------------------
virtual FileHandle_t OpenEx( const char *pFileName, const char *pOptions, unsigned flags = 0, const char *pathID = 0, char **ppszResolvedFilename = NULL ) = 0;
// Extended version of read provides more context to allow for more optimal reading
virtual int ReadEx( void* pOutput, int sizeDest, int size, FileHandle_t file ) = 0;
virtual int ReadFileEx( const char *pFileName, const char *pPath, void **ppBuf, bool bNullTerminate = false, bool bOptimalAlloc = false, int nMaxBytes = 0, int nStartingByte = 0, FSAllocFunc_t pfnAlloc = NULL ) = 0;
virtual FileNameHandle_t FindFileName( char const *pFileName ) = 0;
#if defined( TRACK_BLOCKING_IO )
virtual void EnableBlockingFileAccessTracking( bool state ) = 0;
virtual bool IsBlockingFileAccessEnabled() const = 0;
virtual IBlockingFileItemList *RetrieveBlockingFileAccessInfo() = 0;
#endif
virtual void SetupPreloadData() = 0;
virtual void DiscardPreloadData() = 0;
// Fixme, we could do these via a string embedded into the compiled data, etc...
enum KeyValuesPreloadType_t
{
TYPE_VMT,
TYPE_SOUNDEMITTER,
TYPE_SOUNDSCAPE,
TYPE_SOUNDOPERATORS,
NUM_PRELOAD_TYPES
};
// If the "PreloadedData" hasn't been purged, then this'll try and instance the KeyValues using the fast path of compiled keyvalues loaded during startup.
// Otherwise, it'll just fall through to the regular KeyValues loading routines
virtual KeyValues *LoadKeyValues( KeyValuesPreloadType_t type, char const *filename, char const *pPathID = 0 ) = 0;
virtual bool LoadKeyValues( KeyValues& head, KeyValuesPreloadType_t type, char const *filename, char const *pPathID = 0 ) = 0;
virtual FSAsyncStatus_t AsyncWrite(const char *pFileName, const void *pSrc, int nSrcBytes, bool bFreeMemory, bool bAppend = false, FSAsyncControl_t *pControl = NULL ) = 0;
virtual FSAsyncStatus_t AsyncWriteFile(const char *pFileName, const CUtlBuffer *pSrc, int nSrcBytes, bool bFreeMemory, bool bAppend = false, FSAsyncControl_t *pControl = NULL ) = 0;
// Async read functions with memory blame
FSAsyncStatus_t AsyncReadCreditAlloc( const FileAsyncRequest_t &request, const char *pszFile, int line, FSAsyncControl_t *phControl = NULL ) { return AsyncReadMultipleCreditAlloc( &request, 1, pszFile, line, phControl ); }
virtual FSAsyncStatus_t AsyncReadMultipleCreditAlloc( const FileAsyncRequest_t *pRequests, int nRequests, const char *pszFile, int line, FSAsyncControl_t *phControls = NULL ) = 0;
virtual FSAsyncStatus_t AsyncDirectoryScan( const char* pSearchSpec, bool recurseFolders, void* pContext, FSAsyncScanAddFunc_t pfnAdd, FSAsyncScanCompleteFunc_t pfnDone, FSAsyncControl_t *pControl = NULL ) = 0;
virtual bool GetFileTypeForFullPath( char const *pFullPath, wchar_t *buf, size_t bufSizeInBytes ) = 0;
//--------------------------------------------------------
//--------------------------------------------------------
virtual bool ReadToBuffer( FileHandle_t hFile, CUtlBuffer &buf, int nMaxBytes = 0, FSAllocFunc_t pfnAlloc = NULL ) = 0;
//--------------------------------------------------------
// Optimal IO operations
//--------------------------------------------------------
virtual bool GetOptimalIOConstraints( FileHandle_t hFile, unsigned *pOffsetAlign, unsigned *pSizeAlign, unsigned *pBufferAlign ) = 0;
inline unsigned GetOptimalReadSize( FileHandle_t hFile, unsigned nLogicalSize );
virtual void *AllocOptimalReadBuffer( FileHandle_t hFile, unsigned nSize = 0, unsigned nOffset = 0 ) = 0;
virtual void FreeOptimalReadBuffer( void * ) = 0;
//--------------------------------------------------------
//
//--------------------------------------------------------
virtual void BeginMapAccess() = 0;
virtual void EndMapAccess() = 0;
// Returns true on success, otherwise false if it can't be resolved
virtual bool FullPathToRelativePathEx( const char *pFullpath, const char *pPathId, char *pRelative, int maxlen ) = 0;
virtual int GetPathIndex( const FileNameHandle_t &handle ) = 0;
virtual long GetPathTime( const char *pPath, const char *pPathID ) = 0;
virtual DVDMode_t GetDVDMode() = 0;
//--------------------------------------------------------
// Whitelisting for pure servers.
//--------------------------------------------------------
// This should be called ONCE at startup. Multiplayer games (gameinfo.txt does not contain singleplayer_only)
// want to enable this so sv_pure works.
virtual void EnableWhitelistFileTracking( bool bEnable ) = 0;
// This is called when the client connects to a server using a pure_server_whitelist.txt file.
//
// Files listed in pWantCRCList will have CRCs calculated for them IF they come off disk
// (and those CRCs will come out of GetUnverifiedCRCFiles).
//
// Files listed in pAllowFromDiskList will be allowed to load from disk. All other files will
// be forced to come from Steam.
//
// The filesystem hangs onto the whitelists you pass in here, and it will Release() them when it closes down
// or when you call this function again.
//
// NOTE: The whitelists you pass in here will be accessed from multiple threads, so make sure the
// IsFileInList function is thread safe.
//
// If pFilesToReload is non-null, the filesystem will hand back a list of files that should be reloaded because they
// are now "dirty". For example, if you were on a non-pure server and you loaded a certain model, and then you connected
// to a pure server that said that model had to come from Steam, then pFilesToReload would specify that model
// and the engine should reload it so it can come from Steam.
//
// Be sure to call Release() on pFilesToReload.
virtual void RegisterFileWhitelist( IFileList *pWantCRCList, IFileList *pAllowFromDiskList, IFileList **pFilesToReload ) = 0;
// Called when the client logs onto a server. Any files that came off disk should be marked as
// unverified because this server may have a different set of files it wants to guarantee.
virtual void MarkAllCRCsUnverified() = 0;
// As the server loads whitelists when it transitions maps, it calls this to calculate CRCs for any files marked
// with check_crc. Then it calls CheckCachedFileCRC later when it gets client requests to verify CRCs.
virtual void CacheFileCRCs( const char *pPathname, ECacheCRCType eType, IFileList *pFilter ) = 0;
virtual EFileCRCStatus CheckCachedFileCRC( const char *pPathID, const char *pRelativeFilename, CRC32_t *pCRC ) = 0;
// Fills in the list of files that have been loaded off disk and have not been verified.
// Returns the number of files filled in (between 0 and nMaxFiles).
//
// This also removes any files it's returning from the unverified CRC list, so they won't be
// returned from here again.
// The client sends batches of these to the server to verify.
virtual int GetUnverifiedCRCFiles( CUnverifiedCRCFile *pFiles, int nMaxFiles ) = 0;
// Control debug message output.
// Pass a combination of WHITELIST_SPEW_ flags.
virtual int GetWhitelistSpewFlags() = 0;
virtual void SetWhitelistSpewFlags( int flags ) = 0;
// Installs a callback used to display a dirty disk dialog
virtual void InstallDirtyDiskReportFunc( FSDirtyDiskReportFunc_t func ) = 0;
virtual bool IsLaunchedFromXboxHDD() = 0;
virtual bool IsInstalledToXboxHDDCache() = 0;
virtual bool IsDVDHosted() = 0;
virtual bool IsInstallAllowed() = 0;
virtual int GetSearchPathID( char *pPath, int nMaxLen ) = 0;
virtual bool FixupSearchPathsAfterInstall() = 0;
virtual FSDirtyDiskReportFunc_t GetDirtyDiskReportFunc() = 0;
virtual void AddVPKFile( char const *pszName, SearchPathAdd_t addType = PATH_ADD_TO_TAIL ) = 0;
virtual void RemoveVPKFile( char const *pszName ) = 0;
virtual void GetVPKFileNames( CUtlVector<CUtlString> &destVector ) = 0;
virtual void RemoveAllMapSearchPaths() = 0;
virtual void SyncDvdDevCache() = 0;
virtual bool GetStringFromKVPool( CRC32_t poolKey, unsigned int key, char *pOutBuff, int buflen ) = 0;
virtual bool DiscoverDLC( int iController ) = 0;
virtual int IsAnyDLCPresent( bool *pbDLCSearchPathMounted = NULL ) = 0;
virtual bool GetAnyDLCInfo( int iDLC, unsigned int *pLicenseMask, wchar_t *pTitleBuff, int nOutTitleSize ) = 0;
virtual int IsAnyCorruptDLC() = 0;
virtual bool GetAnyCorruptDLCInfo( int iCorruptDLC, wchar_t *pTitleBuff, int nOutTitleSize ) = 0;
virtual bool AddDLCSearchPaths() = 0;
virtual bool IsSpecificDLCPresent( unsigned int nDLCPackage ) = 0;
// call this to look for CPU-hogs during loading processes. When you set this, a breakpoint
// will be issued whenever the indicated # of seconds go by without an i/o request. Passing
// 0.0 will turn off the functionality.
virtual void SetIODelayAlarm( float flThreshhold ) = 0;
virtual bool AddXLSPUpdateSearchPath( const void *pData, int nSize ) = 0;
virtual IIoStats *GetIoStats() = 0;
};
//-----------------------------------------------------------------------------
#if defined( _X360 ) && !defined( _CERT )
extern char g_szXboxProfileLastFileOpened[MAX_PATH];
#define SetLastProfileFileRead( s ) V_strncpy( g_szXboxProfileLastFileOpened, sizeof( g_szXboxProfileLastFileOpened), pFileName )
#define GetLastProfileFileRead() (&g_szXboxProfileLastFileOpened[0])
#else
#define SetLastProfileFileRead( s ) ((void)0)
#define GetLastProfileFileRead() NULL
#endif
#if defined( _X360 ) && defined( _BASETSD_H_ )
class CXboxDiskCacheSetter
{
public:
CXboxDiskCacheSetter( SIZE_T newSize )
{
m_oldSize = XGetFileCacheSize();
XSetFileCacheSize( newSize );
}
~CXboxDiskCacheSetter()
{
XSetFileCacheSize( m_oldSize );
}
private:
SIZE_T m_oldSize;
};
#define DISK_INTENSIVE() CXboxDiskCacheSetter cacheSetter( 1024*1024 )
#else
#define DISK_INTENSIVE() ((void)0)
#endif
//-----------------------------------------------------------------------------
inline unsigned IFileSystem::GetOptimalReadSize( FileHandle_t hFile, unsigned nLogicalSize )
{
unsigned align;
if ( GetOptimalIOConstraints( hFile, &align, NULL, NULL ) )
return AlignValue( nLogicalSize, align );
else
return nLogicalSize;
}
//-----------------------------------------------------------------------------
// We include this here so it'll catch compile errors in VMPI early.
#include "filesystem_passthru.h"
//-----------------------------------------------------------------------------
// Async memory tracking
//-----------------------------------------------------------------------------
#if (defined(_DEBUG) || defined(USE_MEM_DEBUG))
#define AsyncRead( a, b ) AsyncReadCreditAlloc( a, __FILE__, __LINE__, b )
#define AsyncReadMutiple( a, b, c ) AsyncReadMultipleCreditAlloc( a, b, __FILE__, __LINE__, c )
#endif
//-----------------------------------------------------------------------------
// Globals Exposed
//-----------------------------------------------------------------------------
DECLARE_TIER2_INTERFACE( IFileSystem, g_pFullFileSystem );
#endif // FILESYSTEM_H

View File

@@ -0,0 +1,299 @@
//========= Copyright (c) 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================//
#ifndef FILESYSTEM_PASSTHRU_H
#define FILESYSTEM_PASSTHRU_H
#ifdef _WIN32
#pragma once
#endif
#include "filesystem.h"
#include <stdio.h>
#include <stdarg.h>
#ifdef AsyncRead
#undef AsyncRead
#undef AsyncReadMutiple
#endif
//
// These classes pass all filesystem interface calls through to another filesystem
// interface. They can be used anytime you want to override a couple things in
// a filesystem. VMPI uses this to override the base filesystem calls while
// allowing the rest of the filesystem functionality to work on the master.
//
template<class Base>
class CInternalFileSystemPassThru : public Base
{
public:
CInternalFileSystemPassThru()
{
m_pBaseFileSystemPassThru = NULL;
}
virtual void InitPassThru( IBaseFileSystem *pBaseFileSystemPassThru )
{
m_pBaseFileSystemPassThru = pBaseFileSystemPassThru;
}
virtual int Read( void* pOutput, int size, FileHandle_t file ) { return m_pBaseFileSystemPassThru->Read( pOutput, size, file ); }
virtual int Write( void const* pInput, int size, FileHandle_t file ) { return m_pBaseFileSystemPassThru->Write( pInput, size, file ); }
virtual FileHandle_t Open( const char *pFileName, const char *pOptions, const char *pathID ) { return m_pBaseFileSystemPassThru->Open( pFileName, pOptions, pathID ); }
virtual void Close( FileHandle_t file ) { m_pBaseFileSystemPassThru->Close( file ); }
virtual void Seek( FileHandle_t file, int pos, FileSystemSeek_t seekType ) { m_pBaseFileSystemPassThru->Seek( file, pos, seekType ); }
virtual unsigned int Tell( FileHandle_t file ) { return m_pBaseFileSystemPassThru->Tell( file ); }
virtual unsigned int Size( FileHandle_t file ) { return m_pBaseFileSystemPassThru->Size( file ); }
virtual unsigned int Size( const char *pFileName, const char *pPathID ) { return m_pBaseFileSystemPassThru->Size( pFileName, pPathID ); }
virtual void Flush( FileHandle_t file ) { m_pBaseFileSystemPassThru->Flush( file ); }
virtual bool Precache( const char *pFileName, const char *pPathID ) { return m_pBaseFileSystemPassThru->Precache( pFileName, pPathID ); }
virtual bool FileExists( const char *pFileName, const char *pPathID ) { return m_pBaseFileSystemPassThru->FileExists( pFileName, pPathID ); }
virtual bool IsFileWritable( char const *pFileName, const char *pPathID ) { return m_pBaseFileSystemPassThru->IsFileWritable( pFileName, pPathID ); }
virtual bool SetFileWritable( char const *pFileName, bool writable, const char *pPathID ) { return m_pBaseFileSystemPassThru->SetFileWritable( pFileName, writable, pPathID ); }
virtual long GetFileTime( const char *pFileName, const char *pPathID ) { return m_pBaseFileSystemPassThru->GetFileTime( pFileName, pPathID ); }
virtual bool ReadFile( const char *pFileName, const char *pPath, CUtlBuffer &buf, int nMaxBytes = 0, int nStartingByte = 0, FSAllocFunc_t pfnAlloc = NULL ) { return m_pBaseFileSystemPassThru->ReadFile( pFileName, pPath, buf, nMaxBytes, nStartingByte, pfnAlloc ); }
virtual bool WriteFile( const char *pFileName, const char *pPath, CUtlBuffer &buf ) { return m_pBaseFileSystemPassThru->WriteFile( pFileName, pPath, buf ); }
virtual bool UnzipFile( const char *pFileName, const char *pPath, const char *pDestination ) { return m_pBaseFileSystemPassThru->UnzipFile( pFileName, pPath, pDestination ); }
protected:
IBaseFileSystem *m_pBaseFileSystemPassThru;
};
class CBaseFileSystemPassThru : public CInternalFileSystemPassThru<IBaseFileSystem>
{
public:
};
class CFileSystemPassThru : public CInternalFileSystemPassThru<IFileSystem>
{
public:
typedef CInternalFileSystemPassThru<IFileSystem> BaseClass;
CFileSystemPassThru()
{
m_pFileSystemPassThru = NULL;
}
virtual void InitPassThru( IFileSystem *pFileSystemPassThru, bool bBaseOnly )
{
if ( !bBaseOnly )
m_pFileSystemPassThru = pFileSystemPassThru;
BaseClass::InitPassThru( pFileSystemPassThru );
}
// IAppSystem stuff.
// Here's where the app systems get to learn about each other
virtual bool Connect( CreateInterfaceFn factory ) { return m_pFileSystemPassThru->Connect( factory ); }
virtual void Disconnect() { m_pFileSystemPassThru->Disconnect(); }
virtual void *QueryInterface( const char *pInterfaceName ) { return m_pFileSystemPassThru->QueryInterface( pInterfaceName ); }
virtual InitReturnVal_t Init() { return m_pFileSystemPassThru->Init(); }
virtual void Shutdown() { m_pFileSystemPassThru->Shutdown(); }
virtual const AppSystemInfo_t* GetDependencies() { return m_pFileSystemPassThru->GetDependencies(); }
virtual AppSystemTier_t GetTier() { return m_pFileSystemPassThru->GetTier(); }
virtual void Reconnect( CreateInterfaceFn factory, const char *pInterfaceName ) { m_pFileSystemPassThru->Reconnect( factory, pInterfaceName ); }
virtual void RemoveAllSearchPaths( void ) { m_pFileSystemPassThru->RemoveAllSearchPaths(); }
virtual void AddSearchPath( const char *pPath, const char *pathID, SearchPathAdd_t addType ) { m_pFileSystemPassThru->AddSearchPath( pPath, pathID, addType ); }
virtual bool RemoveSearchPath( const char *pPath, const char *pathID ) { return m_pFileSystemPassThru->RemoveSearchPath( pPath, pathID ); }
virtual void RemoveFile( char const* pRelativePath, const char *pathID ) { m_pFileSystemPassThru->RemoveFile( pRelativePath, pathID ); }
virtual bool RenameFile( char const *pOldPath, char const *pNewPath, const char *pathID ) { return m_pFileSystemPassThru->RenameFile( pOldPath, pNewPath, pathID ); }
virtual void CreateDirHierarchy( const char *path, const char *pathID ) { m_pFileSystemPassThru->CreateDirHierarchy( path, pathID ); }
virtual bool IsDirectory( const char *pFileName, const char *pathID ) { return m_pFileSystemPassThru->IsDirectory( pFileName, pathID ); }
virtual void FileTimeToString( char* pStrip, int maxCharsIncludingTerminator, long fileTime ) { m_pFileSystemPassThru->FileTimeToString( pStrip, maxCharsIncludingTerminator, fileTime ); }
virtual void SetBufferSize( FileHandle_t file, unsigned nBytes ) { m_pFileSystemPassThru->SetBufferSize( file, nBytes ); }
virtual bool IsOk( FileHandle_t file ) { return m_pFileSystemPassThru->IsOk( file ); }
virtual bool EndOfFile( FileHandle_t file ) { return m_pFileSystemPassThru->EndOfFile( file ); }
virtual char *ReadLine( char *pOutput, int maxChars, FileHandle_t file ) { return m_pFileSystemPassThru->ReadLine( pOutput, maxChars, file ); }
virtual int FPrintf( FileHandle_t file, const char *pFormat, ... )
{
char str[8192];
va_list marker;
va_start( marker, pFormat );
_vsnprintf( str, sizeof( str ), pFormat, marker );
va_end( marker );
return m_pFileSystemPassThru->FPrintf( file, "%s", str );
}
virtual CSysModule *LoadModule( const char *pFileName, const char *pPathID, bool bValidatedDllOnly ) { return m_pFileSystemPassThru->LoadModule( pFileName, pPathID, bValidatedDllOnly ); }
virtual void UnloadModule( CSysModule *pModule ) { m_pFileSystemPassThru->UnloadModule( pModule ); }
virtual const char *FindFirst( const char *pWildCard, FileFindHandle_t *pHandle ) { return m_pFileSystemPassThru->FindFirst( pWildCard, pHandle ); }
virtual const char *FindNext( FileFindHandle_t handle ) { return m_pFileSystemPassThru->FindNext( handle ); }
virtual bool FindIsDirectory( FileFindHandle_t handle ) { return m_pFileSystemPassThru->FindIsDirectory( handle ); }
virtual void FindClose( FileFindHandle_t handle ) { m_pFileSystemPassThru->FindClose( handle ); }
virtual void FindFileAbsoluteList( CUtlVector< CUtlString > &outAbsolutePathNames, const char *pWildCard, const char *pPathID ) { m_pFileSystemPassThru->FindFileAbsoluteList( outAbsolutePathNames, pWildCard, pPathID ); }
virtual const char *GetLocalPath( const char *pFileName, char *pLocalPath, int localPathBufferSize ) { return m_pFileSystemPassThru->GetLocalPath( pFileName, pLocalPath, localPathBufferSize ); }
virtual bool FullPathToRelativePath( const char *pFullpath, char *pRelative, int maxlen ) { return m_pFileSystemPassThru->FullPathToRelativePath( pFullpath, pRelative, maxlen ); }
virtual bool GetCurrentDirectory( char* pDirectory, int maxlen ) { return m_pFileSystemPassThru->GetCurrentDirectory( pDirectory, maxlen ); }
virtual void PrintOpenedFiles( void ) { m_pFileSystemPassThru->PrintOpenedFiles(); }
virtual void PrintSearchPaths( void ) { m_pFileSystemPassThru->PrintSearchPaths(); }
virtual void SetWarningFunc( void (*pfnWarning)( const char *fmt, ... ) ) { m_pFileSystemPassThru->SetWarningFunc( pfnWarning ); }
virtual void SetWarningLevel( FileWarningLevel_t level ) { m_pFileSystemPassThru->SetWarningLevel( level ); }
virtual void AddLoggingFunc( void (*pfnLogFunc)( const char *fileName, const char *accessType ) ){ m_pFileSystemPassThru->AddLoggingFunc( pfnLogFunc ); }
virtual void RemoveLoggingFunc( FileSystemLoggingFunc_t logFunc ) { m_pFileSystemPassThru->RemoveLoggingFunc( logFunc ); }
virtual FSAsyncStatus_t AsyncReadMultiple( const FileAsyncRequest_t *pRequests, int nRequests, FSAsyncControl_t *pControls ) { return m_pFileSystemPassThru->AsyncReadMultiple( pRequests, nRequests, pControls ); }
virtual FSAsyncStatus_t AsyncReadMultipleCreditAlloc( const FileAsyncRequest_t *pRequests, int nRequests, const char *pszFile, int line, FSAsyncControl_t *pControls ) { return m_pFileSystemPassThru->AsyncReadMultipleCreditAlloc( pRequests, nRequests, pszFile, line, pControls ); }
virtual FSAsyncStatus_t AsyncDirectoryScan( const char* pSearchSpec, bool recurseFolders, void* pContext, FSAsyncScanAddFunc_t pfnAdd, FSAsyncScanCompleteFunc_t pfnDone, FSAsyncControl_t *pControl = NULL ) { return m_pFileSystemPassThru->AsyncDirectoryScan( pSearchSpec, recurseFolders, pContext, pfnAdd, pfnDone, pControl ); }
virtual FSAsyncStatus_t AsyncFinish(FSAsyncControl_t hControl, bool wait) { return m_pFileSystemPassThru->AsyncFinish( hControl, wait ); }
virtual FSAsyncStatus_t AsyncGetResult( FSAsyncControl_t hControl, void **ppData, int *pSize ) { return m_pFileSystemPassThru->AsyncGetResult( hControl, ppData, pSize ); }
virtual FSAsyncStatus_t AsyncAbort(FSAsyncControl_t hControl) { return m_pFileSystemPassThru->AsyncAbort( hControl ); }
virtual FSAsyncStatus_t AsyncStatus(FSAsyncControl_t hControl) { return m_pFileSystemPassThru->AsyncStatus( hControl ); }
virtual FSAsyncStatus_t AsyncFlush() { return m_pFileSystemPassThru->AsyncFlush(); }
virtual void AsyncAddRef( FSAsyncControl_t hControl ) { m_pFileSystemPassThru->AsyncAddRef( hControl ); }
virtual void AsyncRelease( FSAsyncControl_t hControl ) { m_pFileSystemPassThru->AsyncRelease( hControl ); }
virtual FSAsyncStatus_t AsyncBeginRead( const char *pszFile, FSAsyncFile_t *phFile ) { return m_pFileSystemPassThru->AsyncBeginRead( pszFile, phFile ); }
virtual FSAsyncStatus_t AsyncEndRead( FSAsyncFile_t hFile ) { return m_pFileSystemPassThru->AsyncEndRead( hFile ); }
virtual const FileSystemStatistics *GetFilesystemStatistics() { return m_pFileSystemPassThru->GetFilesystemStatistics(); }
#if defined( _PS3 )
// These should never be called on PS3!
virtual Ps3FileType_t GetPs3FileType(const char* path) { return PS3_FILETYPE_UNKNOWN; }
virtual void LogFileAccess( const char *pFullFileName ) { }
virtual bool PrefetchFile( const char *pFileName, int nPriority, bool bPersist ) { return m_pFileSystemPassThru->PrefetchFile( pFileName, nPriority, bPersist ); }
virtual bool PrefetchFile( const char *pFileName, int nPriority, bool bPersist, int64 nOffset, int64 nSize ) { return m_pFileSystemPassThru->PrefetchFile( pFileName, nPriority, bPersist, nOffset, nSize ); }
virtual void FlushCache() { m_pFileSystemPassThru->FlushCache(); }
virtual void SuspendPrefetches( const char * pWhy ) { m_pFileSystemPassThru->SuspendPrefetches( pWhy ); }
virtual void ResumePrefetches( const char * pWhy ) { m_pFileSystemPassThru->ResumePrefetches( pWhy ); }
virtual void OnSaveStateChanged( bool bSaving ) { m_pFileSystemPassThru->OnSaveStateChanged( bSaving ); }
virtual bool IsPrefetchingDone( ) { return m_pFileSystemPassThru->IsPrefetchingDone(); }
#endif //_PS3
virtual WaitForResourcesHandle_t WaitForResources( const char *resourcelist ) { return m_pFileSystemPassThru->WaitForResources( resourcelist ); }
virtual bool GetWaitForResourcesProgress( WaitForResourcesHandle_t handle,
float *progress, bool *complete ) { return m_pFileSystemPassThru->GetWaitForResourcesProgress( handle, progress, complete ); }
virtual void CancelWaitForResources( WaitForResourcesHandle_t handle ) { m_pFileSystemPassThru->CancelWaitForResources( handle ); }
virtual int HintResourceNeed( const char *hintlist, int forgetEverything ) { return m_pFileSystemPassThru->HintResourceNeed( hintlist, forgetEverything ); }
virtual bool IsFileImmediatelyAvailable(const char *pFileName) { return m_pFileSystemPassThru->IsFileImmediatelyAvailable( pFileName ); }
virtual void GetLocalCopy( const char *pFileName ) { m_pFileSystemPassThru->GetLocalCopy( pFileName ); }
virtual FileNameHandle_t FindOrAddFileName( char const *pFileName ) { return m_pFileSystemPassThru->FindOrAddFileName( pFileName ); }
virtual FileNameHandle_t FindFileName( char const *pFileName ) { return m_pFileSystemPassThru->FindFileName( pFileName ); }
virtual bool String( const FileNameHandle_t& handle, char *buf, int buflen ) { return m_pFileSystemPassThru->String( handle, buf, buflen ); }
virtual bool IsOk2( FileHandle_t file ) { return IsOk(file); }
virtual void RemoveSearchPaths( const char *szPathID ) { m_pFileSystemPassThru->RemoveSearchPaths( szPathID ); }
virtual bool IsSteam() const { return m_pFileSystemPassThru->IsSteam(); }
virtual FilesystemMountRetval_t MountSteamContent( int nExtraAppId = -1 ) { return m_pFileSystemPassThru->MountSteamContent( nExtraAppId ); }
virtual const char *FindFirstEx(
const char *pWildCard,
const char *pPathID,
FileFindHandle_t *pHandle
) { return m_pFileSystemPassThru->FindFirstEx( pWildCard, pPathID, pHandle ); }
virtual void MarkPathIDByRequestOnly( const char *pPathID, bool bRequestOnly ) { m_pFileSystemPassThru->MarkPathIDByRequestOnly( pPathID, bRequestOnly ); }
virtual bool AddPackFile( const char *fullpath, const char *pathID ) { return m_pFileSystemPassThru->AddPackFile( fullpath, pathID ); }
virtual FSAsyncStatus_t AsyncAppend(const char *pFileName, const void *pSrc, int nSrcBytes, bool bFreeMemory, FSAsyncControl_t *pControl ) { return m_pFileSystemPassThru->AsyncAppend( pFileName, pSrc, nSrcBytes, bFreeMemory, pControl); }
virtual FSAsyncStatus_t AsyncWrite(const char *pFileName, const void *pSrc, int nSrcBytes, bool bFreeMemory, bool bAppend, FSAsyncControl_t *pControl ) { return m_pFileSystemPassThru->AsyncWrite( pFileName, pSrc, nSrcBytes, bFreeMemory, bAppend, pControl); }
virtual FSAsyncStatus_t AsyncWriteFile(const char *pFileName, const CUtlBuffer *pSrc, int nSrcBytes, bool bFreeMemory, bool bAppend, FSAsyncControl_t *pControl ) { return m_pFileSystemPassThru->AsyncWriteFile( pFileName, pSrc, nSrcBytes, bFreeMemory, bAppend, pControl); }
virtual FSAsyncStatus_t AsyncAppendFile(const char *pDestFileName, const char *pSrcFileName, FSAsyncControl_t *pControl ) { return m_pFileSystemPassThru->AsyncAppendFile(pDestFileName, pSrcFileName, pControl); }
virtual void AsyncFinishAll( int iToPriority ) { m_pFileSystemPassThru->AsyncFinishAll(iToPriority); }
virtual void AsyncFinishAllWrites() { m_pFileSystemPassThru->AsyncFinishAllWrites(); }
virtual FSAsyncStatus_t AsyncSetPriority(FSAsyncControl_t hControl, int newPriority) { return m_pFileSystemPassThru->AsyncSetPriority(hControl, newPriority); }
virtual bool AsyncSuspend() { return m_pFileSystemPassThru->AsyncSuspend(); }
virtual bool AsyncResume() { return m_pFileSystemPassThru->AsyncResume(); }
virtual const char *RelativePathToFullPath( const char *pFileName, const char *pPathID, char *pLocalPath, int localPathBufferSize, PathTypeFilter_t pathFilter = FILTER_NONE, PathTypeQuery_t *pPathType = NULL ) { return m_pFileSystemPassThru->RelativePathToFullPath( pFileName, pPathID, pLocalPath, localPathBufferSize, pathFilter, pPathType ); }
#if IsGameConsole()
// Given a relative path, gets the PACK file that contained this file and its offset and size. Can be used to prefetch a file to a HDD for caching reason.
virtual bool GetPackFileInfoFromRelativePath( const char *pFileName, const char * pPathID, char *pPackPath, int nPackPathBufferSize, int64 &nPosition, int64 &nLength ) { return m_pFileSystemPassThru->GetPackFileInfoFromRelativePath( pFileName, pPathID, pPackPath, nPackPathBufferSize, nPosition, nLength ); }
#endif
virtual int GetSearchPath( const char *pathID, bool bGetPackFiles, char *pPath, int nMaxLen ) { return m_pFileSystemPassThru->GetSearchPath( pathID, bGetPackFiles, pPath, nMaxLen ); }
virtual FileHandle_t OpenEx( const char *pFileName, const char *pOptions, unsigned flags = 0, const char *pathID = 0, char **ppszResolvedFilename = NULL ) { return m_pFileSystemPassThru->OpenEx( pFileName, pOptions, flags, pathID, ppszResolvedFilename );}
virtual int ReadEx( void* pOutput, int destSize, int size, FileHandle_t file ) { return m_pFileSystemPassThru->ReadEx( pOutput, destSize, size, file ); }
virtual int ReadFileEx( const char *pFileName, const char *pPath, void **ppBuf, bool bNullTerminate, bool bOptimalAlloc, int nMaxBytes = 0, int nStartingByte = 0, FSAllocFunc_t pfnAlloc = NULL ) { return m_pFileSystemPassThru->ReadFileEx( pFileName, pPath, ppBuf, bNullTerminate, bOptimalAlloc, nMaxBytes, nStartingByte, pfnAlloc ); }
#if defined( TRACK_BLOCKING_IO )
virtual void EnableBlockingFileAccessTracking( bool state ) { m_pFileSystemPassThru->EnableBlockingFileAccessTracking( state ); }
virtual bool IsBlockingFileAccessEnabled() const { return m_pFileSystemPassThru->IsBlockingFileAccessEnabled(); }
virtual IBlockingFileItemList *RetrieveBlockingFileAccessInfo() { return m_pFileSystemPassThru->RetrieveBlockingFileAccessInfo(); }
#endif
virtual void SetupPreloadData() {}
virtual void DiscardPreloadData() {}
// If the "PreloadedData" hasn't been purged, then this'll try and instance the KeyValues using the fast path of compiled keyvalues loaded during startup.
// Otherwise, it'll just fall through to the regular KeyValues loading routines
virtual KeyValues *LoadKeyValues( KeyValuesPreloadType_t type, char const *filename, char const *pPathID = 0 ) { return m_pFileSystemPassThru->LoadKeyValues( type, filename, pPathID ); }
virtual bool LoadKeyValues( KeyValues& head, KeyValuesPreloadType_t type, char const *filename, char const *pPathID = 0 ) { return m_pFileSystemPassThru->LoadKeyValues( head, type, filename, pPathID ); }
virtual bool GetFileTypeForFullPath( char const *pFullPath, wchar_t *buf, size_t bufSizeInBytes ) { return m_pFileSystemPassThru->GetFileTypeForFullPath( pFullPath, buf, bufSizeInBytes ); }
virtual bool GetOptimalIOConstraints( FileHandle_t hFile, unsigned *pOffsetAlign, unsigned *pSizeAlign, unsigned *pBufferAlign ) { return m_pFileSystemPassThru->GetOptimalIOConstraints( hFile, pOffsetAlign, pSizeAlign, pBufferAlign ); }
virtual void *AllocOptimalReadBuffer( FileHandle_t hFile, unsigned nSize, unsigned nOffset ) { return m_pFileSystemPassThru->AllocOptimalReadBuffer( hFile, nOffset, nSize ); }
virtual void FreeOptimalReadBuffer( void *p ) { m_pFileSystemPassThru->FreeOptimalReadBuffer( p ); }
virtual void BeginMapAccess() { m_pFileSystemPassThru->BeginMapAccess(); }
virtual void EndMapAccess() { m_pFileSystemPassThru->EndMapAccess(); }
virtual bool ReadToBuffer( FileHandle_t hFile, CUtlBuffer &buf, int nMaxBytes = 0, FSAllocFunc_t pfnAlloc = NULL ) { return m_pFileSystemPassThru->ReadToBuffer( hFile, buf, nMaxBytes, pfnAlloc ); }
virtual bool FullPathToRelativePathEx( const char *pFullPath, const char *pPathId, char *pRelative, int nMaxLen ) { return m_pFileSystemPassThru->FullPathToRelativePathEx( pFullPath, pPathId, pRelative, nMaxLen ); }
virtual int GetPathIndex( const FileNameHandle_t &handle ) { return m_pFileSystemPassThru->GetPathIndex( handle ); }
virtual long GetPathTime( const char *pPath, const char *pPathID ) { return m_pFileSystemPassThru->GetPathTime( pPath, pPathID ); }
virtual DVDMode_t GetDVDMode() { return m_pFileSystemPassThru->GetDVDMode(); }
virtual void EnableWhitelistFileTracking( bool bEnable )
{ m_pFileSystemPassThru->EnableWhitelistFileTracking( bEnable ); }
virtual void RegisterFileWhitelist( IFileList *pForceMatchList, IFileList *pAllowFromDiskList, IFileList **pFilesToReload )
{ m_pFileSystemPassThru->RegisterFileWhitelist( pForceMatchList, pAllowFromDiskList, pFilesToReload ); }
virtual void MarkAllCRCsUnverified()
{ m_pFileSystemPassThru->MarkAllCRCsUnverified(); }
virtual void CacheFileCRCs( const char *pPathname, ECacheCRCType eType, IFileList *pFilter )
{ return m_pFileSystemPassThru->CacheFileCRCs( pPathname, eType, pFilter ); }
virtual EFileCRCStatus CheckCachedFileCRC( const char *pPathID, const char *pRelativeFilename, CRC32_t *pCRC )
{ return m_pFileSystemPassThru->CheckCachedFileCRC( pPathID, pRelativeFilename, pCRC ); }
virtual int GetUnverifiedCRCFiles( CUnverifiedCRCFile *pFiles, int nMaxFiles )
{ return m_pFileSystemPassThru->GetUnverifiedCRCFiles( pFiles, nMaxFiles ); }
virtual int GetWhitelistSpewFlags()
{ return m_pFileSystemPassThru->GetWhitelistSpewFlags(); }
virtual void SetWhitelistSpewFlags( int spewFlags )
{ m_pFileSystemPassThru->SetWhitelistSpewFlags( spewFlags ); }
virtual void InstallDirtyDiskReportFunc( FSDirtyDiskReportFunc_t func ) { m_pFileSystemPassThru->InstallDirtyDiskReportFunc( func ); }
virtual bool IsLaunchedFromXboxHDD() { return m_pFileSystemPassThru->IsLaunchedFromXboxHDD(); }
virtual bool IsInstalledToXboxHDDCache() { return m_pFileSystemPassThru->IsInstalledToXboxHDDCache(); }
virtual bool IsDVDHosted() { return m_pFileSystemPassThru->IsDVDHosted(); }
virtual bool IsInstallAllowed() { return m_pFileSystemPassThru->IsInstallAllowed(); }
virtual int GetSearchPathID( char *pPath, int nMaxLen ) { return m_pFileSystemPassThru->GetSearchPathID( pPath, nMaxLen ); }
virtual bool FixupSearchPathsAfterInstall() { return m_pFileSystemPassThru->FixupSearchPathsAfterInstall(); }
virtual FSDirtyDiskReportFunc_t GetDirtyDiskReportFunc() { return m_pFileSystemPassThru->GetDirtyDiskReportFunc(); }
virtual void AddVPKFile( char const *pPkName, SearchPathAdd_t addType = PATH_ADD_TO_TAIL ) { m_pFileSystemPassThru->AddVPKFile( pPkName, addType ); }
virtual void RemoveVPKFile( char const *pPkName ) { m_pFileSystemPassThru->RemoveVPKFile( pPkName ); }
virtual void GetVPKFileNames( CUtlVector<CUtlString> &destVector ) { m_pFileSystemPassThru->GetVPKFileNames( destVector ); }
virtual void RemoveAllMapSearchPaths( void ) { m_pFileSystemPassThru->RemoveAllMapSearchPaths(); }
virtual void SyncDvdDevCache( void ) { m_pFileSystemPassThru->SyncDvdDevCache(); }
virtual bool GetStringFromKVPool( CRC32_t poolKey, unsigned int key, char *pOutBuff, int buflen ) { return m_pFileSystemPassThru->GetStringFromKVPool( poolKey, key, pOutBuff, buflen ); }
virtual bool DiscoverDLC( int iController ) { return m_pFileSystemPassThru->DiscoverDLC( iController ); }
virtual int IsAnyDLCPresent( bool *pbDLCSearchPathMounted = NULL ) { return m_pFileSystemPassThru->IsAnyDLCPresent( pbDLCSearchPathMounted ); }
virtual bool GetAnyDLCInfo( int iDLC, unsigned int *pLicenseMask, wchar_t *pTitleBuff, int nOutTitleSize ) { return m_pFileSystemPassThru->GetAnyDLCInfo( iDLC, pLicenseMask, pTitleBuff, nOutTitleSize ); }
virtual int IsAnyCorruptDLC() { return m_pFileSystemPassThru->IsAnyCorruptDLC(); }
virtual bool GetAnyCorruptDLCInfo( int iCorruptDLC, wchar_t *pTitleBuff, int nOutTitleSize ) { return m_pFileSystemPassThru->GetAnyCorruptDLCInfo( iCorruptDLC, pTitleBuff, nOutTitleSize ); }
virtual bool AddDLCSearchPaths() { return m_pFileSystemPassThru->AddDLCSearchPaths(); }
virtual bool IsSpecificDLCPresent( unsigned int nDLCPackage ) { return m_pFileSystemPassThru->IsSpecificDLCPresent( nDLCPackage ); }
virtual void SetIODelayAlarm( float flThreshhold ) { m_pFileSystemPassThru->SetIODelayAlarm( flThreshhold ); }
virtual bool AddXLSPUpdateSearchPath( const void *pData, int nSize ) { return m_pFileSystemPassThru->AddXLSPUpdateSearchPath( pData, nSize ); }
virtual IIoStats *GetIoStats() { return m_pFileSystemPassThru->GetIoStats(); }
protected:
IFileSystem *m_pFileSystemPassThru;
};
// This is so people who change the filesystem interface are forced to add the passthru wrapper into CFileSystemPassThru,
// so they don't break VMPI.
inline void GiveMeACompileError()
{
CFileSystemPassThru asdf;
}
#endif // FILESYSTEM_PASSTHRU_H

213
external/vpc/public/icvar.h vendored Normal file
View File

@@ -0,0 +1,213 @@
//===== Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ======//
//
// Purpose:
//
//===========================================================================//
#ifndef ICVAR_H
#define ICVAR_H
#ifdef _WIN32
#pragma once
#endif
#include "appframework/iappsystem.h"
#include "tier1/iconvar.h"
#include "tier1/utlvector.h"
class ConCommandBase;
class ConCommand;
class ConVar;
class Color;
//-----------------------------------------------------------------------------
// ConVars/ComCommands are marked as having a particular DLL identifier
//-----------------------------------------------------------------------------
typedef int CVarDLLIdentifier_t;
//-----------------------------------------------------------------------------
// Used to display console messages
//-----------------------------------------------------------------------------
abstract_class IConsoleDisplayFunc
{
public:
virtual void ColorPrint( const Color& clr, const char *pMessage ) = 0;
virtual void Print( const char *pMessage ) = 0;
virtual void DPrint( const char *pMessage ) = 0;
virtual void GetConsoleText( char *pchText, size_t bufSize ) const = 0;
};
//-----------------------------------------------------------------------------
// Purpose: Applications can implement this to modify behavior in ICvar
//-----------------------------------------------------------------------------
#define CVAR_QUERY_INTERFACE_VERSION "VCvarQuery001"
abstract_class ICvarQuery : public IAppSystem
{
public:
// Can these two convars be aliased?
virtual bool AreConVarsLinkable( const ConVar *child, const ConVar *parent ) = 0;
};
//-----------------------------------------------------------------------------
// Purpose: DLL interface to ConVars/ConCommands
//-----------------------------------------------------------------------------
abstract_class ICvar : public IAppSystem
{
public:
// Allocate a unique DLL identifier
virtual CVarDLLIdentifier_t AllocateDLLIdentifier() = 0;
// Register, unregister commands
virtual void RegisterConCommand( ConCommandBase *pCommandBase ) = 0;
virtual void UnregisterConCommand( ConCommandBase *pCommandBase ) = 0;
virtual void UnregisterConCommands( CVarDLLIdentifier_t id ) = 0;
// If there is a +<varname> <value> on the command line, this returns the value.
// Otherwise, it returns NULL.
virtual const char* GetCommandLineValue( const char *pVariableName ) = 0;
// Try to find the cvar pointer by name
virtual ConCommandBase *FindCommandBase( const char *name ) = 0;
virtual const ConCommandBase *FindCommandBase( const char *name ) const = 0;
virtual ConVar *FindVar ( const char *var_name ) = 0;
virtual const ConVar *FindVar ( const char *var_name ) const = 0;
virtual ConCommand *FindCommand( const char *name ) = 0;
virtual const ConCommand *FindCommand( const char *name ) const = 0;
// Install a global change callback (to be called when any convar changes)
virtual void InstallGlobalChangeCallback( FnChangeCallback_t callback ) = 0;
virtual void RemoveGlobalChangeCallback( FnChangeCallback_t callback ) = 0;
virtual void CallGlobalChangeCallbacks( ConVar *var, const char *pOldString, float flOldValue ) = 0;
// Install a console printer
virtual void InstallConsoleDisplayFunc( IConsoleDisplayFunc* pDisplayFunc ) = 0;
virtual void RemoveConsoleDisplayFunc( IConsoleDisplayFunc* pDisplayFunc ) = 0;
virtual void ConsoleColorPrintf( const Color& clr, const char *pFormat, ... ) const = 0;
virtual void ConsolePrintf( const char *pFormat, ... ) const = 0;
virtual void ConsoleDPrintf( const char *pFormat, ... ) const = 0;
// Reverts cvars which contain a specific flag
virtual void RevertFlaggedConVars( int nFlag ) = 0;
// Method allowing the engine ICvarQuery interface to take over
// A little hacky, owing to the fact the engine is loaded
// well after ICVar, so we can't use the standard connect pattern
virtual void InstallCVarQuery( ICvarQuery *pQuery ) = 0;
#if defined( USE_VXCONSOLE )
virtual void PublishToVXConsole( ) = 0;
#endif
virtual void SetMaxSplitScreenSlots( int nSlots ) = 0;
virtual int GetMaxSplitScreenSlots() const = 0;
virtual void AddSplitScreenConVars() = 0;
virtual void RemoveSplitScreenConVars( CVarDLLIdentifier_t id ) = 0;
virtual int GetConsoleDisplayFuncCount() const = 0;
virtual void GetConsoleText( int nDisplayFuncIndex, char *pchText, size_t bufSize ) const = 0;
// Utilities for convars accessed by the material system thread
virtual bool IsMaterialThreadSetAllowed( ) const = 0;
virtual void QueueMaterialThreadSetValue( ConVar *pConVar, const char *pValue ) = 0;
virtual void QueueMaterialThreadSetValue( ConVar *pConVar, int nValue ) = 0;
virtual void QueueMaterialThreadSetValue( ConVar *pConVar, float flValue ) = 0;
virtual bool HasQueuedMaterialThreadConVarSets() const = 0;
virtual int ProcessQueuedMaterialThreadConVarSets() = 0;
protected: class ICVarIteratorInternal;
public:
/// Iteration over all cvars.
/// (THIS IS A SLOW OPERATION AND YOU SHOULD AVOID IT.)
/// usage:
/// { ICVar::Iterator iter(g_pCVar);
/// for ( iter.SetFirst() ; iter.IsValid() ; iter.Next() )
/// {
/// ConCommandBase *cmd = iter.Get();
/// }
/// }
/// The Iterator class actually wraps the internal factory methods
/// so you don't need to worry about new/delete -- scope takes care
// of it.
/// We need an iterator like this because we can't simply return a
/// pointer to the internal data type that contains the cvars --
/// it's a custom, protected class with unusual semantics and is
/// prone to change.
class Iterator
{
public:
inline Iterator(ICvar *icvar);
inline ~Iterator(void);
inline void SetFirst( void );
inline void Next( void );
inline bool IsValid( void );
inline ConCommandBase *Get( void );
private:
ICVarIteratorInternal *m_pIter;
};
protected:
// internals for ICVarIterator
class ICVarIteratorInternal
{
public:
virtual void SetFirst( void ) = 0;
virtual void Next( void ) = 0;
virtual bool IsValid( void ) = 0;
virtual ConCommandBase *Get( void ) = 0;
virtual ~ICVarIteratorInternal() {}
};
virtual ICVarIteratorInternal *FactoryInternalIterator( void ) = 0;
friend class Iterator;
};
inline ICvar::Iterator::Iterator(ICvar *icvar)
{
m_pIter = icvar->FactoryInternalIterator();
}
inline ICvar::Iterator::~Iterator( void )
{
delete m_pIter;
}
inline void ICvar::Iterator::SetFirst( void )
{
m_pIter->SetFirst();
}
inline void ICvar::Iterator::Next( void )
{
m_pIter->Next();
}
inline bool ICvar::Iterator::IsValid( void )
{
return m_pIter->IsValid();
}
inline ConCommandBase * ICvar::Iterator::Get( void )
{
return m_pIter->Get();
}
//-----------------------------------------------------------------------------
// These global names are defined by tier1.h, duplicated here so you
// don't have to include tier1.h
//-----------------------------------------------------------------------------
// These are marked DLL_EXPORT for Linux.
DECLARE_TIER1_INTERFACE( ICvar, cvar );
DECLARE_TIER1_INTERFACE( ICvar, g_pCVar );
#endif // ICVAR_H

28
external/vpc/public/ilaunchabledll.h vendored Normal file
View File

@@ -0,0 +1,28 @@
//========= Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================//
#ifndef ILAUNCHABLEDLL_H
#define ILAUNCHABLEDLL_H
#ifdef _WIN32
#pragma once
#endif
#define LAUNCHABLE_DLL_INTERFACE_VERSION "launchable_dll_1"
// vmpi_service can use this to debug worker apps in-process,
// and some of the launchers (like texturecompile) use this.
class ILaunchableDLL
{
public:
// All vrad.exe does is load the VRAD DLL and run this.
virtual int main( int argc, char **argv ) = 0;
};
#endif // ILAUNCHABLEDLL_H

View File

@@ -0,0 +1,287 @@
//===== Copyright <20> 2005-2005, Valve Corporation, All rights reserved. ======//
//
// Purpose: A higher level link library for general use in the game and tools.
//
//===========================================================================//
#ifndef INTERFACES_H
#define INTERFACES_H
#if defined( COMPILER_MSVC )
#pragma once
#endif
//-----------------------------------------------------------------------------
// Interface creation function
//-----------------------------------------------------------------------------
typedef void* (*CreateInterfaceFn)(const char *pName, int *pReturnCode);
//-----------------------------------------------------------------------------
// Macros to declare interfaces appropriate for various tiers
//-----------------------------------------------------------------------------
#if 1 || defined( TIER1_LIBRARY ) || defined( TIER2_LIBRARY ) || defined( TIER3_LIBRARY ) || defined( TIER4_LIBRARY ) || defined( APPLICATION )
#define DECLARE_TIER1_INTERFACE( _Interface, _Global ) extern _Interface * _Global;
#else
#define DECLARE_TIER1_INTERFACE( _Interface, _Global )
#endif
#if 1 || defined( TIER2_LIBRARY ) || defined( TIER3_LIBRARY ) || defined( TIER4_LIBRARY ) || defined( APPLICATION )
#define DECLARE_TIER2_INTERFACE( _Interface, _Global ) extern _Interface * _Global;
#else
#define DECLARE_TIER2_INTERFACE( _Interface, _Global )
#endif
#if 1 || defined( TIER3_LIBRARY ) || defined( TIER4_LIBRARY ) || defined( APPLICATION )
#define DECLARE_TIER3_INTERFACE( _Interface, _Global ) extern _Interface * _Global;
#else
#define DECLARE_TIER3_INTERFACE( _Interface, _Global )
#endif
//-----------------------------------------------------------------------------
// Forward declarations
//-----------------------------------------------------------------------------
class ICvar;
class IProcessUtils;
class ILocalize;
class IPhysics2;
class IPhysics2ActorManager;
class IPhysics2ResourceManager;
class IEventSystem;
class IAsyncFileSystem;
class IColorCorrectionSystem;
class IDebugTextureInfo;
class IFileSystem;
class IRenderHardwareConfig;
class IInputSystem;
class IInputStackSystem;
class IMaterialSystem;
class IMaterialSystem2;
class IMaterialSystemHardwareConfig;
class IMdlLib;
class INetworkSystem;
class IP4;
class IQueuedLoader;
class IResourceAccessControl;
class IPrecacheSystem;
class IRenderDevice;
class IRenderDeviceMgr;
class IResourceSystem;
class IVBAllocTracker;
class IXboxInstaller;
class IMatchFramework;
class ISoundSystem;
class IStudioRender;
class IMatSystemSurface;
class IGameUISystemMgr;
class IDataCache;
class IMDLCache;
class IAvi;
class IBik;
class IDmeMakefileUtils;
class IPhysicsCollision;
class ISoundEmitterSystemBase;
class IMeshSystem;
class IWorldRendererMgr;
class ISceneSystem;
class IVGuiRenderSurface;
namespace vgui
{
class ISurface;
class IVGui;
class IInput;
class IPanel;
class IVGUILocalize;
class ISchemeManager;
class ISystem;
}
//-----------------------------------------------------------------------------
// Fills out global DLL exported interface pointers
//-----------------------------------------------------------------------------
#define CVAR_INTERFACE_VERSION "VEngineCvar007"
DECLARE_TIER1_INTERFACE( ICvar, cvar );
DECLARE_TIER1_INTERFACE( ICvar, g_pCVar )
#define PROCESS_UTILS_INTERFACE_VERSION "VProcessUtils002"
DECLARE_TIER1_INTERFACE( IProcessUtils, g_pProcessUtils );
#define VPHYSICS2_INTERFACE_VERSION "Physics2 Interface v0.3"
DECLARE_TIER1_INTERFACE( IPhysics2, g_pPhysics2 );
#define VPHYSICS2_ACTOR_MGR_INTERFACE_VERSION "Physics2 Interface ActorMgr v0.1"
DECLARE_TIER1_INTERFACE( IPhysics2ActorManager, g_pPhysics2ActorManager );
#define VPHYSICS2_RESOURCE_MGR_INTERFACE_VERSION "Physics2 Interface ResourceMgr v0.1"
DECLARE_TIER1_INTERFACE( IPhysics2ResourceManager, g_pPhysics2ResourceManager );
#define EVENTSYSTEM_INTERFACE_VERSION "EventSystem001"
DECLARE_TIER1_INTERFACE( IEventSystem, g_pEventSystem );
#define LOCALIZE_INTERFACE_VERSION "Localize_001"
DECLARE_TIER2_INTERFACE( ILocalize, g_pLocalize );
DECLARE_TIER3_INTERFACE( vgui::IVGUILocalize, g_pVGuiLocalize );
#define RENDER_DEVICE_MGR_INTERFACE_VERSION "RenderDeviceMgr001"
DECLARE_TIER2_INTERFACE( IRenderDeviceMgr, g_pRenderDeviceMgr );
#define FILESYSTEM_INTERFACE_VERSION "VFileSystem017"
DECLARE_TIER2_INTERFACE( IFileSystem, g_pFullFileSystem );
#define ASYNCFILESYSTEM_INTERFACE_VERSION "VNewAsyncFileSystem001"
DECLARE_TIER2_INTERFACE( IAsyncFileSystem, g_pAsyncFileSystem );
#define RESOURCESYSTEM_INTERFACE_VERSION "ResourceSystem004"
DECLARE_TIER2_INTERFACE( IResourceSystem, g_pResourceSystem );
#define MATERIAL_SYSTEM_INTERFACE_VERSION "VMaterialSystem080"
DECLARE_TIER2_INTERFACE( IMaterialSystem, materials );
DECLARE_TIER2_INTERFACE( IMaterialSystem, g_pMaterialSystem );
#define MATERIAL_SYSTEM2_INTERFACE_VERSION "VMaterialSystem2_001"
DECLARE_TIER2_INTERFACE( IMaterialSystem2, g_pMaterialSystem2 );
#define INPUTSYSTEM_INTERFACE_VERSION "InputSystemVersion001"
DECLARE_TIER2_INTERFACE( IInputSystem, g_pInputSystem );
#define INPUTSTACKSYSTEM_INTERFACE_VERSION "InputStackSystemVersion001"
DECLARE_TIER2_INTERFACE( IInputStackSystem, g_pInputStackSystem );
#define NETWORKSYSTEM_INTERFACE_VERSION "NetworkSystemVersion001"
DECLARE_TIER2_INTERFACE( INetworkSystem, g_pNetworkSystem );
#define MATERIALSYSTEM_HARDWARECONFIG_INTERFACE_VERSION "MaterialSystemHardwareConfig013"
DECLARE_TIER2_INTERFACE( IMaterialSystemHardwareConfig, g_pMaterialSystemHardwareConfig );
#define DEBUG_TEXTURE_INFO_VERSION "DebugTextureInfo001"
DECLARE_TIER2_INTERFACE( IDebugTextureInfo, g_pMaterialSystemDebugTextureInfo );
#define VB_ALLOC_TRACKER_INTERFACE_VERSION "VBAllocTracker001"
DECLARE_TIER2_INTERFACE( IVBAllocTracker, g_VBAllocTracker );
#define COLORCORRECTION_INTERFACE_VERSION "COLORCORRECTION_VERSION_1"
DECLARE_TIER2_INTERFACE( IColorCorrectionSystem, colorcorrection );
#define P4_INTERFACE_VERSION "VP4002"
DECLARE_TIER2_INTERFACE( IP4, p4 );
#define MDLLIB_INTERFACE_VERSION "VMDLLIB001"
DECLARE_TIER2_INTERFACE( IMdlLib, mdllib );
#define QUEUEDLOADER_INTERFACE_VERSION "QueuedLoaderVersion001"
DECLARE_TIER2_INTERFACE( IQueuedLoader, g_pQueuedLoader );
#define RESOURCE_ACCESS_CONTROL_INTERFACE_VERSION "VResourceAccessControl001"
DECLARE_TIER2_INTERFACE( IResourceAccessControl, g_pResourceAccessControl );
#define PRECACHE_SYSTEM_INTERFACE_VERSION "VPrecacheSystem001"
DECLARE_TIER2_INTERFACE( IPrecacheSystem, g_pPrecacheSystem );
#if defined( _X360 )
#define XBOXINSTALLER_INTERFACE_VERSION "XboxInstallerVersion001"
DECLARE_TIER2_INTERFACE( IXboxInstaller, g_pXboxInstaller );
#endif
#define MATCHFRAMEWORK_INTERFACE_VERSION "MATCHFRAMEWORK_001"
DECLARE_TIER2_INTERFACE( IMatchFramework, g_pMatchFramework );
#define GAMEUISYSTEMMGR_INTERFACE_VERSION "GameUISystemMgr001"
DECLARE_TIER3_INTERFACE( IGameUISystemMgr, g_pGameUISystemMgr );
//-----------------------------------------------------------------------------
// Not exactly a global, but we're going to keep track of these here anyways
// NOTE: Appframework deals with connecting these bad boys. See materialsystem2app.cpp
//-----------------------------------------------------------------------------
#define RENDER_DEVICE_INTERFACE_VERSION "RenderDevice001"
DECLARE_TIER2_INTERFACE( IRenderDevice, g_pRenderDevice );
#define RENDER_HARDWARECONFIG_INTERFACE_VERSION "RenderHardwareConfig001"
DECLARE_TIER2_INTERFACE( IRenderHardwareConfig, g_pRenderHardwareConfig );
#define SOUNDSYSTEM_INTERFACE_VERSION "SoundSystem001"
DECLARE_TIER2_INTERFACE( ISoundSystem, g_pSoundSystem );
#define MESHSYSTEM_INTERFACE_VERSION "MeshSystem001"
DECLARE_TIER3_INTERFACE( IMeshSystem, g_pMeshSystem );
#define STUDIO_RENDER_INTERFACE_VERSION "VStudioRender026"
DECLARE_TIER3_INTERFACE( IStudioRender, g_pStudioRender );
DECLARE_TIER3_INTERFACE( IStudioRender, studiorender );
#define MAT_SYSTEM_SURFACE_INTERFACE_VERSION "MatSystemSurface006"
DECLARE_TIER3_INTERFACE( IMatSystemSurface, g_pMatSystemSurface );
#define RENDER_SYSTEM_SURFACE_INTERFACE_VERSION "RenderSystemSurface001"
DECLARE_TIER3_INTERFACE( IVGuiRenderSurface, g_pVGuiRenderSurface );
#define SCENESYSTEM_INTERFACE_VERSION "SceneSystem_001"
DECLARE_TIER3_INTERFACE( ISceneSystem, g_pSceneSystem );
#define VGUI_SURFACE_INTERFACE_VERSION "VGUI_Surface031"
DECLARE_TIER3_INTERFACE( vgui::ISurface, g_pVGuiSurface );
#define SCHEME_SURFACE_INTERFACE_VERSION "SchemeSurface001"
#define VGUI_INPUT_INTERFACE_VERSION "VGUI_Input005"
DECLARE_TIER3_INTERFACE( vgui::IInput, g_pVGuiInput );
#define VGUI_IVGUI_INTERFACE_VERSION "VGUI_ivgui008"
DECLARE_TIER3_INTERFACE( vgui::IVGui, g_pVGui );
#define VGUI_PANEL_INTERFACE_VERSION "VGUI_Panel009"
DECLARE_TIER3_INTERFACE( vgui::IPanel, g_pVGuiPanel );
#define VGUI_SCHEME_INTERFACE_VERSION "VGUI_Scheme010"
DECLARE_TIER3_INTERFACE( vgui::ISchemeManager, g_pVGuiSchemeManager );
#define VGUI_SYSTEM_INTERFACE_VERSION "VGUI_System010"
DECLARE_TIER3_INTERFACE( vgui::ISystem, g_pVGuiSystem );
#define DATACACHE_INTERFACE_VERSION "VDataCache003"
DECLARE_TIER3_INTERFACE( IDataCache, g_pDataCache ); // FIXME: Should IDataCache be in tier2?
#define MDLCACHE_INTERFACE_VERSION "MDLCache004"
DECLARE_TIER3_INTERFACE( IMDLCache, g_pMDLCache );
DECLARE_TIER3_INTERFACE( IMDLCache, mdlcache );
#define AVI_INTERFACE_VERSION "VAvi001"
DECLARE_TIER3_INTERFACE( IAvi, g_pAVI );
#define BIK_INTERFACE_VERSION "VBik001"
DECLARE_TIER3_INTERFACE( IBik, g_pBIK );
#define DMEMAKEFILE_UTILS_INTERFACE_VERSION "VDmeMakeFileUtils001"
DECLARE_TIER3_INTERFACE( IDmeMakefileUtils, g_pDmeMakefileUtils );
#define VPHYSICS_COLLISION_INTERFACE_VERSION "VPhysicsCollision007"
DECLARE_TIER3_INTERFACE( IPhysicsCollision, g_pPhysicsCollision );
#define SOUNDEMITTERSYSTEM_INTERFACE_VERSION "VSoundEmitter003"
DECLARE_TIER3_INTERFACE( ISoundEmitterSystemBase, g_pSoundEmitterSystem );
#define WORLD_RENDERER_MGR_INTERFACE_VERSION "WorldRendererMgr001"
DECLARE_TIER3_INTERFACE( IWorldRendererMgr, g_pWorldRendererMgr );
//-----------------------------------------------------------------------------
// Fills out global DLL exported interface pointers
//-----------------------------------------------------------------------------
void ConnectInterfaces( CreateInterfaceFn *pFactoryList, int nFactoryCount );
void DisconnectInterfaces();
//-----------------------------------------------------------------------------
// Reconnects an interface
//-----------------------------------------------------------------------------
void ReconnectInterface( CreateInterfaceFn factory, const char *pInterfaceName );
#endif // INTERFACES_H

97
external/vpc/public/mathlib/fltx4.h vendored Normal file
View File

@@ -0,0 +1,97 @@
//===== Copyright 1996-2010, Valve Corporation, All rights reserved. ======//
//
// Purpose: - defines the type fltx4 - Avoid cyclic includion.
//
//===========================================================================//
#ifndef FLTX4_H
#define FLTX4_H
#if defined(GNUC)
#define USE_STDC_FOR_SIMD 0
#else
#define USE_STDC_FOR_SIMD 0
#endif
#if (!defined(PLATFORM_PPC) && (USE_STDC_FOR_SIMD == 0))
#define _SSE1 1
#endif
// I thought about defining a class/union for the SIMD packed floats instead of using fltx4,
// but decided against it because (a) the nature of SIMD code which includes comparisons is to blur
// the relationship between packed floats and packed integer types and (b) not sure that the
// compiler would handle generating good code for the intrinsics.
#if USE_STDC_FOR_SIMD
#error "hello"
typedef union
{
float m128_f32[4];
uint32 m128_u32[4];
} fltx4;
typedef fltx4 i32x4;
typedef fltx4 u32x4;
#ifdef _PS3
typedef fltx4 u32x4;
typedef fltx4 i32x4;
#endif
typedef fltx4 bi32x4;
#elif ( defined( _PS3 ) )
typedef union
{
// This union allows float/int access (which generally shouldn't be done in inner loops)
vec_float4 vmxf;
vec_int4 vmxi;
vec_uint4 vmxui;
__vector bool vmxbi;
struct
{
float x;
float y;
float z;
float w;
};
float m128_f32[4];
uint32 m128_u32[4];
int32 m128_i32[4];
} fltx4_union;
typedef vec_float4 fltx4;
typedef vec_uint4 u32x4;
typedef vec_int4 i32x4;
typedef __vector bool bi32x4;
#define DIFFERENT_NATIVE_VECTOR_TYPES // true if the compiler has different types for float4, uint4, int4, etc
#elif ( defined( _X360 ) )
typedef union
{
// This union allows float/int access (which generally shouldn't be done in inner loops)
__vector4 vmx;
float m128_f32[4];
uint32 m128_u32[4];
} fltx4_union;
typedef __vector4 fltx4;
typedef __vector4 i32x4; // a VMX register; just a way of making it explicit that we're doing integer ops.
typedef __vector4 u32x4; // a VMX register; just a way of making it explicit that we're doing unsigned integer ops.
typedef fltx4 bi32x4;
#else
typedef __m128 fltx4;
typedef __m128 i32x4;
typedef __m128 u32x4;
typedef fltx4 bi32x4;
#endif
#endif

283
external/vpc/public/mathlib/math_pfns.h vendored Normal file
View File

@@ -0,0 +1,283 @@
//========= Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=====================================================================================//
#ifndef _MATH_PFNS_H_
#define _MATH_PFNS_H_
#include <limits>
#if defined( _X360 )
#include <xboxmath.h>
#elif defined(_PS3)
#ifndef SPU
#include <ppu_asm_intrinsics.h>
#endif
// Note that similar defines exist in ssemath.h
// Maybe we should consolidate in one place for all platforms.
#define _VEC_0x7ff (vec_int4){0x7ff,0x7ff,0x7ff,0x7ff}
#define _VEC_0x3ff (vec_int4){0x3ff,0x3ff,0x3ff,0x3ff}
#define _VEC_22L (vector unsigned int){22,22,22,22}
#define _VEC_11L (vector unsigned int){11,11,11,11}
#define _VEC_0L (vector unsigned int){0,0,0,0}
#define _VEC_255F (vector float){255.0f,255.0f,255.0f,255.0f}
#define _VEC_NEGONEF (vector float){-1.0f,-1.0f,-1.0f,-1.0f}
#define _VEC_ONEF (vector float){1.0f,1.0f,1.0f,1.0f}
#define _VEC_ZEROF (vector float){0.0f,0.0f,0.0f,0.0f}
#define _VEC_ZEROxyzONEwF (vector float){0.0f,0.0f,0.0f,1.0f}
#define _VEC_HALFF (vector float){0.5f,0.5f,0.5f,0.5f}
#define _VEC_HALFxyzZEROwF (vector float){0.5f,0.5f,0.5f,0.0f}
#define _VEC_PERMUTE_XYZ0W1 (vector unsigned char){0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x1c,0x1d,0x1e,0x1f}
#define _VEC_IEEEHACK (vector float){(float)(1 << 23),(float)(1 << 23),(float)(1 << 23),(float)(1 << 23)}
#define _VEC_PERMUTE_FASTFTOC (vector unsigned char){0,0,0,0,0,0,0,0,0,0,0,0,0x03,0x07,0x0b,0x0f}
// AngleQuaternion
#define _VEC_PERMUTE_AQsxsxcxcx (vector unsigned char) {0x00,0x01,0x02,0x03,0x00,0x01,0x02,0x03,0x10,0x11,0x12,0x13,0x10,0x11,0x12,0x13}
#define _VEC_PERMUTE_AQczszszcz (vector unsigned char) {0x18,0x19,0x1a,0x1b,0x08,0x09,0x0a,0x0b,0x08,0x09,0x0a,0x0b,0x18,0x19,0x1a,0x1b}
#define _VEC_PERMUTE_AQcxcxsxsx (vector unsigned char) {0x10,0x11,0x12,0x13,0x10,0x11,0x12,0x13,0x00,0x01,0x02,0x03,0x00,0x01,0x02,0x03}
#define _VEC_PERMUTE_AQszczczsz (vector unsigned char) {0x08,0x09,0x0a,0x0b,0x18,0x19,0x1a,0x1b,0x18,0x19,0x1a,0x1b,0x08,0x09,0x0a,0x0b}
#define _VEC_PERMUTE_ANGLEQUAT (vector unsigned char) {0x10,0x11,0x12,0x13,0x04,0x05,0x06,0x07,0x18,0x19,0x1a,0x1b,0x0c,0x0d,0x0e,0x0f}
#define _VEC_EPSILONF (__vector float) {FLT_EPSILON,FLT_EPSILON,FLT_EPSILON,FLT_EPSILON}
#endif
#if !(defined( PLATFORM_PPC ) || defined(SPU))
// If we are not PPC based or SPU based, then assumes it is SSE2. We should make this code cleaner.
#include <xmmintrin.h>
// These globals are initialized by mathlib and redirected based on available fpu features
// The following are not declared as macros because they are often used in limiting situations,
// and sometimes the compiler simply refuses to inline them for some reason
FORCEINLINE float FastSqrt( float x )
{
__m128 root = _mm_sqrt_ss( _mm_load_ss( &x ) );
return *( reinterpret_cast<float *>( &root ) );
}
FORCEINLINE float FastRSqrtFast( float x )
{
// use intrinsics
__m128 rroot = _mm_rsqrt_ss( _mm_load_ss( &x ) );
return *( reinterpret_cast<float *>( &rroot ) );
}
// Single iteration NewtonRaphson reciprocal square root:
// 0.5 * rsqrtps * (3 - x * rsqrtps(x) * rsqrtps(x))
// Very low error, and fine to use in place of 1.f / sqrtf(x).
FORCEINLINE float FastRSqrt( float x )
{
float rroot = FastRSqrtFast( x );
return (0.5f * rroot) * (3.f - (x * rroot) * rroot);
}
void FastSinCos( float x, float* s, float* c ); // any x
float FastCos( float x );
inline float FastRecip(float x) {return 1.0f / x;}
// Simple SSE rsqrt. Usually accurate to around 6 (relative) decimal places
// or so, so ok for closed transforms. (ie, computing lighting normals)
inline float FastSqrtEst(float x) { return FastRSqrtFast(x) * x; }
#else // !defined( PLATFORM_PPC ) && !defined(_SPU)
#ifndef SPU
// We may not need this for SPU, so let's not bother for now
FORCEINLINE float _VMX_Sqrt( float x )
{
return __fsqrts( x );
}
FORCEINLINE double _VMX_RSqrt( double x )
{
double rroot = __frsqrte( x );
// Single iteration NewtonRaphson on reciprocal square root estimate
return (0.5f * rroot) * (3.0f - (x * rroot) * rroot);
}
FORCEINLINE double _VMX_RSqrtFast( double x )
{
return __frsqrte( x );
}
#ifdef _X360
FORCEINLINE void _VMX_SinCos( float a, float *pS, float *pC )
{
XMScalarSinCos( pS, pC, a );
}
FORCEINLINE float _VMX_Cos( float a )
{
return XMScalarCos( a );
}
#endif
// the 360 has fixed hw and calls directly
#define FastSqrt(x) _VMX_Sqrt(x)
#define FastRSqrt(x) _VMX_RSqrt(x)
#define FastRSqrtFast(x) _VMX_RSqrtFast(x)
#define FastSinCos(x,s,c) _VMX_SinCos(x,s,c)
#define FastCos(x) _VMX_Cos(x)
inline double FastRecip(double x) {return __fres(x);}
inline double FastSqrtEst(double x) { return __frsqrte(x) * x; }
#endif // !defined( PLATFORM_PPC ) && !defined(_SPU)
// if x is infinite, return FLT_MAX
inline float FastClampInfinity( float x )
{
#ifdef PLATFORM_PPC
return fsel( std::numeric_limits<float>::infinity() - x, x, FLT_MAX );
#else
return ( x > FLT_MAX ? FLT_MAX : x );
#endif
}
#if defined (_PS3) && !defined(SPU)
// extern float cosvf(float); /* single precision cosine */
// extern float sinvf(float); /* single precision sine */
// TODO: need a faster single precision equivalent
#define cosvf cosf
#define sinvf sinf
inline int _rotl( int x, int c )
{
return __rlwimi(x,x,c,0,31);
}
inline int64 _rotl64( int64 x, int c )
{
return __rldicl( x, c, 0 );
}
//-----------------------------------------------------------------
// Vector Unions
//-----------------------------------------------------------------
//-----------------------------------------------------------------
// Floats
//-----------------------------------------------------------------
typedef union
{
vector float vf;
float f[4];
} vector_float_union;
//-----------------------------------------------------------------
// Ints
//-----------------------------------------------------------------
typedef union
{
vector int vi;
int i[4];
} vector_int4_union;
typedef union
{
vector unsigned int vui;
unsigned int ui[4];
} vector_uint4_union;
//-----------------------------------------------------------------
// Shorts
//-----------------------------------------------------------------
typedef union
{
vector signed short vs;
signed short s[8];
} vector_short8_union;
typedef union
{
vector unsigned short vus;
unsigned short us[8];
} vector_ushort8_union;
//-----------------------------------------------------------------
// Chars
//-----------------------------------------------------------------
typedef union
{
vector signed char vc;
signed char c[16];
} vector_char16_union;
typedef union
{
vector unsigned char vuc;
unsigned char uc[16];
} vector_uchar16_union;
/*
FORCEINLINE float _VMX_Sqrt( float x )
{
vector_float_union vIn, vOut;
vIn.f[0] = x;
vOut.vf = sqrtf4(vIn.vf);
return vOut.f[0];
}
FORCEINLINE float _VMX_RSqrt( float x )
{
vector_float_union vIn, vOut;
vIn.f[0] = x;
vOut.vf = rsqrtf4(vIn.vf);
return vOut.f[0];
}
FORCEINLINE float _VMX_RSqrtFast( float x )
{
vector_float_union vIn, vOut;
vIn.f[0] = x;
vOut.vf = rsqrtf4fast(vIn.vf);
return vOut.f[0];
}
*/
FORCEINLINE void _VMX_SinCos( float a, float *pS, float *pC )
{
*pS=sinvf(a);
*pC=cosvf(a);
}
FORCEINLINE float _VMX_Cos( float a )
{
return cosvf(a);
}
// the 360 has fixed hw and calls directly
/*
#define FastSqrt(x) _VMX_Sqrt(x)
#define FastRSqrt(x) _VMX_RSqrt(x)
#define FastRSqrtFast(x) _VMX_RSqrtFast(x)
#define FastSinCos(x,s,c) _VMX_SinCos(x,s,c)
#define FastCos(x) _VMX_Cos(x)
*/
#endif // _PS3
#endif // #ifndef SPU
#endif // _MATH_PFNS_H_

2425
external/vpc/public/mathlib/mathlib.h vendored Normal file

File diff suppressed because it is too large Load Diff

2633
external/vpc/public/mathlib/vector.h vendored Normal file

File diff suppressed because it is too large Load Diff

670
external/vpc/public/mathlib/vector2d.h vendored Normal file
View File

@@ -0,0 +1,670 @@
//========= Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//
//=============================================================================//
#ifndef VECTOR2D_H
#define VECTOR2D_H
#ifdef _WIN32
#pragma once
#endif
#include <math.h>
#include <float.h>
// For vec_t, put this somewhere else?
#include "tier0/basetypes.h"
// For RandomFloat()
#include "vstdlib/random.h"
#include "tier0/dbg.h"
#include "mathlib/math_pfns.h"
//=========================================================
// 2D Vector2D
//=========================================================
class Vector2D
{
public:
// Members
vec_t x, y;
// Construction/destruction
Vector2D(void);
Vector2D(vec_t X, vec_t Y);
Vector2D(const float *pFloat);
// Initialization
void Init(vec_t ix=0.0f, vec_t iy=0.0f);
// Got any nasty NAN's?
bool IsValid() const;
// array access...
vec_t operator[](int i) const;
vec_t& operator[](int i);
// Base address...
vec_t* Base();
vec_t const* Base() const;
// Initialization methods
void Random( float minVal, float maxVal );
// equality
bool operator==(const Vector2D& v) const;
bool operator!=(const Vector2D& v) const;
// arithmetic operations
Vector2D& operator+=(const Vector2D &v);
Vector2D& operator-=(const Vector2D &v);
Vector2D& operator*=(const Vector2D &v);
Vector2D& operator*=(float s);
Vector2D& operator/=(const Vector2D &v);
Vector2D& operator/=(float s);
// negate the Vector2D components
void Negate();
// Get the Vector2D's magnitude.
vec_t Length() const;
// Get the Vector2D's magnitude squared.
vec_t LengthSqr(void) const;
// return true if this vector is (0,0) within tolerance
bool IsZero( float tolerance = 0.01f ) const
{
return (x > -tolerance && x < tolerance &&
y > -tolerance && y < tolerance);
}
// Normalize in place and return the old length.
vec_t NormalizeInPlace();
// Compare length.
bool IsLengthGreaterThan( float val ) const;
bool IsLengthLessThan( float val ) const;
// Get the distance from this Vector2D to the other one.
vec_t DistTo(const Vector2D &vOther) const;
// Get the distance from this Vector2D to the other one squared.
vec_t DistToSqr(const Vector2D &vOther) const;
// Copy
void CopyToArray(float* rgfl) const;
// Multiply, add, and assign to this (ie: *this = a + b * scalar). This
// is about 12% faster than the actual Vector2D equation (because it's done per-component
// rather than per-Vector2D).
void MulAdd(const Vector2D& a, const Vector2D& b, float scalar);
// Dot product.
vec_t Dot(const Vector2D& vOther) const;
// assignment
Vector2D& operator=(const Vector2D &vOther);
#ifndef VECTOR_NO_SLOW_OPERATIONS
// copy constructors
Vector2D(const Vector2D &vOther);
// arithmetic operations
Vector2D operator-(void) const;
Vector2D operator+(const Vector2D& v) const;
Vector2D operator-(const Vector2D& v) const;
Vector2D operator*(const Vector2D& v) const;
Vector2D operator/(const Vector2D& v) const;
Vector2D operator*(float fl) const;
Vector2D operator/(float fl) const;
// Cross product between two vectors.
Vector2D Cross(const Vector2D &vOther) const;
// Returns a Vector2D with the min or max in X, Y, and Z.
Vector2D Min(const Vector2D &vOther) const;
Vector2D Max(const Vector2D &vOther) const;
#else
private:
// No copy constructors allowed if we're in optimal mode
Vector2D(const Vector2D& vOther);
#endif
};
//-----------------------------------------------------------------------------
const Vector2D vec2_origin(0,0);
const Vector2D vec2_invalid( FLT_MAX, FLT_MAX );
//-----------------------------------------------------------------------------
// Vector2D related operations
//-----------------------------------------------------------------------------
// Vector2D clear
void Vector2DClear( Vector2D& a );
// Copy
void Vector2DCopy( const Vector2D& src, Vector2D& dst );
// Vector2D arithmetic
void Vector2DAdd( const Vector2D& a, const Vector2D& b, Vector2D& result );
void Vector2DSubtract( const Vector2D& a, const Vector2D& b, Vector2D& result );
void Vector2DMultiply( const Vector2D& a, vec_t b, Vector2D& result );
void Vector2DMultiply( const Vector2D& a, const Vector2D& b, Vector2D& result );
void Vector2DDivide( const Vector2D& a, vec_t b, Vector2D& result );
void Vector2DDivide( const Vector2D& a, const Vector2D& b, Vector2D& result );
void Vector2DMA( const Vector2D& start, float s, const Vector2D& dir, Vector2D& result );
// Store the min or max of each of x, y, and z into the result.
void Vector2DMin( const Vector2D &a, const Vector2D &b, Vector2D &result );
void Vector2DMax( const Vector2D &a, const Vector2D &b, Vector2D &result );
#define Vector2DExpand( v ) (v).x, (v).y
// Normalization
vec_t Vector2DNormalize( Vector2D& v );
// Length
vec_t Vector2DLength( const Vector2D& v );
// Dot Product
vec_t DotProduct2D(const Vector2D& a, const Vector2D& b);
// Linearly interpolate between two vectors
void Vector2DLerp(const Vector2D& src1, const Vector2D& src2, vec_t t, Vector2D& dest );
//-----------------------------------------------------------------------------
//
// Inlined Vector2D methods
//
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// constructors
//-----------------------------------------------------------------------------
inline Vector2D::Vector2D(void)
{
#ifdef _DEBUG
// Initialize to NAN to catch errors
x = y = VEC_T_NAN;
#endif
}
inline Vector2D::Vector2D(vec_t X, vec_t Y)
{
x = X; y = Y;
Assert( IsValid() );
}
inline Vector2D::Vector2D(const float *pFloat)
{
Assert( pFloat );
x = pFloat[0]; y = pFloat[1];
Assert( IsValid() );
}
//-----------------------------------------------------------------------------
// copy constructor
//-----------------------------------------------------------------------------
inline Vector2D::Vector2D(const Vector2D &vOther)
{
Assert( vOther.IsValid() );
x = vOther.x; y = vOther.y;
}
//-----------------------------------------------------------------------------
// initialization
//-----------------------------------------------------------------------------
inline void Vector2D::Init( vec_t ix, vec_t iy )
{
x = ix; y = iy;
Assert( IsValid() );
}
inline void Vector2D::Random( float minVal, float maxVal )
{
x = RandomFloat( minVal , maxVal );
y = RandomFloat( minVal , maxVal );
}
inline void Vector2DClear( Vector2D& a )
{
a.x = a.y = 0.0f;
}
//-----------------------------------------------------------------------------
// assignment
//-----------------------------------------------------------------------------
inline Vector2D& Vector2D::operator=(const Vector2D &vOther)
{
Assert( vOther.IsValid() );
x=vOther.x; y=vOther.y;
return *this;
}
//-----------------------------------------------------------------------------
// Array access
//-----------------------------------------------------------------------------
inline vec_t& Vector2D::operator[](int i)
{
Assert( (i >= 0) && (i < 2) );
return ((vec_t*)this)[i];
}
inline vec_t Vector2D::operator[](int i) const
{
Assert( (i >= 0) && (i < 2) );
return ((vec_t*)this)[i];
}
//-----------------------------------------------------------------------------
// Base address...
//-----------------------------------------------------------------------------
inline vec_t* Vector2D::Base()
{
return (vec_t*)this;
}
inline vec_t const* Vector2D::Base() const
{
return (vec_t const*)this;
}
//-----------------------------------------------------------------------------
// IsValid?
//-----------------------------------------------------------------------------
inline bool Vector2D::IsValid() const
{
return IsFinite(x) && IsFinite(y);
}
//-----------------------------------------------------------------------------
// comparison
//-----------------------------------------------------------------------------
inline bool Vector2D::operator==( const Vector2D& src ) const
{
Assert( src.IsValid() && IsValid() );
return (src.x == x) && (src.y == y);
}
inline bool Vector2D::operator!=( const Vector2D& src ) const
{
Assert( src.IsValid() && IsValid() );
return (src.x != x) || (src.y != y);
}
//-----------------------------------------------------------------------------
// Copy
//-----------------------------------------------------------------------------
inline void Vector2DCopy( const Vector2D& src, Vector2D& dst )
{
Assert( src.IsValid() );
dst.x = src.x;
dst.y = src.y;
}
inline void Vector2D::CopyToArray(float* rgfl) const
{
Assert( IsValid() );
Assert( rgfl );
rgfl[0] = x; rgfl[1] = y;
}
//-----------------------------------------------------------------------------
// standard math operations
//-----------------------------------------------------------------------------
inline void Vector2D::Negate()
{
Assert( IsValid() );
x = -x; y = -y;
}
inline Vector2D& Vector2D::operator+=(const Vector2D& v)
{
Assert( IsValid() && v.IsValid() );
x+=v.x; y+=v.y;
return *this;
}
inline Vector2D& Vector2D::operator-=(const Vector2D& v)
{
Assert( IsValid() && v.IsValid() );
x-=v.x; y-=v.y;
return *this;
}
inline Vector2D& Vector2D::operator*=(float fl)
{
x *= fl;
y *= fl;
Assert( IsValid() );
return *this;
}
inline Vector2D& Vector2D::operator*=(const Vector2D& v)
{
x *= v.x;
y *= v.y;
Assert( IsValid() );
return *this;
}
inline Vector2D& Vector2D::operator/=(float fl)
{
Assert( fl != 0.0f );
float oofl = 1.0f / fl;
x *= oofl;
y *= oofl;
Assert( IsValid() );
return *this;
}
inline Vector2D& Vector2D::operator/=(const Vector2D& v)
{
Assert( v.x != 0.0f && v.y != 0.0f );
x /= v.x;
y /= v.y;
Assert( IsValid() );
return *this;
}
inline void Vector2DAdd( const Vector2D& a, const Vector2D& b, Vector2D& c )
{
Assert( a.IsValid() && b.IsValid() );
c.x = a.x + b.x;
c.y = a.y + b.y;
}
inline void Vector2DSubtract( const Vector2D& a, const Vector2D& b, Vector2D& c )
{
Assert( a.IsValid() && b.IsValid() );
c.x = a.x - b.x;
c.y = a.y - b.y;
}
inline void Vector2DMultiply( const Vector2D& a, vec_t b, Vector2D& c )
{
Assert( a.IsValid() && IsFinite(b) );
c.x = a.x * b;
c.y = a.y * b;
}
inline void Vector2DMultiply( const Vector2D& a, const Vector2D& b, Vector2D& c )
{
Assert( a.IsValid() && b.IsValid() );
c.x = a.x * b.x;
c.y = a.y * b.y;
}
inline void Vector2DDivide( const Vector2D& a, vec_t b, Vector2D& c )
{
Assert( a.IsValid() );
Assert( b != 0.0f );
vec_t oob = 1.0f / b;
c.x = a.x * oob;
c.y = a.y * oob;
}
inline void Vector2DDivide( const Vector2D& a, const Vector2D& b, Vector2D& c )
{
Assert( a.IsValid() );
Assert( (b.x != 0.0f) && (b.y != 0.0f) );
c.x = a.x / b.x;
c.y = a.y / b.y;
}
inline void Vector2DMA( const Vector2D& start, float s, const Vector2D& dir, Vector2D& result )
{
Assert( start.IsValid() && IsFinite(s) && dir.IsValid() );
result.x = start.x + s*dir.x;
result.y = start.y + s*dir.y;
}
// FIXME: Remove
// For backwards compatability
inline void Vector2D::MulAdd(const Vector2D& a, const Vector2D& b, float scalar)
{
x = a.x + b.x * scalar;
y = a.y + b.y * scalar;
}
inline void Vector2DLerp(const Vector2D& src1, const Vector2D& src2, vec_t t, Vector2D& dest )
{
dest[0] = src1[0] + (src2[0] - src1[0]) * t;
dest[1] = src1[1] + (src2[1] - src1[1]) * t;
}
//-----------------------------------------------------------------------------
// dot, cross
//-----------------------------------------------------------------------------
inline vec_t DotProduct2D(const Vector2D& a, const Vector2D& b)
{
Assert( a.IsValid() && b.IsValid() );
return( a.x*b.x + a.y*b.y );
}
// for backwards compatability
inline vec_t Vector2D::Dot( const Vector2D& vOther ) const
{
return DotProduct2D( *this, vOther );
}
//-----------------------------------------------------------------------------
// length
//-----------------------------------------------------------------------------
inline vec_t Vector2DLength( const Vector2D& v )
{
Assert( v.IsValid() );
return (vec_t)FastSqrt(v.x*v.x + v.y*v.y);
}
inline vec_t Vector2D::LengthSqr(void) const
{
Assert( IsValid() );
return (x*x + y*y);
}
inline vec_t Vector2D::NormalizeInPlace()
{
return Vector2DNormalize( *this );
}
inline bool Vector2D::IsLengthGreaterThan( float val ) const
{
return LengthSqr() > val*val;
}
inline bool Vector2D::IsLengthLessThan( float val ) const
{
return LengthSqr() < val*val;
}
inline vec_t Vector2D::Length(void) const
{
return Vector2DLength( *this );
}
inline void Vector2DMin( const Vector2D &a, const Vector2D &b, Vector2D &result )
{
result.x = (a.x < b.x) ? a.x : b.x;
result.y = (a.y < b.y) ? a.y : b.y;
}
inline void Vector2DMax( const Vector2D &a, const Vector2D &b, Vector2D &result )
{
result.x = (a.x > b.x) ? a.x : b.x;
result.y = (a.y > b.y) ? a.y : b.y;
}
//-----------------------------------------------------------------------------
// Normalization
//-----------------------------------------------------------------------------
inline vec_t Vector2DNormalize( Vector2D& v )
{
Assert( v.IsValid() );
vec_t l = v.Length();
if (l != 0.0f)
{
v /= l;
}
else
{
v.x = v.y = 0.0f;
}
return l;
}
//-----------------------------------------------------------------------------
// Get the distance from this Vector2D to the other one
//-----------------------------------------------------------------------------
inline vec_t Vector2D::DistTo(const Vector2D &vOther) const
{
Vector2D delta;
Vector2DSubtract( *this, vOther, delta );
return delta.Length();
}
inline vec_t Vector2D::DistToSqr(const Vector2D &vOther) const
{
Vector2D delta;
Vector2DSubtract( *this, vOther, delta );
return delta.LengthSqr();
}
//-----------------------------------------------------------------------------
// Computes the closest point to vecTarget no farther than flMaxDist from vecStart
//-----------------------------------------------------------------------------
inline void ComputeClosestPoint2D( const Vector2D& vecStart, float flMaxDist, const Vector2D& vecTarget, Vector2D *pResult )
{
Vector2D vecDelta;
Vector2DSubtract( vecTarget, vecStart, vecDelta );
float flDistSqr = vecDelta.LengthSqr();
if ( flDistSqr <= flMaxDist * flMaxDist )
{
*pResult = vecTarget;
}
else
{
vecDelta /= FastSqrt( flDistSqr );
Vector2DMA( vecStart, flMaxDist, vecDelta, *pResult );
}
}
//-----------------------------------------------------------------------------
//
// Slow methods
//
//-----------------------------------------------------------------------------
#ifndef VECTOR_NO_SLOW_OPERATIONS
//-----------------------------------------------------------------------------
// Returns a Vector2D with the min or max in X, Y, and Z.
//-----------------------------------------------------------------------------
inline Vector2D Vector2D::Min(const Vector2D &vOther) const
{
return Vector2D(x < vOther.x ? x : vOther.x,
y < vOther.y ? y : vOther.y);
}
inline Vector2D Vector2D::Max(const Vector2D &vOther) const
{
return Vector2D(x > vOther.x ? x : vOther.x,
y > vOther.y ? y : vOther.y);
}
//-----------------------------------------------------------------------------
// arithmetic operations
//-----------------------------------------------------------------------------
inline Vector2D Vector2D::operator-(void) const
{
return Vector2D(-x,-y);
}
inline Vector2D Vector2D::operator+(const Vector2D& v) const
{
Vector2D res;
Vector2DAdd( *this, v, res );
return res;
}
inline Vector2D Vector2D::operator-(const Vector2D& v) const
{
Vector2D res;
Vector2DSubtract( *this, v, res );
return res;
}
inline Vector2D Vector2D::operator*(float fl) const
{
Vector2D res;
Vector2DMultiply( *this, fl, res );
return res;
}
inline Vector2D Vector2D::operator*(const Vector2D& v) const
{
Vector2D res;
Vector2DMultiply( *this, v, res );
return res;
}
inline Vector2D Vector2D::operator/(float fl) const
{
Vector2D res;
Vector2DDivide( *this, fl, res );
return res;
}
inline Vector2D Vector2D::operator/(const Vector2D& v) const
{
Vector2D res;
Vector2DDivide( *this, v, res );
return res;
}
inline Vector2D operator*(float fl, const Vector2D& v)
{
return v * fl;
}
#endif //slow
#endif // VECTOR2D_H

191
external/vpc/public/p4lib/ip4.h vendored Normal file
View File

@@ -0,0 +1,191 @@
//====== Copyright <20> 1996-2005, Valve Corporation, All rights reserved. =======
//
// Purpose:
//
//=============================================================================
#ifndef IP4_H
#define IP4_H
#ifdef _WIN32
#pragma once
#endif
#include "tier1/utlsymbol.h"
#include "tier1/utlvector.h"
#include "tier1/utlstring.h"
#include "appframework/iappsystem.h"
//-----------------------------------------------------------------------------
// Current perforce file state
//-----------------------------------------------------------------------------
enum P4FileState_t
{
P4FILE_UNOPENED = 0,
P4FILE_OPENED_FOR_ADD,
P4FILE_OPENED_FOR_EDIT,
P4FILE_OPENED_FOR_DELETE,
P4FILE_OPENED_FOR_INTEGRATE,
};
//-----------------------------------------------------------------------------
// Purpose: definition of a file
//-----------------------------------------------------------------------------
struct P4File_t
{
CUtlSymbol m_sName; // file name
CUtlSymbol m_sPath; // residing folder
CUtlSymbol m_sDepotFile; // the name in the depot
CUtlSymbol m_sClientFile; // the name on the client in Perforce syntax
CUtlSymbol m_sLocalFile; // the name on the client in local syntax
int m_iHeadRevision; // head revision number
int m_iHaveRevision; // the revision the clientspec has synced locally
bool m_bOpenedByOther; // opened by another user
bool m_bDir; // directory
bool m_bDeleted; // deleted
P4FileState_t m_eOpenState; // current change state
int m_iChangelist; // changelist current opened in
};
//-----------------------------------------------------------------------------
// Purpose: a single revision of a file
//-----------------------------------------------------------------------------
struct P4Revision_t
{
int m_iChange; // changelist number
int m_nYear, m_nMonth, m_nDay;
int m_nHour, m_nMinute, m_nSecond;
CUtlSymbol m_sUser; // submitting user
CUtlSymbol m_sClient; // submitting client
CUtlString m_Description;
};
//-----------------------------------------------------------------------------
// Purpose: a single clientspec
//-----------------------------------------------------------------------------
struct P4Client_t
{
CUtlSymbol m_sName;
CUtlSymbol m_sUser;
CUtlSymbol m_sHost; // machine name this client is on
CUtlSymbol m_sLocalRoot; // local path
};
//-----------------------------------------------------------------------------
// Purpose: Interface to accessing P4 commands
//-----------------------------------------------------------------------------
#define P4_MAX_INPUT_BUFFER_SIZE 16384 // descriptions should be limited to this size!
abstract_class IP4 : public IAppSystem
{
public:
// name of the current clientspec
virtual P4Client_t &GetActiveClient() = 0;
// changes the current client
virtual void SetActiveClient(const char *clientname) = 0;
// Refreshes the current client from p4 settings
virtual void RefreshActiveClient() = 0;
// translate filespecs into the desired syntax
virtual void GetDepotFilePath(char *depotFilePath, const char *filespec, int size) = 0;
virtual void GetClientFilePath(char *clientFilePath, const char *filespec, int size) = 0;
virtual void GetLocalFilePath(char *localFilePath, const char *filespec, int size) = 0;
// retreives the list of files in a path
virtual CUtlVector<P4File_t> &GetFileList( const char *path ) = 0;
// returns the list of files opened for edit/integrate/delete
virtual void GetOpenedFileList( CUtlVector<P4File_t> &fileList, bool bDefaultChangeOnly ) = 0;
virtual void GetOpenedFileList( const char *pRootDirectory, CUtlVector<P4File_t> &fileList ) = 0;
virtual void GetOpenedFileListInPath( const char *pPathID, CUtlVector<P4File_t> &fileList ) = 0;
// retrieves revision history for a file or directory
virtual CUtlVector<P4Revision_t> &GetRevisionList( const char *path, bool bIsDir ) = 0;
// returns a list of clientspecs
virtual CUtlVector<P4Client_t> &GetClientList() = 0;
// changes the clientspec to remove the specified path (cloaking)
virtual void RemovePathFromActiveClientspec( const char *path ) = 0;
// file manipulation
virtual bool OpenFileForAdd( const char *pFullPath ) = 0;
virtual bool OpenFileForEdit( const char *pFullPath ) = 0;
virtual bool OpenFileForDelete( const char *pFullPath ) = 0;
virtual bool SyncFile( const char *pFullPath, int nRevision = -1 ) = 0; // default revision is to sync to the head revision
// submit/revert
virtual bool SubmitFile( const char *pFullPath, const char *pDescription ) = 0;
virtual bool RevertFile( const char *pFullPath ) = 0;
// file checkin/checkout for multiple files
virtual bool OpenFilesForAdd( int nCount, const char **ppFullPathList ) = 0;
virtual bool OpenFilesForEdit( int nCount, const char **ppFullPathList ) = 0;
virtual bool OpenFilesForDelete( int nCount, const char **ppFullPathList ) = 0;
// submit/revert for multiple files
virtual bool SubmitFiles( int nCount, const char **ppFullPathList, const char *pDescription ) = 0;
virtual bool RevertFiles( int nCount, const char **ppFullPathList ) = 0;
// Is this file in perforce?
virtual bool IsFileInPerforce( const char *pFullPath ) = 0;
// Get the perforce file state
virtual P4FileState_t GetFileState( const char *pFullPath ) = 0;
// depot root
virtual const char *GetDepotRoot() = 0;
virtual int GetDepotRootLength() = 0;
// local root
virtual const char *GetLocalRoot() = 0;
virtual int GetLocalRootLength() = 0;
// Gets a string for a symbol
virtual const char *String( CUtlSymbol s ) const = 0;
// Returns which clientspec a file lies under. This will
// search for p4config files in root directories of the file
// It returns false if it didn't find a p4config file.
virtual bool GetClientSpecForFile( const char *pFullPath, char *pClientSpec, int nMaxLen ) = 0;
virtual bool GetClientSpecForDirectory( const char *pFullPathDir, char *pClientSpec, int nMaxLen ) = 0;
// Returns which clientspec a filesystem path ID lies under. This will
// search for p4config files in all root directories of the all paths in
// the search path. NOTE: All directories in a path need to use the same clientspec
// or this function will return false.
// It returns false if it didn't find a p4config file.
virtual bool GetClientSpecForPath( const char *pPathId, char *pClientSpec, int nMaxLen ) = 0;
// Opens a file in p4 win
virtual void OpenFileInP4Win( const char *pFullPath ) = 0;
// have we connected? if not, nothing works
virtual bool IsConnectedToServer( bool bRetry = true ) = 0;
// Returns file information for a single file
virtual bool GetFileInfo( const char *pFullPath, P4File_t *pFileInfo ) = 0;
// retrieves the list of files in a path, using a known client spec
virtual CUtlVector<P4File_t> &GetFileListUsingClientSpec( const char *pPath, const char *pClientSpec ) = 0;
// retrieves the last error from the last op (which is likely to span multiple lines)
// this is only valid after OpenFile[s]For{Add,Edit,Delete} or {Submit,Revert}File[s]
virtual const char *GetLastError() = 0;
// sets the name of the changelist to open files under, NULL for "Default" changelist
virtual void SetOpenFileChangeList( const char *pChangeListName ) = 0;
virtual void GetFileListInChangelist( unsigned int changeListNumber, CUtlVector<P4File_t> &fileList ) = 0;
};
DECLARE_TIER2_INTERFACE( IP4, p4 );
#endif // IP4_H

116
external/vpc/public/tier0/annotations.h vendored Normal file
View File

@@ -0,0 +1,116 @@
#ifndef ANALYSIS_ANNOTATIONS_H
#define ANALYSIS_ANNOTATIONS_H
#if _MSC_VER >= 1600 // VS 2010 and above.
//-----------------------------------------------------------------------------
// Upgrading important helpful warnings to errors
//-----------------------------------------------------------------------------
#pragma warning(error : 4789 ) // warning C4789: destination of memory copy is too small
// Suppress some code analysis warnings
#ifdef _PREFAST_
// Include the annotation header file.
#include <sal.h>
// /Analyze warnings can only be suppressed when using a compiler that supports them, which VS 2010
// Professional does not.
// We don't care about these warnings because they are bugs that can only occur during resource
// exhaustion or other unexpected API failure, which we are nowhere near being able to handle.
#pragma warning(disable : 6308) // warning C6308: 'realloc' might return null pointer: assigning null pointer to 's_ppTestCases', which is passed as an argument to 'realloc', will cause the original memory block to be leaked
#pragma warning(disable : 6255) // warning C6255: _alloca indicates failure by raising a stack overflow exception. Consider using _malloca instead
#pragma warning(disable : 6387) // warning C6387: 'argument 1' might be '0': this does not adhere to the specification for the function 'GetProcAddress'
#pragma warning(disable : 6309) // warning C6309: Argument '1' is null: this does not adhere to function specification of 'GetProcAddress'
#pragma warning(disable : 6011) // warning C6011: Dereferencing NULL pointer 'm_ppTestCases'
#pragma warning(disable : 6211) // warning C6211: Leaking memory 'newKeyValue' due to an exception. Consider using a local catch block to clean up memory
#pragma warning(disable : 6031) // warning C6031: Return value ignored: '_getcwd'
// These warnings are because /analyze doesn't like our use of constants, especially things like IsPC()
#pragma warning(disable : 6326) // warning C6326: Potential comparison of a constant with another constant
#pragma warning(disable : 6239) // warning C6239: (<non-zero constant> && <expression>) always evaluates to the result of <expression>. Did you intend to use the bitwise-and operator?
#pragma warning(disable : 6285) // warning C6285: (<non-zero constant> || <non-zero constant>) is always a non-zero constant. Did you intend to use the bitwise-and operator?
#pragma warning(disable : 6237) // warning C6237: (<zero> && <expression>) is always zero. <expression> is never evaluated and might have side effects
#pragma warning(disable : 6235) // warning C6235: (<non-zero constant> || <expression>) is always a non-zero constant
#pragma warning(disable : 6240) // warning C6240: (<expression> && <non-zero constant>) always evaluates to the result of <expression>. Did you intend to use the bitwise-and operator?
// These warnings aren't really important:
#pragma warning(disable : 6323) // warning C6323: Use of arithmetic operator on Boolean type(s)
// Miscellaneous other /analyze warnings. We should consider fixing these at some point.
//#pragma warning(disable : 6204) // warning C6204: Possible buffer overrun in call to 'memcpy': use of unchecked parameter 'src'
//#pragma warning(disable : 6262) // warning C6262: Function uses '16464' bytes of stack: exceeds /analyze:stacksize'16384'. Consider moving some data to heap
// This is a serious warning. Don't suppress it.
//#pragma warning(disable : 6263) // warning C6263: Using _alloca in a loop: this can quickly overflow stack
// 6328 is also used for passing __int64 to printf when int is expected so we can't suppress it.
//#pragma warning(disable : 6328) // warning C6328: 'char' passed as parameter '1' when 'unsigned char' is required in call to 'V_isdigit'
// /analyze doesn't like GCOMPILER_ASSERT's implementation of compile-time asserts
#pragma warning(disable : 6326) // warning C6326: Potential comparison of a constant with another constant
#pragma warning(disable : 6335) // warning C6335: Leaking process information handle 'pi.hThread'
#pragma warning(disable : 6320) // warning C6320: Exception-filter expression is the constant EXCEPTION_EXECUTE_HANDLER. This might mask exceptions that were not intended to be handled
#pragma warning(disable : 6250) // warning C6250: Calling 'VirtualFree' without the MEM_RELEASE flag might free memory but not address descriptors (VADs). This causes address space leaks
#pragma warning(disable : 6384) // ientity2_class_h_schema_gen.cpp(76): warning C6384: Dividing sizeof a pointer by another value
// For temporarily suppressing warnings -- the warnings are suppressed for the next source line.
#define ANALYZE_SUPPRESS(wnum) __pragma(warning(suppress: wnum))
#define ANALYZE_SUPPRESS2(wnum1, wnum2) __pragma(warning(supress: wnum1 wnum2))
#define ANALYZE_SUPPRESS3(wnum1, wnum2, wnum3) __pragma(warning(suppress: wnum1 wnum2 wnum3))
#define ANALYZE_SUPPRESS4(wnum1, wnum2, wnum3, wnum4) __pragma(warning(suppress: wnum1 wnum2 wnum3 wnum4))
// Tag all printf style format strings with this
#define PRINTF_FORMAT_STRING _Printf_format_string_
#define SCANF_FORMAT_STRING _Scanf_format_string_impl_
// Various macros for specifying the capacity of the buffer pointed
// to by a function parameter. Variations include in/out/inout,
// CAP (elements) versus BYTECAP (bytes), and null termination or
// not (_Z).
#define IN_Z _In_z_
#define IN_CAP(x) _In_count_(x)
#define IN_BYTECAP(x) _In_bytecount_(x)
#define OUT_Z_CAP(x) _Out_z_cap_(x)
#define OUT_CAP(x) _Out_cap_(x)
#define OUT_BYTECAP(x) _Out_bytecap_(x)
#define OUT_Z_BYTECAP(x) _Out_z_bytecap_(x)
#define INOUT_BYTECAP(x) _Inout_bytecap_(x)
#define INOUT_Z_CAP(x) _Inout_z_cap_(x)
#define INOUT_Z_BYTECAP(x) _Inout_z_bytecap_(x)
// These macros are use for annotating array reference parameters, typically used in functions
// such as V_strcpy_safe. Because they are array references the capacity is already known.
#if _MSC_VER >= 1700
#define IN_Z_ARRAY _Pre_z_
#define OUT_Z_ARRAY _Post_z_
#define INOUT_Z_ARRAY _Prepost_z_
#else
#define IN_Z_ARRAY _Deref_pre_z_
#define OUT_Z_ARRAY _Deref_post_z_
#define INOUT_Z_ARRAY _Deref_prepost_z_
#endif // _MSC_VER >= 1700
// Use the macros above to annotate string functions that fill buffers as shown here,
// in order to give VS's /analyze more opportunities to find bugs.
// void V_wcsncpy( OUT_Z_BYTECAP(maxLenInBytes) wchar_t *pDest, wchar_t const *pSrc, int maxLenInBytes );
// int V_snwprintf( OUT_Z_CAP(maxLenInCharacters) wchar_t *pDest, int maxLenInCharacters, PRINTF_FORMAT_STRING const wchar_t *pFormat, ... );
#endif // _PREFAST_
#endif // _MSC_VER >= 1600 // VS 2010 and above.
#ifndef ANALYZE_SUPPRESS
#define ANALYZE_SUPPRESS(wnum)
#define ANALYZE_SUPPRESS2(wnum1, wnum2)
#define ANALYZE_SUPPRESS3(wnum1, wnum2, wnum3)
#define ANALYZE_SUPPRESS4(wnum1, wnum2, wnum3, wnum4)
#define PRINTF_FORMAT_STRING
#define SCANF_FORMAT_STRING
#define IN_Z
#define IN_CAP(x)
#define IN_BYTECAP(x)
#define OUT_Z_CAP(x)
#define OUT_CAP(x)
#define OUT_BYTECAP(x)
#define OUT_Z_BYTECAP(x)
#define INOUT_BYTECAP(x)
#define INOUT_Z_CAP(x)
#define INOUT_Z_BYTECAP(x)
#define OUT_Z_ARRAY
#define INOUT_Z_ARRAY
#endif
#endif // ANALYSIS_ANNOTATIONS_H

650
external/vpc/public/tier0/basetypes.h vendored Normal file
View File

@@ -0,0 +1,650 @@
//========= Copyright 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#ifndef BASETYPES_H
#define BASETYPES_H
#ifdef COMPILER_MSVC
#pragma once
#endif
// This is a trick to get the DLL extension off the -D option on the command line.
#define DLLExtTokenPaste(x) #x
#define DLLExtTokenPaste2(x) DLLExtTokenPaste(x)
#define DLL_EXT_STRING DLLExtTokenPaste2( _DLL_EXT )
//////////////////////////////////////////////////////////////////////////
#ifndef schema
#define schema namespace ValveSchemaMarker {}
#endif
#ifdef COMPILING_SCHEMA
#define UNSCHEMATIZED_METHOD( x )
#else
#define UNSCHEMATIZED_METHOD( x ) x
#endif
//////////////////////////////////////////////////////////////////////////
#include "tier0/platform.h"
#include "commonmacros.h"
#include "wchartypes.h"
#ifdef _PS3
#include <float.h>
#elif defined( PLATFORM_POSIX )
#include <math.h>
#endif
#include "tier0/valve_off.h"
// There's a different version of this file in the xbox codeline
// so the PC version built in the xbox branch includes things like
// tickrate changes.
#include "xbox_codeline_defines.h"
#if defined(_PS3)
#include <ppu_intrinsics.h>
#include <sys/fs.h>
#define PATH_MAX CELL_FS_MAX_FS_PATH_LENGTH
#define _MAX_PATH PATH_MAX
#endif
// stdio.h
#ifndef NULL
#define NULL 0
#endif
#ifdef PLATFORM_POSIX
#include <stdint.h>
template<class T>
T abs( const T &a )
{
if ( a < 0 )
return -a;
else
return a;
}
#endif
#define ExecuteNTimes( nTimes, x ) \
{ \
static int __executeCount=0;\
if ( __executeCount < nTimes )\
{ \
++__executeCount; \
x; \
} \
}
#define ExecuteOnce( x ) ExecuteNTimes( 1, x )
// Pad a number so it lies on an N byte boundary.
// So PAD_NUMBER(0,4) is 0 and PAD_NUMBER(1,4) is 4
#define PAD_NUMBER(number, boundary) \
( ((number) + ((boundary)-1)) / (boundary) ) * (boundary)
// In case this ever changes
#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif
// #define COMPILETIME_MAX and COMPILETIME_MIN for max/min in constant expressions
#define COMPILETIME_MIN( a, b ) ( ( ( a ) < ( b ) ) ? ( a ) : ( b ) )
#define COMPILETIME_MAX( a, b ) ( ( ( a ) > ( b ) ) ? ( a ) : ( b ) )
#ifndef MIN
#define MIN( a, b ) ( ( ( a ) < ( b ) ) ? ( a ) : ( b ) )
#endif
#ifndef MAX
#define MAX( a, b ) ( ( ( a ) > ( b ) ) ? ( a ) : ( b ) )
#endif
#ifdef __cplusplus
template< class T, class Y, class X >
inline T clamp( T const &val, Y const &minVal, X const &maxVal )
{
if( val < minVal )
return minVal;
else if( val > maxVal )
return maxVal;
else
return val;
}
#else
#define clamp(val, min, max) (((val) > (max)) ? (max) : (((val) < (min)) ? (min) : (val)))
#endif
#ifndef FALSE
#define FALSE 0
#define TRUE (!FALSE)
#endif
//-----------------------------------------------------------------------------
// fsel
//-----------------------------------------------------------------------------
#if !defined(_PS3) && !defined(_X360)
#define fsel(c,x,y) ( (c) >= 0 ? (x) : (y) )
// integer conditional move
// if a >= 0, return x, else y
#define isel(a,x,y) ( ((a) >= 0) ? (x) : (y) )
// if x = y, return a, else b
#define ieqsel(x,y,a,b) (( (x) == (y) ) ? (a) : (b))
// if the nth bit of a is set (counting with 0 = LSB),
// return x, else y
// this is fast if nbit is a compile-time immediate
#define ibitsel(a, nbit, x, y) ( ( ((a) & (1 << (nbit))) != 0 ) ? (x) : (y) )
FORCEINLINE double fpmin( double a, double b )
{
return a > b ? b : a;
}
FORCEINLINE double fpmax( double a, double b )
{
return a >= b ? a : b;
}
// clamp x to lie inside [a,b]. Assumes b>a
FORCEINLINE float fclamp( float x, float a, float b )
{
return fpmin( fpmax( x, a ), b );
}
// clamp x to lie inside [a,b]. Assumes b>a
FORCEINLINE double fclamp( double x, double a, double b )
{
return fpmin( fpmax( x, a ), b );
}
// At some point, we will need a unified API.
#define imin( x, y ) ( (x) < (y) ? (x) : (y) )
#define imax( x, y ) ( (x) > (y) ? (x) : (y) )
#define iclamp clamp
#else
// __fsel(double fComparand, double fValGE, double fLT) == fComparand >= 0 ? fValGE : fLT
// this is much faster than if ( aFloat > 0 ) { x = .. }
// the XDK defines two intrinsics, one for floats and one for doubles -- it's the same
// opcode, but the __fself version tells the compiler not to do a wasteful unnecessary
// rounding op after each sel.
// #define fsel __fsel
#ifdef _X360
FORCEINLINE double fsel(double fComparand, double fValGE, double fLT) { return __fsel( fComparand, fValGE, fLT ); }
FORCEINLINE float fsel(float fComparand, float fValGE, float fLT) { return __fself( fComparand, fValGE, fLT ); }
#else
FORCEINLINE double fsel(double fComparand, double fValGE, double fLT) { return __fsel( fComparand, fValGE, fLT ); }
FORCEINLINE float fsel(float fComparand, float fValGE, float fLT) { return __fsels( fComparand, fValGE, fLT ); }
#endif
#if !defined(_X360)
FORCEINLINE float fpmin( float a, float b )
{
return fsel( a-b, b,a);
}
FORCEINLINE double fpmin( double a, double b )
{
return fsel( a-b, b,a);
}
FORCEINLINE float fpmax( float a, float b )
{
return fsel( a-b, a,b);
}
FORCEINLINE double fpmax( double a, double b )
{
return fsel( a-b, a,b);
}
// any mixed calls should promote to double
FORCEINLINE double fpmax(float a, double b)
{
return fpmax( (double) a, b );
}
// any mixed calls should promote to double
FORCEINLINE double fpmax(double a, float b)
{
return fpmax( (double) a, (double) b );
}
#endif
// clamp x to lie inside [a,b]. Assumes b>a
FORCEINLINE float fclamp( float x, float a, float b )
{
return fpmin( fpmax( x, a ), b );
}
// clamp x to lie inside [a,b]. Assumes b>a
FORCEINLINE double fclamp( double x, double a, double b )
{
return fpmin( fpmax( x, a ), b );
}
// if a >= 0, return x, else y
FORCEINLINE int isel( int a, int x, int y )
{
int mask = a >> 31; // arithmetic shift right, splat out the sign bit
return x + ((y - x) & mask);
};
// if a >= 0, return x, else y
FORCEINLINE unsigned isel( int a, unsigned x, unsigned y )
{
int mask = a >> 31; // arithmetic shift right, splat out the sign bit
return x + ((y - x) & mask);
};
// ( x == y ) ? a : b
FORCEINLINE unsigned ieqsel( unsigned x, unsigned y, unsigned a, unsigned b )
{
unsigned mask = (x == y) ? 0 : -1;
return a + ((b - a) & mask);
};
// ( x == y ) ? a : b
FORCEINLINE int ieqsel( int x, int y, int a, int b )
{
int mask = (x == y) ? 0 : -1;
return a + ((b - a) & mask);
};
FORCEINLINE int imin( int x, int y )
{
int nMaxSign = x - y; // Positive if x greater than y
int nMaxMask = nMaxSign >> 31; // 0 if x greater than y, 0xffffffff if x smaller than y
int nMaxSaturated = y + ( nMaxSign & nMaxMask );
return nMaxSaturated;
}
FORCEINLINE int imax( int x, int y )
{
int nMinSign = y - x; // Positive if x smaller than y
int nMinMask = nMinSign >> 31; // 0 if x smaller than y, 0xffffffff if x greater than y
int nMinSaturated = y - ( nMinSign & nMinMask);
return nMinSaturated;
}
FORCEINLINE int iclamp( int x, int min, int max )
{
int nResult = imin( x, max );
return imax( nResult, min );
}
// if the nth bit of a is set (counting with 0 = LSB),
// return x, else y
// this is fast if nbit is a compile-time immediate
#define ibitsel(a, nbit, x, y) ( (x) + (((y) - (x)) & (((a) & (1 << (nbit))) ? 0 : -1)) )
#endif
#if CROSS_PLATFORM_VERSION < 1
#ifndef DONT_DEFINE_BOOL // Needed for Cocoa stuff to compile.
typedef int BOOL;
#endif
typedef int qboolean;
//typedef uint32 ULONG;
typedef uint8 BYTE;
typedef uint8 byte;
typedef uint16 word;
#endif
#if defined( _WIN32 ) || defined( _PS3 )
typedef wchar_t ucs2; // under windows & PS3 wchar_t is ucs2
#else
typedef unsigned short ucs2;
#endif
enum ThreeState_t
{
TRS_FALSE,
TRS_TRUE,
TRS_NONE,
};
typedef float vec_t;
#ifdef _WIN32
typedef __int32 vec_t_as_gpr; // a general purpose register type equal in size to a vec_t (in case we have to avoid the fpu for some reason)
#endif
template <typename T>
inline T AlignValue( T val, uintp alignment )
{
return (T)( ( (uintp)val + alignment - 1 ) & ~( alignment - 1 ) );
}
// FIXME: this should move
#ifndef __cplusplus
#define true TRUE
#define false FALSE
#endif
//-----------------------------------------------------------------------------
// look for NANs, infinities, and underflows.
// This assumes the ANSI/IEEE 754-1985 standard
//-----------------------------------------------------------------------------
#ifdef __cplusplus
inline uint32 FloatBits( const vec_t &f )
{
union Convertor_t
{
vec_t f;
uint32 ul;
}tmp;
switch( false ) { case false: ; case (sizeof( tmp ) == 4 && sizeof( tmp.f ) == 4 && sizeof( tmp.ul ) == 4):; };
tmp.f = f;
return tmp.ul;
}
inline vec_t BitsToFloat( uint32 i )
{
union Convertor_t
{
vec_t f;
uint32 ul;
}tmp;
switch( false ) { case false: ; case (sizeof( tmp ) == 4 && sizeof( tmp.f ) == 4 && sizeof( tmp.ul ) == 4 ):; };
tmp.ul = i;
return tmp.f;
}
inline bool IsFinite( const vec_t &f )
{
#ifdef _GAMECONSOLE
return f == f && fabs(f) <= FLT_MAX;
#else
return ((FloatBits(f) & 0x7F800000) != 0x7F800000);
#endif
}
#if defined( WIN32 )
//#include <math.h>
// Just use prototype from math.h
#ifdef __cplusplus
extern "C"
{
#endif
double __cdecl fabs(double);
//_CRT_JIT_INTRINSIC _CRTIMP float __cdecl fabsf( __in float _X);
float __cdecl fabsf( _In_ float );
#ifdef __cplusplus
}
#endif
// In win32 try to use the intrinsic fabs so the optimizer can do it's thing inline in the code
#pragma intrinsic( fabs )
// Also, alias float make positive to use fabs, too
// NOTE: Is there a perf issue with double<->float conversion?
inline float FloatMakePositive( vec_t f )
{
return fabsf( f );
}
#else
inline float FloatMakePositive( vec_t f )
{
return fabsf(f); // was since 2002: BitsToFloat( FloatBits(f) & 0x7FFFFFFF ); fixed in 2010
}
#endif
inline float FloatNegate( vec_t f )
{
return -f; //BitsToFloat( FloatBits(f) ^ 0x80000000 );
}
#define FLOAT32_NAN_BITS (uint32)0x7FC00000 // not a number!
#define FLOAT32_NAN BitsToFloat( FLOAT32_NAN_BITS )
#define VEC_T_NAN FLOAT32_NAN
#endif
inline float FloatMakeNegative( vec_t f )
{
return -fabsf( f );// was since 2002: BitsToFloat( FloatBits(f) | 0x80000000 ); fixed in 2010
}
// FIXME: why are these here? Hardly anyone actually needs them.
struct color24
{
::byte r, g, b;
};
typedef struct color32_s
{
bool operator!=( const struct color32_s &other ) const;
::byte r, g, b, a;
// assign and copy by using the whole register rather
// than byte-by-byte copy. (No, the compiler is not
// smart enough to do this for you. /FAcs if you
// don't believe me.)
inline unsigned *asInt(void) { return reinterpret_cast<unsigned*>(this); }
inline const unsigned *asInt(void) const { return reinterpret_cast<const unsigned*>(this); }
// This thing is in a union elsewhere, and union members can't have assignment
// operators, so you have to explicitly assign using this, or be slow. SUCK.
inline void Copy(const color32_s &rhs)
{
*asInt() = *rhs.asInt();
}
} color32;
inline bool color32::operator!=( const color32 &other ) const
{
return r != other.r || g != other.g || b != other.b || a != other.a;
}
struct colorVec
{
unsigned r, g, b, a;
};
#ifndef NOTE_UNUSED
#define NOTE_UNUSED(arg) ((void)arg) // for pesky compiler / lint warnings
#endif
#ifdef __cplusplus
struct vrect_t
{
int x,y,width,height;
vrect_t *pnext;
};
#endif
//-----------------------------------------------------------------------------
// MaterialRect_t struct - used for DrawDebugText
//-----------------------------------------------------------------------------
struct Rect_t
{
int x, y;
int width, height;
};
struct Rect3D_t
{
int x, y, z;
int width, height, depth;
FORCEINLINE Rect3D_t( int nX, int nY, int nZ, int nWidth, int nHeight, int nDepth )
{
x = nX;
y = nY;
z = nZ;
width = nWidth;
height = nHeight;
depth = nDepth;
}
FORCEINLINE Rect3D_t( void )
{
}
};
//-----------------------------------------------------------------------------
// Interval, used by soundemittersystem + the game
//-----------------------------------------------------------------------------
struct interval_t
{
float start;
float range;
};
//-----------------------------------------------------------------------------
// Declares a type-safe handle type; you can't assign one handle to the next
//-----------------------------------------------------------------------------
// 32-bit pointer handles.
// Typesafe 8-bit and 16-bit handles.
template< class HandleType >
class CBaseIntHandle
{
public:
inline bool operator==( const CBaseIntHandle &other ) { return m_Handle == other.m_Handle; }
inline bool operator!=( const CBaseIntHandle &other ) { return m_Handle != other.m_Handle; }
// Only the code that doles out these handles should use these functions.
// Everyone else should treat them as a transparent type.
inline HandleType GetHandleValue() { return m_Handle; }
inline void SetHandleValue( HandleType val ) { m_Handle = val; }
typedef HandleType HANDLE_TYPE;
protected:
HandleType m_Handle;
};
template< class DummyType >
class CIntHandle16 : public CBaseIntHandle< unsigned short >
{
public:
inline CIntHandle16() {}
static inline CIntHandle16<DummyType> MakeHandle( HANDLE_TYPE val )
{
return CIntHandle16<DummyType>( val );
}
protected:
inline CIntHandle16( HANDLE_TYPE val )
{
m_Handle = val;
}
};
template< class DummyType >
class CIntHandle32 : public CBaseIntHandle< uint32 >
{
public:
inline CIntHandle32() {}
static inline CIntHandle32<DummyType> MakeHandle( HANDLE_TYPE val )
{
return CIntHandle32<DummyType>( val );
}
protected:
inline CIntHandle32( HANDLE_TYPE val )
{
m_Handle = val;
}
};
// NOTE: This macro is the same as windows uses; so don't change the guts of it
#define DECLARE_HANDLE_16BIT(name) typedef CIntHandle16< struct name##__handle * > name;
#define DECLARE_HANDLE_32BIT(name) typedef CIntHandle32< struct name##__handle * > name;
#define DECLARE_POINTER_HANDLE(name) struct name##__ { int unused; }; typedef struct name##__ *name
#define FORWARD_DECLARE_HANDLE(name) typedef struct name##__ *name
#define DECLARE_DERIVED_POINTER_HANDLE( _name, _basehandle ) struct _name##__ : public _basehandle##__ {}; typedef struct _name##__ *_name
#define DECLARE_ALIASED_POINTER_HANDLE( _name, _alias ) typedef struct _alias##__ *name
// @TODO: Find a better home for this
#if !defined(_STATIC_LINKED) && !defined(PUBLISH_DLL_SUBSYSTEM)
// for platforms built with dynamic linking, the dll interface does not need spoofing
#define PUBLISH_DLL_SUBSYSTEM()
#endif
#define UID_PREFIX generated_id_
#define UID_CAT1(a,c) a ## c
#define UID_CAT2(a,c) UID_CAT1(a,c)
#define EXPAND_CONCAT(a,c) UID_CAT1(a,c)
#ifdef _MSC_VER
#define UNIQUE_ID UID_CAT2(UID_PREFIX,__COUNTER__)
#else
#define UNIQUE_ID UID_CAT2(UID_PREFIX,__LINE__)
#endif
#define _MKSTRING(arg) #arg
#define MKSTRING(arg) _MKSTRING(arg)
// this allows enumerations to be used as flags, and still remain type-safe!
#define DEFINE_ENUM_BITWISE_OPERATORS( Type ) \
inline Type operator| ( Type a, Type b ) { return Type( int( a ) | int( b ) ); } \
inline Type operator& ( Type a, Type b ) { return Type( int( a ) & int( b ) ); } \
inline Type operator^ ( Type a, Type b ) { return Type( int( a ) ^ int( b ) ); } \
inline Type operator<< ( Type a, int b ) { return Type( int( a ) << b ); } \
inline Type operator>> ( Type a, int b ) { return Type( int( a ) >> b ); } \
inline Type &operator|= ( Type &a, Type b ) { return a = a | b; } \
inline Type &operator&= ( Type &a, Type b ) { return a = a & b; } \
inline Type &operator^= ( Type &a, Type b ) { return a = a ^ b; } \
inline Type &operator<<=( Type &a, int b ) { return a = a << b; } \
inline Type &operator>>=( Type &a, int b ) { return a = a >> b; } \
inline Type operator~( Type a ) { return Type( ~int( a ) ); }
// defines increment/decrement operators for enums for easy iteration
#define DEFINE_ENUM_INCREMENT_OPERATORS( Type ) \
inline Type &operator++( Type &a ) { return a = Type( int( a ) + 1 ); } \
inline Type &operator--( Type &a ) { return a = Type( int( a ) - 1 ); } \
inline Type operator++( Type &a, int ) { Type t = a; ++a; return t; } \
inline Type operator--( Type &a, int ) { Type t = a; --a; return t; }
// Max 2 player splitscreen in portal (don't merge this back), saves a bunch of memory [8/31/2010 tom]
#define MAX_SPLITSCREEN_CLIENT_BITS 1
// this should == MAX_JOYSTICKS in InputEnums.h
#define MAX_SPLITSCREEN_CLIENTS ( 1 << MAX_SPLITSCREEN_CLIENT_BITS ) // 2
#include "tier0/valve_on.h"
#endif // BASETYPES_H

149
external/vpc/public/tier0/commonmacros.h vendored Normal file
View File

@@ -0,0 +1,149 @@
//========= Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//
//=============================================================================//
#ifndef COMMONMACROS_H
#define COMMONMACROS_H
#ifdef _WIN32
#pragma once
#endif
// -------------------------------------------------------
//
// commonmacros.h
//
// This should contain ONLY general purpose macros that are
// appropriate for use in engine/launcher/all tools
//
// -------------------------------------------------------
// Makes a 4-byte "packed ID" int out of 4 characters
#define MAKEID(d,c,b,a) ( ((int)(a) << 24) | ((int)(b) << 16) | ((int)(c) << 8) | ((int)(d)) )
// Compares a string with a 4-byte packed ID constant
#define STRING_MATCHES_ID( p, id ) ( (*((int *)(p)) == (id) ) ? true : false )
#define ID_TO_STRING( id, p ) ( (p)[3] = (((id)>>24) & 0xFF), (p)[2] = (((id)>>16) & 0xFF), (p)[1] = (((id)>>8) & 0xFF), (p)[0] = (((id)>>0) & 0xFF) )
#define V_ARRAYSIZE(p) (sizeof(p)/sizeof(p[0]))
#define SETBITS(iBitVector, bits) ((iBitVector) |= (bits))
#define CLEARBITS(iBitVector, bits) ((iBitVector) &= ~(bits))
#define FBitSet(iBitVector, bits) ((iBitVector) & (bits))
inline bool IsPowerOfTwo( int value )
{
return (value & ( value - 1 )) == 0;
}
#ifndef REFERENCE
#define REFERENCE(arg) ((void)arg)
#endif
#define CONST_INTEGER_AS_STRING(x) #x //Wraps the integer in quotes, allowing us to form constant strings with it
#define __HACK_LINE_AS_STRING__(x) CONST_INTEGER_AS_STRING(x) //__LINE__ can only be converted to an actual number by going through this, otherwise the output is literally "__LINE__"
#define __LINE__AS_STRING __HACK_LINE_AS_STRING__(__LINE__) //Gives you the line number in constant string form
// Using ARRAYSIZE implementation from winnt.h:
#ifdef ARRAYSIZE
#undef ARRAYSIZE
#endif
// Return the number of elements in a statically sized array.
// DWORD Buffer[100];
// RTL_NUMBER_OF(Buffer) == 100
// This is also popularly known as: NUMBER_OF, ARRSIZE, _countof, NELEM, etc.
//
#define RTL_NUMBER_OF_V1(A) (sizeof(A)/sizeof((A)[0]))
#if defined(__cplusplus) && \
!defined(MIDL_PASS) && \
!defined(RC_INVOKED) && \
!defined(_PREFAST_) && \
(_MSC_FULL_VER >= 13009466) && \
!defined(SORTPP_PASS)
// From crtdefs.h
#if !defined(UNALIGNED)
#if defined(_M_IA64) || defined(_M_AMD64)
#define UNALIGNED __unaligned
#else
#define UNALIGNED
#endif
#endif
// RtlpNumberOf is a function that takes a reference to an array of N Ts.
//
// typedef T array_of_T[N];
// typedef array_of_T &reference_to_array_of_T;
//
// RtlpNumberOf returns a pointer to an array of N chars.
// We could return a reference instead of a pointer but older compilers do not accept that.
//
// typedef char array_of_char[N];
// typedef array_of_char *pointer_to_array_of_char;
//
// sizeof(array_of_char) == N
// sizeof(*pointer_to_array_of_char) == N
//
// pointer_to_array_of_char RtlpNumberOf(reference_to_array_of_T);
//
// We never even call RtlpNumberOf, we just take the size of dereferencing its return type.
// We do not even implement RtlpNumberOf, we just decare it.
//
// Attempts to pass pointers instead of arrays to this macro result in compile time errors.
// That is the point.
extern "C++" // templates cannot be declared to have 'C' linkage
template <typename T, size_t N>
char (*RtlpNumberOf( UNALIGNED T (&)[N] ))[N];
#define RTL_NUMBER_OF_V2(A) (sizeof(*RtlpNumberOf(A)))
// This does not work with:
//
// void Foo()
// {
// struct { int x; } y[2];
// RTL_NUMBER_OF_V2(y); // illegal use of anonymous local type in template instantiation
// }
//
// You must instead do:
//
// struct Foo1 { int x; };
//
// void Foo()
// {
// Foo1 y[2];
// RTL_NUMBER_OF_V2(y); // ok
// }
//
// OR
//
// void Foo()
// {
// struct { int x; } y[2];
// RTL_NUMBER_OF_V1(y); // ok
// }
//
// OR
//
// void Foo()
// {
// struct { int x; } y[2];
// _ARRAYSIZE(y); // ok
// }
#else
#define RTL_NUMBER_OF_V2(A) RTL_NUMBER_OF_V1(A)
#endif
// ARRAYSIZE is more readable version of RTL_NUMBER_OF_V2
// _ARRAYSIZE is a version useful for anonymous types
#define ARRAYSIZE(A) RTL_NUMBER_OF_V2(A)
#define _ARRAYSIZE(A) RTL_NUMBER_OF_V1(A)
#endif // COMMONMACROS_H

716
external/vpc/public/tier0/dbg.h vendored Normal file
View File

@@ -0,0 +1,716 @@
//===== Copyright (c) Valve Corporation, All rights reserved. ========//
//
// Purpose:
//
// $NoKeywords: $
//
//====================================================================//
#ifndef DBG_H
#define DBG_H
#ifdef _WIN32
#pragma once
#endif
#include "tier0/platform.h"
#include "tier0/basetypes.h"
#include "dbgflag.h"
#include "logging.h"
#include <math.h>
#include <stdio.h>
#include <stdarg.h>
//-----------------------------------------------------------------------------
// dll export stuff
//-----------------------------------------------------------------------------
class Color;
//-----------------------------------------------------------------------------
// Usage model for the Dbg library
//
// 1. Assertions.
//
// Assertions are used to detect and warn about invalid states
//
// To use an assertion, use
//
// Assert( (f == 5) );
// AssertMsg( (f == 5), ("F needs to be %d here!\n", 5) );
// AssertFunc( (f == 5), BadFunc() );
// AssertEquals( f, 5 );
// AssertFloatEquals( f, 5.0f, 1e-3 );
//
// The first will simply report that an assertion failed on a particular
// code file and line. The second version will display a print-f formatted message
// along with the file and line, the third will display a generic message and
// will also cause the function BadFunc to be executed, and the last two
// will report an error if f is not equal to 5 (the last one asserts within
// a particular tolerance).
//
// 2. Code activation
//
// To cause code to be run only in debug builds, use DBG_CODE:
// An example is below.
//
// DBG_CODE(
// {
// int x = 5;
// ++x;
// }
// );
//
// Code can be activated based on the dynamic spew groups also. Use
//
// DBG_DCODE( "group", level,
// { int x = 5; ++x; }
// );
//
// 3. Breaking into the debugger.
//
// To cause an unconditional break into the debugger in debug builds only, use DBG_BREAK
//
// DBG_BREAK();
//
// You can force a break in any build (release or debug) using
//
// DebuggerBreak();
//-----------------------------------------------------------------------------
PLATFORM_INTERFACE void _ExitOnFatalAssert( const tchar* pFile, int line );
#if defined( DBGFLAG_STRINGS_STRIP )
#define DbgFlagMacro_ExitOnFatalAssert( pFile, line ) _ExitOnFatalAssert( "", 0 )
#else
#define DbgFlagMacro_ExitOnFatalAssert( pFile, line ) _ExitOnFatalAssert( pFile, line )
#endif
PLATFORM_INTERFACE bool ShouldUseNewAssertDialog();
PLATFORM_INTERFACE bool SetupWin32ConsoleIO();
// Returns true if they want to break in the debugger.
PLATFORM_INTERFACE bool DoNewAssertDialog( const tchar *pFile, int line, const tchar *pExpression );
#if defined( DBGFLAG_STRINGS_STRIP )
#define DbgFlagMacro_DoNewAssertDialog( pFile, line, pExpression ) DoNewAssertDialog( "", 0, "" )
#else
#define DbgFlagMacro_DoNewAssertDialog( pFile, line, pExpression ) DoNewAssertDialog( pFile, line, pExpression )
#endif
/* Used to define macros, never use these directly. */
#ifdef _PREFAST_
// When doing /analyze builds define the assert macros to be __analysis_assume. This tells
// the compiler to assume that the condition is true, which helps to suppress many
// warnings. This define is done in debug and release builds, but debug builds should be
// preferred for static analysis because some asserts are compiled out in release.
// The unfortunate !! is necessary because otherwise /analyze is incapable of evaluating
// all of the logical expressions that the regular compiler can handle.
#define _AssertMsg( _exp, _msg, _executeExp, _bFatal ) __analysis_assume( !!(_exp) )
#define _AssertMsgOnce( _exp, _msg, _bFatal ) __analysis_assume( !!(_exp) )
// Force asserts on for /analyze so that we get a __analysis_assume of all of the constraints.
#define DBGFLAG_ASSERT
#define DBGFLAG_ASSERTFATAL
#else
#define _AssertMsg( _exp, _msg, _executeExp, _bFatal ) \
do { \
if (!(_exp)) \
{ \
LoggingResponse_t ret = Log_Assert( "%s (%d) : %s\n", __TFILE__, __LINE__, _msg ); \
_executeExp; \
if ( ret == LR_DEBUGGER ) \
{ \
if ( !ShouldUseNewAssertDialog() || DbgFlagMacro_DoNewAssertDialog( __TFILE__, __LINE__, _msg ) ) \
DebuggerBreak(); \
if ( _bFatal ) \
DbgFlagMacro_ExitOnFatalAssert( __TFILE__, __LINE__ ); \
} \
} \
} while (0)
#define _AssertMsgOnce( _exp, _msg, _bFatal ) \
do { \
static bool fAsserted; \
if (!fAsserted ) \
{ \
_AssertMsg( _exp, _msg, (fAsserted = true), _bFatal ); \
} \
} while (0)
#endif
/* Spew macros... */
// AssertFatal macros
// AssertFatal is used to detect an unrecoverable error condition.
// If enabled, it may display an assert dialog (if DBGFLAG_ASSERTDLG is turned on or running under the debugger),
// and always terminates the application
#ifdef DBGFLAG_ASSERTFATAL
#define AssertFatal( _exp ) _AssertMsg( _exp, _T("Assertion Failed: ") _T(#_exp), ((void)0), true )
#define AssertFatalOnce( _exp ) _AssertMsgOnce( _exp, _T("Assertion Failed: ") _T(#_exp), true )
#define AssertFatalMsg( _exp, _msg ) _AssertMsg( _exp, _msg, ((void)0), true )
#define AssertFatalMsgOnce( _exp, _msg ) _AssertMsgOnce( _exp, _msg, true )
#define AssertFatalFunc( _exp, _f ) _AssertMsg( _exp, _T("Assertion Failed: " _T(#_exp), _f, true )
#define AssertFatalEquals( _exp, _expectedValue ) AssertFatalMsg2( (_exp) == (_expectedValue), _T("Expected %d but got %d!"), (_expectedValue), (_exp) )
#define AssertFatalFloatEquals( _exp, _expectedValue, _tol ) AssertFatalMsg2( fabs((_exp) - (_expectedValue)) <= (_tol), _T("Expected %f but got %f!"), (_expectedValue), (_exp) )
#define VerifyFatal( _exp ) AssertFatal( _exp )
#define VerifyEqualsFatal( _exp, _expectedValue ) AssertFatalEquals( _exp, _expectedValue )
#define AssertFatalMsg1( _exp, _msg, a1 ) AssertFatalMsg( _exp, (const tchar *)(CDbgFmtMsg( _msg, a1 )))
#define AssertFatalMsg2( _exp, _msg, a1, a2 ) AssertFatalMsg( _exp, (const tchar *)(CDbgFmtMsg( _msg, a1, a2 )))
#define AssertFatalMsg3( _exp, _msg, a1, a2, a3 ) AssertFatalMsg( _exp, (const tchar *)(CDbgFmtMsg( _msg, a1, a2, a3 )))
#define AssertFatalMsg4( _exp, _msg, a1, a2, a3, a4 ) AssertFatalMsg( _exp, (const tchar *)(CDbgFmtMsg( _msg, a1, a2, a3, a4 )))
#define AssertFatalMsg5( _exp, _msg, a1, a2, a3, a4, a5 ) AssertFatalMsg( _exp, (const tchar *)(CDbgFmtMsg( _msg, a1, a2, a3, a4, a5 )))
#define AssertFatalMsg6( _exp, _msg, a1, a2, a3, a4, a5, a6 ) AssertFatalMsg( _exp, (const tchar *)(CDbgFmtMsg( _msg, a1, a2, a3, a4, a5, a6 )))
#define AssertFatalMsg6( _exp, _msg, a1, a2, a3, a4, a5, a6 ) AssertFatalMsg( _exp, (const tchar *)(CDbgFmtMsg( _msg, a1, a2, a3, a4, a5, a6 )))
#define AssertFatalMsg7( _exp, _msg, a1, a2, a3, a4, a5, a6, a7 ) AssertFatalMsg( _exp, (const tchar *)(CDbgFmtMsg( _msg, a1, a2, a3, a4, a5, a6, a7 )))
#define AssertFatalMsg8( _exp, _msg, a1, a2, a3, a4, a5, a6, a7, a8 ) AssertFatalMsg( _exp, (const tchar *)(CDbgFmtMsg( _msg, a1, a2, a3, a4, a5, a6, a7, a8 )))
#define AssertFatalMsg9( _exp, _msg, a1, a2, a3, a4, a5, a6, a7, a8, a9 ) AssertFatalMsg( _exp, (const tchar *)(CDbgFmtMsg( _msg, a1, a2, a3, a4, a5, a6, a7, a8, a9 )))
#else // DBGFLAG_ASSERTFATAL
#define AssertFatal( _exp ) ((void)0)
#define AssertFatalOnce( _exp ) ((void)0)
#define AssertFatalMsg( _exp, _msg ) ((void)0)
#define AssertFatalMsgOnce( _exp, _msg ) ((void)0)
#define AssertFatalFunc( _exp, _f ) ((void)0)
#define AssertFatalEquals( _exp, _expectedValue ) ((void)0)
#define AssertFatalFloatEquals( _exp, _expectedValue, _tol ) ((void)0)
#define VerifyFatal( _exp ) (_exp)
#define VerifyEqualsFatal( _exp, _expectedValue ) (_exp)
#define AssertFatalMsg1( _exp, _msg, a1 ) ((void)0)
#define AssertFatalMsg2( _exp, _msg, a1, a2 ) ((void)0)
#define AssertFatalMsg3( _exp, _msg, a1, a2, a3 ) ((void)0)
#define AssertFatalMsg4( _exp, _msg, a1, a2, a3, a4 ) ((void)0)
#define AssertFatalMsg5( _exp, _msg, a1, a2, a3, a4, a5 ) ((void)0)
#define AssertFatalMsg6( _exp, _msg, a1, a2, a3, a4, a5, a6 ) ((void)0)
#define AssertFatalMsg6( _exp, _msg, a1, a2, a3, a4, a5, a6 ) ((void)0)
#define AssertFatalMsg7( _exp, _msg, a1, a2, a3, a4, a5, a6, a7 ) ((void)0)
#define AssertFatalMsg8( _exp, _msg, a1, a2, a3, a4, a5, a6, a7, a8 ) ((void)0)
#define AssertFatalMsg9( _exp, _msg, a1, a2, a3, a4, a5, a6, a7, a8, a9 ) ((void)0)
#endif // DBGFLAG_ASSERTFATAL
// lightweight assert macros: in theory, can be run in release without slowing it down
#if defined(_CERT) || defined(_RETAIL)
#define AssertAligned(PTR)
#else
# if defined( _X360 )
# define AssertAligned(PTR) __twnei( intp(PTR) & 0xF, 0 ) // trap if not equal to immediate value; unsigned comparison
# elif defined( DBGFLAG_ASSERT )
# define AssertAligned( adr ) Assert( ( ( ( intp ) ( adr ) ) & 0xf ) == 0 )
# else
# define AssertAligned(PTR)
# endif
#endif
// Assert macros
// Assert is used to detect an important but survivable error.
// It's only turned on when DBGFLAG_ASSERT is true.
#ifdef DBGFLAG_ASSERT
#define Assert( _exp ) _AssertMsg( _exp, _T("Assertion Failed: ") _T(#_exp), ((void)0), false )
#define AssertMsg_( _exp, _msg ) _AssertMsg( _exp, _msg, ((void)0), false )
#define AssertOnce( _exp ) _AssertMsgOnce( _exp, _T("Assertion Failed: ") _T(#_exp), false )
#define AssertMsgOnce( _exp, _msg ) _AssertMsgOnce( _exp, _msg, false )
#define AssertFunc( _exp, _f ) _AssertMsg( _exp, _T("Assertion Failed: ") _T(#_exp), _f, false )
#define AssertEquals( _exp, _expectedValue ) AssertMsg2( (_exp) == (_expectedValue), _T("Expected %d but got %d!"), (_expectedValue), (_exp) )
#define AssertFloatEquals( _exp, _expectedValue, _tol ) AssertMsg2( fabs((_exp) - (_expectedValue)) <= (_tol), _T("Expected %f but got %f!"), (_expectedValue), (_exp) )
#define Verify( _exp ) Assert( _exp )
#define VerifyEquals( _exp, _expectedValue ) AssertEquals( _exp, _expectedValue )
#define AssertMsg( _exp, _msg ) AssertMsg_( _exp, _T( _msg ) )
#define AssertMsg1( _exp, _msg, a1 ) AssertMsg_( _exp, (const tchar *)(CDbgFmtMsg( _T( _msg ), a1 )) )
#define AssertMsg2( _exp, _msg, a1, a2 ) AssertMsg_( _exp, (const tchar *)(CDbgFmtMsg( _T( _msg ), a1, a2 )) )
#define AssertMsg3( _exp, _msg, a1, a2, a3 ) AssertMsg_( _exp, (const tchar *)(CDbgFmtMsg( _T( _msg ), a1, a2, a3 )) )
#define AssertMsg4( _exp, _msg, a1, a2, a3, a4 ) AssertMsg_( _exp, (const tchar *)(CDbgFmtMsg( _T( _msg ), a1, a2, a3, a4 )) )
#define AssertMsg5( _exp, _msg, a1, a2, a3, a4, a5 ) AssertMsg_( _exp, (const tchar *)(CDbgFmtMsg( _T( _msg ), a1, a2, a3, a4, a5 )) )
#define AssertMsg6( _exp, _msg, a1, a2, a3, a4, a5, a6 ) AssertMsg_( _exp, (const tchar *)(CDbgFmtMsg( _T( _msg ), a1, a2, a3, a4, a5, a6 )) )
#define AssertMsg7( _exp, _msg, a1, a2, a3, a4, a5, a6, a7 ) AssertMsg_( _exp, (const tchar *)(CDbgFmtMsg( _T( _msg ), a1, a2, a3, a4, a5, a6, a7 )) )
#define AssertMsg8( _exp, _msg, a1, a2, a3, a4, a5, a6, a7, a8 ) AssertMsg_( _exp, (const tchar *)(CDbgFmtMsg( _T( _msg ), a1, a2, a3, a4, a5, a6, a7, a8 )) )
#define AssertMsg9( _exp, _msg, a1, a2, a3, a4, a5, a6, a7, a8, a9 ) AssertMsg_( _exp, (const tchar *)(CDbgFmtMsg( _T( _msg ), a1, a2, a3, a4, a5, a6, a7, a8, a9 )) )
#else // DBGFLAG_ASSERT
#define Assert( _exp ) ((void)0)
#define AssertOnce( _exp ) ((void)0)
#define AssertMsg( _exp, _msg ) ((void)0)
#define AssertMsgOnce( _exp, _msg ) ((void)0)
#define AssertFunc( _exp, _f ) ((void)0)
#define AssertEquals( _exp, _expectedValue ) ((void)0)
#define AssertFloatEquals( _exp, _expectedValue, _tol ) ((void)0)
#define Verify( _exp ) (_exp)
#define VerifyEquals( _exp, _expectedValue ) (_exp)
#define AssertMsg1( _exp, _msg, a1 ) ((void)0)
#define AssertMsg2( _exp, _msg, a1, a2 ) ((void)0)
#define AssertMsg3( _exp, _msg, a1, a2, a3 ) ((void)0)
#define AssertMsg4( _exp, _msg, a1, a2, a3, a4 ) ((void)0)
#define AssertMsg5( _exp, _msg, a1, a2, a3, a4, a5 ) ((void)0)
#define AssertMsg6( _exp, _msg, a1, a2, a3, a4, a5, a6 ) ((void)0)
#define AssertMsg6( _exp, _msg, a1, a2, a3, a4, a5, a6 ) ((void)0)
#define AssertMsg7( _exp, _msg, a1, a2, a3, a4, a5, a6, a7 ) ((void)0)
#define AssertMsg8( _exp, _msg, a1, a2, a3, a4, a5, a6, a7, a8 ) ((void)0)
#define AssertMsg9( _exp, _msg, a1, a2, a3, a4, a5, a6, a7, a8, a9 ) ((void)0)
#endif // DBGFLAG_ASSERT
#define STRINGIFY_INTERNAL(x) #x
#define STRINGIFY(x) STRINGIFY_INTERNAL(x)
#define FILE_LINE_FUNCTION_STRING __FILE__ "(" STRINGIFY(__LINE__) "):" __FUNCTION__ ":"
#define FILE_LINE_STRING __FILE__ "(" STRINGIFY(__LINE__) "):"
#define FUNCTION_LINE_STRING __FUNCTION__ "(" STRINGIFY(__LINE__) "): "
//////////////////////////////////////////////////////////////////////////
// Legacy Logging System
//////////////////////////////////////////////////////////////////////////
// Channels which map the legacy logging system to the new system.
// Channel for all default Msg/Warning/Error commands.
DECLARE_LOGGING_CHANNEL( LOG_GENERAL );
// Channel for all asserts.
DECLARE_LOGGING_CHANNEL( LOG_ASSERT );
// Channel for all ConMsg and ConColorMsg commands.
DECLARE_LOGGING_CHANNEL( LOG_CONSOLE );
// Channel for all DevMsg and DevWarning commands with level < 2.
DECLARE_LOGGING_CHANNEL( LOG_DEVELOPER );
// Channel for ConDMsg commands.
DECLARE_LOGGING_CHANNEL( LOG_DEVELOPER_CONSOLE );
// Channel for all DevMsg and DevWarning commands with level >= 2.
DECLARE_LOGGING_CHANNEL( LOG_DEVELOPER_VERBOSE );
// Legacy logging functions
PLATFORM_INTERFACE void Error( const tchar *pMsg, ... ) FMTFUNCTION( 1, 2 );
PLATFORM_INTERFACE void Error_SpewCallStack( int iMaxCallStackLength, const tchar *pMsg, ... ) FMTFUNCTION( 2, 3 );
#if defined( DBGFLAG_STRINGS_STRIP ) && !defined( TIER0_DLL_EXPORT )
#define Msg( ... ) ((void)0)
#define Warning( ... ) ((void)0)
#define Warning_SpewCallStack( ... ) ((void)0)
#define DevMsg( ... ) ((void)0)
#define DevWarning( ... ) ((void)0)
#define ConColorMsg( ... ) ((void)0)
#define ConMsg( ... ) ((void)0)
#define ConDMsg( ... ) ((void)0)
#define COM_TimestampedLog( ... ) ((void)0)
#else // #if defined( DBGFLAG_STRINGS_STRIP ) && !defined( TIER0_DLL_EXPORT )
PLATFORM_INTERFACE void Msg( const tchar* pMsg, ... );
PLATFORM_INTERFACE void Warning( const tchar *pMsg, ... ) FMTFUNCTION( 1, 2 );
PLATFORM_INTERFACE void Warning_SpewCallStack( int iMaxCallStackLength, const tchar *pMsg, ... ) FMTFUNCTION( 2, 3 );
#ifdef _PS3
PLATFORM_OVERLOAD void DevMsg( int level, const tchar* pMsg, ... ) FMTFUNCTION( 2, 3 );
PLATFORM_OVERLOAD void DevWarning( int level, const tchar *pMsg, ... ) FMTFUNCTION( 2, 3 );
PLATFORM_INTERFACE void DevMsg( const tchar* pMsg, ... ) FMTFUNCTION( 1, 2 );
PLATFORM_INTERFACE void DevWarning( const tchar *pMsg, ... ) FMTFUNCTION( 1, 2 );
PLATFORM_INTERFACE void ConColorMsg( const Color& clr, const tchar* pMsg, ... ) FMTFUNCTION( 2, 3 );
PLATFORM_INTERFACE void ConMsg( const tchar* pMsg, ... ) FMTFUNCTION( 1, 2 );
#else // !_PS3
PLATFORM_INTERFACE void DevMsg( int level, const tchar* pMsg, ... ) FMTFUNCTION( 2, 3 );
PLATFORM_INTERFACE void DevWarning( int level, const tchar *pMsg, ... ) FMTFUNCTION( 2, 3 );
PLATFORM_OVERLOAD void DevMsg( const tchar* pMsg, ... ) FMTFUNCTION( 1, 2 );
PLATFORM_OVERLOAD void DevWarning( const tchar *pMsg, ... ) FMTFUNCTION( 1, 2 );
PLATFORM_OVERLOAD void ConColorMsg( const Color& clr, const tchar* pMsg, ... ) FMTFUNCTION( 2, 3 );
PLATFORM_OVERLOAD void ConMsg( const tchar* pMsg, ... ) FMTFUNCTION( 1, 2 );
#endif // _PS3
PLATFORM_INTERFACE void ConDMsg( const tchar* pMsg, ... ) FMTFUNCTION( 1, 2 );
PLATFORM_INTERFACE void COM_TimestampedLog( char const *fmt, ... ) FMTFUNCTION( 1, 2 );
#endif // #if defined( DBGFLAG_STRINGS_STRIP ) && !defined( TIER0_DLL_EXPORT )
// You can use this macro like a runtime assert macro.
// If the condition fails, then Error is called with the message. This macro is called
// like AssertMsg, where msg must be enclosed in parenthesis:
//
// ErrorIfNot( bCondition, ("a b c %d %d %d", 1, 2, 3) );
#define ErrorIfNot( condition, msg ) \
if ( (condition) ) \
; \
else \
{ \
Error msg; \
}
#ifdef _DEBUG
#define DebugMsg(...) DevMsg(__VA_ARGS__)
#else
#define DebugMsg(...)
#endif
// @TODO: these callstack spew functions are currently disabled in the new logging system. Need to add support for these if desired.
PLATFORM_INTERFACE void _Warning_AlwaysSpewCallStack_Enable( bool bEnable );
PLATFORM_INTERFACE void _Warning_AlwaysSpewCallStack_Length( int iMaxCallStackLength );
PLATFORM_INTERFACE void _Error_AlwaysSpewCallStack_Enable( bool bEnable );
PLATFORM_INTERFACE void _Error_AlwaysSpewCallStack_Length( int iMaxCallStackLength );
/* Code macros, debugger interface */
#ifdef _DEBUG
#define DBG_CODE( _code ) if (0) ; else { _code }
#define DBG_CODE_NOSCOPE( _code ) _code
#define DBG_DCODE( _g, _l, _code ) if (IsSpewActive( _g, _l )) { _code } else {}
#define DBG_BREAK() DebuggerBreak() /* defined in platform.h */
#else /* not _DEBUG */
#define DBG_CODE( _code ) ((void)0)
#define DBG_CODE_NOSCOPE( _code )
#define DBG_DCODE( _g, _l, _code ) ((void)0)
#define DBG_BREAK() ((void)0)
#endif /* _DEBUG */
//-----------------------------------------------------------------------------
// Macro to assist in asserting constant invariants during compilation
#ifdef _DEBUG
#define COMPILE_TIME_ASSERT( pred ) switch(0){case 0:case pred:;}
#define ASSERT_INVARIANT( pred ) static void UNIQUE_ID() { COMPILE_TIME_ASSERT( pred ) }
#else
#define COMPILE_TIME_ASSERT( pred )
#define ASSERT_INVARIANT( pred )
#endif
#ifdef _DEBUG
template<typename DEST_POINTER_TYPE, typename SOURCE_POINTER_TYPE>
inline DEST_POINTER_TYPE assert_cast(SOURCE_POINTER_TYPE* pSource)
{
Assert( static_cast<DEST_POINTER_TYPE>(pSource) == dynamic_cast<DEST_POINTER_TYPE>(pSource) );
return static_cast<DEST_POINTER_TYPE>(pSource);
}
#else
#define assert_cast static_cast
#endif
//-----------------------------------------------------------------------------
// Templates to assist in validating pointers:
// Have to use these stubs so we don't have to include windows.h here.
PLATFORM_INTERFACE void _AssertValidReadPtr( void* ptr, int count = 1 );
PLATFORM_INTERFACE void _AssertValidWritePtr( void* ptr, int count = 1 );
PLATFORM_INTERFACE void _AssertValidReadWritePtr( void* ptr, int count = 1 );
PLATFORM_INTERFACE void _AssertValidStringPtr( const tchar* ptr, int maxchar );
#ifdef DBGFLAG_ASSERT
inline void AssertValidStringPtr( const tchar* ptr, int maxchar = 0xFFFFFF ) { _AssertValidStringPtr( ptr, maxchar ); }
template<class T> inline void AssertValidReadPtr( T* ptr, int count = 1 ) { _AssertValidReadPtr( (void*)ptr, count ); }
template<class T> inline void AssertValidWritePtr( T* ptr, int count = 1 ) { _AssertValidWritePtr( (void*)ptr, count ); }
template<class T> inline void AssertValidReadWritePtr( T* ptr, int count = 1 ) { _AssertValidReadWritePtr( (void*)ptr, count ); }
#define AssertValidThis() AssertValidReadWritePtr(this,sizeof(*this))
#else
inline void AssertValidStringPtr( const tchar* ptr, int maxchar = 0xFFFFFF ) { }
template<class T> inline void AssertValidReadPtr( T* ptr, int count = 1 ) { }
template<class T> inline void AssertValidWritePtr( T* ptr, int count = 1 ) { }
template<class T> inline void AssertValidReadWritePtr( T* ptr, int count = 1 ) { }
#define AssertValidThis()
#endif
//-----------------------------------------------------------------------------
// Macro to protect functions that are not reentrant
#ifdef _DEBUG
class CReentryGuard
{
public:
CReentryGuard(int *pSemaphore)
: m_pSemaphore(pSemaphore)
{
++(*m_pSemaphore);
}
~CReentryGuard()
{
--(*m_pSemaphore);
}
private:
int *m_pSemaphore;
};
#define ASSERT_NO_REENTRY() \
static int fSemaphore##__LINE__; \
Assert( !fSemaphore##__LINE__ ); \
CReentryGuard ReentryGuard##__LINE__( &fSemaphore##__LINE__ )
#else
#define ASSERT_NO_REENTRY()
#endif
// Tier0 uses these for string functions since this abstraction is normally done in tier1.
#ifdef POSIX
#define Tier0Internal_sntprintf snprintf
#define Tier0Internal_vsntprintf vsnprintf
#define Tier0Internal_vsnprintf vsnprintf
#else
#define Tier0Internal_sntprintf _sntprintf
#define Tier0Internal_vsntprintf _vsntprintf
#define Tier0Internal_vsnprintf _vsnprintf
#endif
//-----------------------------------------------------------------------------
//
// Purpose: Inline string formatter
//
#include "tier0/valve_off.h"
class CDbgFmtMsg
{
public:
CDbgFmtMsg(const tchar *pszFormat, ...)
{
va_list arg_ptr;
va_start(arg_ptr, pszFormat);
Tier0Internal_vsntprintf(m_szBuf, sizeof(m_szBuf)-1, pszFormat, arg_ptr);
va_end(arg_ptr);
m_szBuf[sizeof(m_szBuf)-1] = 0;
}
operator const tchar *() const
{
return m_szBuf;
}
private:
tchar m_szBuf[256];
};
#include "tier0/valve_on.h"
//-----------------------------------------------------------------------------
//
// Purpose: Embed debug info in each file.
//
#if defined( _WIN32 ) && !defined( _X360 )
#ifdef _DEBUG
#pragma comment(compiler)
#endif
#endif
//-----------------------------------------------------------------------------
//
// Purpose: Wrap around a variable to create a simple place to put a breakpoint
//
#ifdef _DEBUG
template< class Type >
class CDataWatcher
{
public:
const Type& operator=( const Type &val )
{
return Set( val );
}
const Type& operator=( const CDataWatcher<Type> &val )
{
return Set( val.m_Value );
}
const Type& Set( const Type &val )
{
// Put your breakpoint here
m_Value = val;
return m_Value;
}
Type& GetForModify()
{
return m_Value;
}
const Type& operator+=( const Type &val )
{
return Set( m_Value + val );
}
const Type& operator-=( const Type &val )
{
return Set( m_Value - val );
}
const Type& operator/=( const Type &val )
{
return Set( m_Value / val );
}
const Type& operator*=( const Type &val )
{
return Set( m_Value * val );
}
const Type& operator^=( const Type &val )
{
return Set( m_Value ^ val );
}
const Type& operator|=( const Type &val )
{
return Set( m_Value | val );
}
const Type& operator++()
{
return (*this += 1);
}
Type operator--()
{
return (*this -= 1);
}
Type operator++( int ) // postfix version..
{
Type val = m_Value;
(*this += 1);
return val;
}
Type operator--( int ) // postfix version..
{
Type val = m_Value;
(*this -= 1);
return val;
}
// For some reason the compiler only generates type conversion warnings for this operator when used like
// CNetworkVarBase<unsigned tchar> = 0x1
// (it warns about converting from an int to an unsigned char).
template< class C >
const Type& operator&=( C val )
{
return Set( m_Value & val );
}
operator const Type&() const
{
return m_Value;
}
const Type& Get() const
{
return m_Value;
}
const Type* operator->() const
{
return &m_Value;
}
Type m_Value;
};
#else
template< class Type >
class CDataWatcher
{
private:
CDataWatcher(); // refuse to compile in non-debug builds
};
#endif
// Code for programmatically setting/unsetting hardware breakpoints (there's probably a 360 and
#ifdef IS_WINDOWS_PC
typedef void * HardwareBreakpointHandle_t;
enum EHardwareBreakpointType
{
BREAKPOINT_EXECUTE = 0,
BREAKPOINT_WRITE,
BREAKPOINT_READWRITE,
};
enum EHardwareBreakpointSize
{
BREAKPOINT_SIZE_1 = 1,
BREAKPOINT_SIZE_2 = 2,
BREAKPOINT_SIZE_4 = 4,
BREAKPOINT_SIZE_8 = 8,
};
PLATFORM_INTERFACE HardwareBreakpointHandle_t SetHardwareBreakpoint( EHardwareBreakpointType eType, EHardwareBreakpointSize eSize, const void *pvLocation );
PLATFORM_INTERFACE bool ClearHardwareBreakpoint( HardwareBreakpointHandle_t handle );
class CHardwareBreakPointScopeGuard
{
public:
CHardwareBreakPointScopeGuard( const void *pvLocation, size_t nLocationSize, EHardwareBreakpointType eType = BREAKPOINT_WRITE )
{
EHardwareBreakpointSize eSize = BREAKPOINT_SIZE_4;
switch ( nLocationSize )
{
case 1:
eSize = BREAKPOINT_SIZE_1;
break;
case 2:
eSize = BREAKPOINT_SIZE_2;
break;
case 4:
eSize = BREAKPOINT_SIZE_4;
break;
case 8:
eSize = BREAKPOINT_SIZE_8;
break;
default:
Warning( _T( "SetHardwareBreakpoint can only work with 1, 2, 4 or 8 byte data fields." ) );
break;
}
m_hBreakPoint = SetHardwareBreakpoint( eType, eSize, pvLocation );
m_bActive = m_hBreakPoint != (HardwareBreakpointHandle_t)0;
}
~CHardwareBreakPointScopeGuard()
{
Release();
}
void Release()
{
if ( !m_bActive )
return;
ClearHardwareBreakpoint( m_hBreakPoint );
}
private:
bool m_bActive;
HardwareBreakpointHandle_t m_hBreakPoint;
};
#endif // IS_WINDOWS_PC
//-----------------------------------------------------------------------------
#endif /* DBG_H */

68
external/vpc/public/tier0/dbgflag.h vendored Normal file
View File

@@ -0,0 +1,68 @@
//========= Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose: This file sets all of our debugging flags. It should be
// called before all other header files.
//
// $NoKeywords: $
//=============================================================================//
#ifndef DBGFLAG_H
#define DBGFLAG_H
#ifdef _WIN32
#pragma once
#endif
// Here are all the flags we support:
// DBGFLAG_MEMORY: Enables our memory debugging system, which overrides malloc & free
// DBGFLAG_MEMORY_NEWDEL: Enables new / delete tracking for memory debug system. Requires DBGFLAG_MEMORY to be enabled.
// DBGFLAG_VALIDATE: Enables our recursive validation system for checking integrity and memory leaks
// DBGFLAG_ASSERT: Turns Assert on or off (when off, it isn't compiled at all)
// DBGFLAG_ASSERTFATAL: Turns AssertFatal on or off (when off, it isn't compiled at all)
// DBGFLAG_ASSERTDLG: Turns assert dialogs on or off and debug breaks on or off when not under the debugger.
// (Dialogs will always be on when process is being debugged.)
// DBGFLAG_STRINGS: Turns on hardcore string validation (slow but safe)
#undef DBGFLAG_MEMORY
#undef DBGFLAG_MEMORY_NEWDEL
#undef DBGFLAG_VALIDATE
#undef DBGFLAG_ASSERT
#undef DBGFLAG_ASSERTFATAL
#undef DBGFLAG_ASSERTDLG
#undef DBGFLAG_STRINGS
//-----------------------------------------------------------------------------
// Default flags for debug builds
//-----------------------------------------------------------------------------
#if defined( _DEBUG ) && !defined( PS3MEMOVERRIDEWRAP )
#define DBGFLAG_MEMORY
#ifdef _SERVER // only enable new & delete tracking for server; on client it conflicts with CRT mem leak tracking
#define DBGFLAG_MEMORY_NEWDEL
#endif
#ifdef STEAM
#define DBGFLAG_VALIDATE
#endif
#define DBGFLAG_ASSERT
#define DBGFLAG_ASSERTFATAL
#define DBGFLAG_ASSERTDLG
#define DBGFLAG_STRINGS
//-----------------------------------------------------------------------------
// Default flags for release builds
//-----------------------------------------------------------------------------
#else // _DEBUG
#ifdef STEAM
#define DBGFLAG_ASSERT
#endif
#define DBGFLAG_ASSERTFATAL // note: fatal asserts are enabled in release builds
#define DBGFLAG_ASSERTDLG
#endif // _DEBUG
#if defined( _CERT )
#define DBGFLAG_STRINGS_STRIP
#endif
#endif // DBGFLAG_H

155
external/vpc/public/tier0/etwprof.h vendored Normal file
View File

@@ -0,0 +1,155 @@
//============ Copyright (c) Valve Corporation, All rights reserved. ============
//
// ETW (Event Tracing for Windows) profiling helpers.
// This allows easy insertion of Generic Event markers into ETW/xperf tracing
// which then aids in analyzing the traces and finding performance problems.
// The usage patterns are to use ETWBegin and ETWEnd (typically through the
// convenience class CETWScope) to bracket time-consuming operations. In addition
// ETWFrameMark marks the beginning of each frame, and ETWMark can be used to
// mark other notable events. More event types and providers can be added as needed.
// When recording xperf profiles add Valve-Main+Valve-FrameRate to the list of
// user-mode providers and be sure to register the providers with this sequence
// of commands:
// xcopy /y game\bin\tier0.dll %temp%
// wevtutil um src\tier0\ValveETWProvider.man
// wevtutil im src\tier0\ValveETWProvider.man
//
//===============================================================================
#ifndef ETWPROF_H
#define ETWPROF_H
#if defined( COMPILER_MSVC )
#pragma once
#endif
#include "tier0/platform.h"
#ifdef IS_WINDOWS_PC
// ETW support should be compiled in for all Windows PC platforms. It isn't
// supported on Windows XP but that is determined at run-time.
#if !defined(STANDALONE_VPC) && !defined(DISABLE_ETW)
#define ETW_MARKS_ENABLED
#endif
#endif
#ifdef ETW_MARKS_ENABLED
// Insert a single event to mark a point in an ETW trace. The return value is a 64-bit
// time stamp.
PLATFORM_INTERFACE int64 ETWMark( const char *pMessage );
// Optionally do full printf formatting of the mark string. This will be more expensive,
// but only when tracing is enabled.
PLATFORM_INTERFACE int64 ETWMarkPrintf( PRINTF_FORMAT_STRING const char *pMessage, ... ) FMTFUNCTION( 1, 2 );
// Optionally specify one to four floats. They will show up in separate columns in
// summary tables to allow sorting and easier transfer to spreadsheets.
PLATFORM_INTERFACE void ETWMark1F( const char *pMessage, float data1 );
PLATFORM_INTERFACE void ETWMark2F( const char *pMessage, float data1, float data2 );
PLATFORM_INTERFACE void ETWMark3F( const char *pMessage, float data1, float data2, float data3 );
PLATFORM_INTERFACE void ETWMark4F( const char *pMessage, float data1, float data2, float data3, float data4 );
// Optionally specify one to four ints. They will show up in separate columns in
// summary tables to allow sorting and easier transfer to spreadsheets.
PLATFORM_INTERFACE void ETWMark1I( const char *pMessage, int data1 );
PLATFORM_INTERFACE void ETWMark2I( const char *pMessage, int data1, int data2 );
PLATFORM_INTERFACE void ETWMark3I( const char *pMessage, int data1, int data2, int data3 );
PLATFORM_INTERFACE void ETWMark4I( const char *pMessage, int data1, int data2, int data3, int data4 );
// Optionally specify one to two strings. They will show up in separate columns in
// summary tables to allow sorting and easier transfer to spreadsheets.
PLATFORM_INTERFACE void ETWMark1S( const char *pMessage, const char* data1 );
PLATFORM_INTERFACE void ETWMark2S( const char *pMessage, const char* data1, const char* data2 );
// Insert a begin event to mark the start of some work. The return value is a 64-bit
// time stamp which should be passed to the corresponding ETWEnd function.
PLATFORM_INTERFACE int64 ETWBegin( const char *pMessage );
// Insert a paired end event to mark the end of some work.
PLATFORM_INTERFACE int64 ETWEnd( const char *pMessage, int64 nStartTime );
// Mark the start of the next render frame. bIsServerProcess must be passed
// in consistently for a particular process.
PLATFORM_INTERFACE void ETWRenderFrameMark( bool bIsServerProcess );
// Mark the start of the next simulation frame. bIsServerProcess must be passed
// in consistently for a particular process.
PLATFORM_INTERFACE void ETWSimFrameMark( bool bIsServerProcess );
// Return the frame number recorded in the ETW trace -- useful for synchronization
// other profile information to the ETW trace.
PLATFORM_INTERFACE int ETWGetRenderFrameNumber();
PLATFORM_INTERFACE void ETWMouseDown( int nWhichButton, int nX, int nY );
PLATFORM_INTERFACE void ETWMouseUp( int nWhichButton, int nX, int nY );
PLATFORM_INTERFACE void ETWKeyDown( int nScanCode, int nVirtualCode, const char *pChar );
PLATFORM_INTERFACE void ETWSendPacket( const char *pTo, int nWireSize, int nOutSequenceNR, int nOutSequenceNrAck );
PLATFORM_INTERFACE void ETWThrottled();
PLATFORM_INTERFACE void ETWReadPacket( const char *pFrom, int nWireSize, int nInSequenceNR, int nOutSequenceNRAck );
// This class calls the ETW Begin and End functions in order to insert a
// pair of events to bracket some work.
class CETWScope
{
public:
CETWScope( const char *pMessage )
: m_pMessage( pMessage )
{
m_nStartTime = ETWBegin( pMessage );
}
~CETWScope()
{
ETWEnd( m_pMessage, m_nStartTime );
}
private:
// Private and unimplemented to disable copying.
CETWScope( const CETWScope& rhs );
CETWScope& operator=( const CETWScope& rhs );
const char* m_pMessage;
int64 m_nStartTime;
};
#else
inline int64 ETWMark( const char* ) { return 0; }
inline int64 ETWMarkPrintf( const char *, ... ) { return 0; }
inline void ETWMark1F( const char *, float ) { }
inline void ETWMark2F( const char *, float , float ) { }
inline void ETWMark3F( const char *, float , float , float ) { }
inline void ETWMark4F( const char *, float , float , float , float ) { }
inline void ETWMark1I( const char *, int ) { }
inline void ETWMark2I( const char *, int , int ) { }
inline void ETWMark3I( const char *, int , int , int ) { }
inline void ETWMark4I( const char *, int , int , int , int ) { }
// Optionally specify one to two strings. They will show up in separate columns in
// summary tables to allow sorting and easier transfer to spreadsheets.
inline void ETWMark1S( const char *, const char* ) { }
inline void ETWMark2S( const char *, const char* , const char* ) { }
inline int64 ETWBegin( const char* ) { return 0; }
inline int64 ETWEnd( const char*, int64 ) { return 0; }
inline void ETWRenderFrameMark( bool ) {}
inline void ETWSimFrameMark( bool ) {}
inline int ETWGetRenderFrameNumber() { return 0; }
inline void ETWMouseDown( int nWhichButton, int nX, int nY ) {}
inline void ETWMouseUp( int nWhichButton, int nX, int nY ) {}
inline void ETWKeyDown( int nScanCode, int nVirtualCode, const char *pChar ) {}
inline void ETWSendPacket( const char *pTo, int nWireSize, int nOutSequenceNR, int nOutSequenceNrAck ) {}
inline void ETWThrottled() {}
inline void ETWReadPacket( const char *pFrom, int nWireSize, int nInSequenceNR, int nOutSequenceNRAck ) {}
// This class calls the ETW Begin and End functions in order to insert a
// pair of events to bracket some work.
class CETWScope
{
public:
CETWScope( const char* )
{
}
private:
// Private and unimplemented to disable copying.
CETWScope( const CETWScope& rhs );
CETWScope& operator=( const CETWScope& rhs );
};
#endif
#endif // ETWPROF_H

480
external/vpc/public/tier0/eventmasks.h vendored Normal file
View File

@@ -0,0 +1,480 @@
//========= Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//
//=============================================================================//
#pragma once
typedef union EVENT_MASK(TC_deliver_mode)
{
struct
{
uint16 DD:1; // both logical processors in deliver mode },
uint16 DB:1; // logical processor 0 in deliver mode, 1 in build mode },
uint16 DI:1; // logical processor 0 in deliver mode, 1 is inactive },
uint16 BD:1; // logical processor 0 in build mode, 1 in deliver mode },
uint16 BB:1; // both logical processors in build mode },
uint16 BI:1; // logical processor 0 in build mode, 1 is inactive },
uint16 ID:1; // logical processor 0 is inactive, 1 in deliver mode },
uint16 IB:1; // logical processor 0 is inactive, 1 in build mode }
};
uint16 flat;
} EVENT_MASK(TC_deliver_mode);
typedef union EVENT_MASK(BPU_fetch_request)
{
struct
{
uint16 TCMISS:1; // Trace cache lookup miss },
};
uint16 flat;
} EVENT_MASK(BPU_fetch_request);
typedef union EVENT_MASK(ITLB_reference)
{
struct
{
uint16 HIT : 1; //ITLB hit },
uint16 MISS : 1;//ITLB miss },
uint16 HIT_UC :1; // Uncacheable ITLB hit }
};
uint16 flat;
} EVENT_MASK(ITLB_reference);
typedef union EVENT_MASK(memory_cancel)
{
struct
{
uint16 dummy : 2;
uint16 ST_RB_FULL:1; //Replayed because no store request buffer is available },
uint16 _64K_CONF:1; //Conflicts due to 64K aliasing }
};
uint16 flat;
}EVENT_MASK(memory_cancel);
typedef union EVENT_MASK(memory_complete)
{
struct
{
uint16 LSC:1; // Load split completed, excluding UC/WC loads },
uint16 SSC:1; //Any split stores completed } }
};
uint16 flat;
} EVENT_MASK(memory_complete);
typedef union EVENT_MASK(load_port_replay)
{
struct
{
uint16 dummy:1;
uint16 SPLIT_LD:1; //Split load } }
};
uint16 flat;
} EVENT_MASK(load_port_replay);
typedef union EVENT_MASK(store_port_replay)
{
struct
{
uint16 dummy0:1;
uint16 SPLIT_ST:1; //Split store } }
};
uint16 flat;
} EVENT_MASK(store_port_replay);
typedef union EVENT_MASK(MOB_load_replay)
{
struct
{
uint16 dummy0:1;
uint16 NO_STA:1; //Replayed because of unknown store address },
uint16 dummy2:1;
uint16 NO_STD:1; //Replayed because of unknown store data },
uint16 PARTIAL_DATA:1; //Replayed because of partially overlapped data access between the load and store operations },
uint16 UNALGN_ADDR:1; //Replayed because the lower 4 bits of the linear address do not match between the load and store operations } }
};
uint16 flat;
}EVENT_MASK(MOB_load_replay);
typedef union EVENT_MASK(page_walk_type)
{
struct
{
uint16 DTMISS:1; // Page walk for a data TLB miss },
uint16 ITMISS:1; // Page walk for an instruction TLB miss } }
};
uint16 flat;
}EVENT_MASK(page_walk_type);
typedef union EVENT_MASK(BSQ_cache_reference)
{
struct
{
uint16 RD_2ndL_HITS:1; // Read 2nd level cache hit Shared },
uint16 RD_2ndL_HITE:1; // Read 2nd level cache hit Exclusive },
uint16 RD_2ndL_HITM:1; // Read 2nd level cache hit Modified },
uint16 RD_3rdL_HITS:1; // Read 3rd level cache hit Shared },
uint16 RD_3rdL_HITE:1; // Read 3rd level cache hit Exclusive },
uint16 RD_3rdL_HITM:1; // Read 3rd level cache hit Modified },
uint16 dummy6:1;
uint16 dummy7:1;
uint16 RD_2ndL_MISS:1; // Read 2nd level cache miss },
uint16 RD_3rdL_MISS:1; // Read 3rd level cache miss },
uint16 WR_2ndL_MISS:1; // Writeback lookup from DAC misses the 2nd level cache } }
};
uint16 flat;
} EVENT_MASK(BSQ_cache_reference) ;
typedef union EVENT_MASK(IOQ)
{
struct
{
uint16 bit0:1; // bus request type (use 00001 for invalid or default)
uint16 bit1:1; //
uint16 bit2:1; //
uint16 bit3:1; //
uint16 bit4:1; //
uint16 ALL_READ:1; // Count read entries },
uint16 ALL_WRITE:1; // Count write entries },
uint16 MEM_UC:1; // Count UC memory access entries },
uint16 MEM_WC:1; // Count WC memory access entries },
uint16 MEM_WT:1; // Count WT memory access entries },
uint16 MEM_WP:1; // Count WP memory access entries },
uint16 MEM_WB:1; // Count WB memory access entries },
uint16 dummy12:1;
uint16 OWN:1; // Count own store requests },
uint16 OTHER:1; // Count other and DMA store requests },
uint16 PREFETCH:1; // Include HW and SW prefetch requests } }
};
uint16 flat;
} EVENT_MASK(IOQ) ;
typedef union EVENT_MASK(FSB_data_activity)
{
struct
{
/* DRDY_OWN is mutually exclusive with DRDY_OTHER */
/* DBSY_OWN is mutually exclusive with DBSY_OTHER */
uint16 DRDY_DRV:1; // Count when this processor drives data onto the bus },
uint16 DRDY_OWN:1; // Count when this processor reads data from the bus },
uint16 DRDY_OTHER:1; // Count when data is on the bus but not being sampled by the processor },
uint16 DBSY_DRV:1; // Count when this processor reserves the bus for driving data },
uint16 DBSY_OWN:1; // Count when this processor reserves the bus for sampling data },
uint16 DBSY_OTHER:1; // Count when the bus is reserved for driving data this processor will not sample } }
};
uint16 flat;
}EVENT_MASK(FSB_data_activity);
typedef union EVENT_MASK(BSQ)
{
struct
{
uint16 REQ_TYPE0:1; // Request type encoding bit 0 },
uint16 REQ_TYPE1:1; // Request type encoding bit 1 },
uint16 REQ_LEN0:1; // Request length encoding bit 0 },
uint16 REQ_LEN1:1; // Request length encoding bit 1 },
uint16 dummy4: 1;
uint16 REQ_IO_TYPE:1; // Request type is input or output },
uint16 REQ_LOCK_TYPE:1; // Request type is bus lock },
uint16 REQ_CACHE_TYPE:1; // Request type is cacheable },
uint16 REQ_SPLIT_TYPE:1; // Request type is a bus 8-byte chunk split across 8-byte boundary },
uint16 REQ_DEM_TYPE:1; // Request type is a demand (1) or prefetch (0) },
uint16 REQ_ORD_TYPE:1; // Request is an ordered type },
uint16 MEM_TYPE0:1; // Memory type encoding bit 0 },
uint16 MEM_TYPE1:1; // Memory type encoding bit 1 },
uint16 MEM_TYPE2:1; // Memory type encoding bit 2 } }
};
uint16 flat;
} EVENT_MASK(BSQ);
typedef union EVENT_MASK(firm_uop)
{
struct
{
uint16 dummy15 : 15;
uint16 ALL:1; // count all uops of this type } }
};
uint16 flat;
} EVENT_MASK(firm_uop);
typedef union EVENT_MASK(TC_misc)
{
struct
{
uint16 dymmy4 : 4;
uint16 FLUSH:1; // Number of flushes } }
};
uint16 flat;
} EVENT_MASK(TC_misc);
typedef union EVENT_MASK(global_power_events)
{
struct
{
uint16 Running:1; // The processor is active } }
};
uint16 flat;
} EVENT_MASK(global_power_events);
typedef union EVENT_MASK(tc_ms_xfer)
{
struct
{
uint16 CISC:1; // A TC to MS transfer ocurred } }
};
uint16 flat;
}EVENT_MASK(tc_ms_xfer);
typedef union EVENT_MASK(uop_queue_writes)
{
struct
{
uint16 FROM_TC_BUILD:1; // uops written from TC build mode
uint16 FROM_TC_DELIVER:1; // uops written from TC deliver mode
uint16 FROM_ROM:1; // uops written from microcode ROM } }
};
uint16 flat;
} EVENT_MASK(uop_queue_writes);
typedef union EVENT_MASK(branch_type)
{
struct
{
uint16 dummy : 1;
uint16 CONDITIONAL:1; // Conditional jumps
uint16 CALL:1; // Direct or indirect call
uint16 RETURN:1; // Return branches
uint16 INDIRECT:1; // Returns, indirect calls, or indirect jumps
};
uint16 flat;
} EVENT_MASK(branch_type);
typedef union EVENT_MASK(resource_stall)
{
struct
{
uint16 dummy1 : 5;
uint16 SBFULL:1; // A Stall due to lack of store buffers } }
};
uint16 flat;
} EVENT_MASK(resource_stall);
typedef union EVENT_MASK(WC_Buffer)
{
struct
{
uint16 WCB_EVICTS : 1; // all causes },
uint16 WCB_FULL_EVICT : 1; // no WC buffer is available },
/* XXX: 245472-011 no longer lists bit 2, but that looks like
a table formatting error. Keeping it for now. */
uint16 WCB_HITM_EVICT : 1; // store encountered a Hit Modified condition } }
};
uint16 flat;
} EVENT_MASK(WC_Buffer);
typedef union EVENT_MASK(b2b_cycles)
{
struct
{
uint16 dummy0 : 1;
uint16 bit1 : 1; //
uint16 bit2 : 1; //
uint16 bit3 : 1; //
uint16 bit4 : 1; //
uint16 bit5 : 1; //
uint16 bit6 : 1; //
};
uint16 flat;
} EVENT_MASK(b2b_cycles);
typedef union EVENT_MASK(bnr)
{
struct
{
uint16 bit0:1; //
uint16 bit1:1; //
uint16 bit2:1; //
};
uint16 flat;
} EVENT_MASK(bnr);
typedef union EVENT_MASK(snoop)
{
struct
{
uint16 dummy0 : 1;
uint16 dummy1 : 1;
uint16 bit2:1; //
uint16 dummy3:1; //
uint16 dummy4:1; //
uint16 dummy5:1; //
uint16 bit6:1; //
uint16 bit7:1; //
};
uint16 flat;
} EVENT_MASK(snoop);
typedef union EVENT_MASK(response)
{
struct
{
uint16 dummy0:1; //
uint16 bit1:1; //
uint16 bit2:1; //
uint16 dummy3:1; //
uint16 dummy4:1; //
uint16 dummy5:1; //
uint16 dummy6:1; //
uint16 dummy7:1; //
uint16 bit8:1; //
uint16 bit9:1; //
};
uint16 flat;
} EVENT_MASK(response);
typedef union EVENT_MASK(nbogus_bogus)
{
struct
{
uint16 NBOGUS:1; // The marked uops are not bogus
uint16 BOGUS:1; // The marked uops are bogus
};
uint16 flat;
} EVENT_MASK(nbogus_bogus);
typedef union EVENT_MASK(execution_event)
{
struct
{
uint16 NBOGUS0:1; // non-bogus uops with tag bit 0 set },
uint16 NBOGUS1:1; // non-bogus uops with tag bit 1 set },
uint16 NBOGUS2:1; // non-bogus uops with tag bit 2 set },
uint16 NBOGUS3:1; // non-bogus uops with tag bit 3 set },
uint16 BOGUS0:1; // bogus uops with tag bit 0 set },
uint16 BOGUS1:1; // bogus uops with tag bit 1 set },
uint16 BOGUS2:1; // bogus uops with tag bit 2 set },
uint16 BOGUS3:1; // bogus uops with tag bit 3 set } }
};
uint16 flat;
}EVENT_MASK(execution_event);
typedef union EVENT_MASK(instr_retired)
{
struct
{
uint16 NBOGUSNTAG:1; // Non-bogus instructions that are not tagged },
uint16 NBOGUSTAG:1; // Non-bogus instructions that are tagged },
uint16 BOGUSNTAG:1; // Bogus instructions that are not tagged },
uint16 BOGUSTAG:1; // Bogus instructions that are tagged } }
};
uint16 flat;
} EVENT_MASK(instr_retired);
typedef union EVENT_MASK(uop_type)
{
struct
{
uint16 dummy0 : 1;
uint16 TAGLOADS:1; // The uop is a load operation },
uint16 TAGSTORES:1; // The uop is a store operation } }
};
uint16 flat;
} EVENT_MASK(uop_type);
typedef union EVENT_MASK(branch_retired)
{
struct
{
uint16 MMNP:1; // Branch Not-taken Predicted
uint16 MMNM:1; // Branch Not-taken Mispredicted
uint16 MMTP:1; // Branch Taken Predicted
uint16 MMTM:1; // Branch Taken Mispredicted
};
uint16 flat;
} EVENT_MASK(branch_retired);
typedef union EVENT_MASK(mispred_branch_retired)
{
struct
{
uint16 NBOGUS:1; // The retired branch is not bogus } }
};
uint16 flat;
} EVENT_MASK(mispred_branch_retired);
typedef union EVENT_MASK(x87_assist)
{
struct
{
uint16 FPSU:1; // FP stack underflow },
uint16 FPSO:1; // FP stack overflow },
uint16 POAO:1; // x87 output overflow },
uint16 POAU:1; // x87 output underflow },
uint16 PREA:1; // x87 input assist } }
};
uint16 flat;
}EVENT_MASK(x87_assist);
typedef union EVENT_MASK(machine_clear)
{
struct
{
uint16 CLEAR:1; // Count a portion of the cycles when the machine is cleared },
uint16 dummy1: 1;
uint16 MOCLEAR:1; // Count clears due to memory ordering issues },
uint16 dummy3: 1;
uint16 dummy4: 1;
uint16 dummy5: 1;
uint16 SMCLEAR:1;// Count clears due to self-modifying code issues } }
};
uint16 flat;
} EVENT_MASK(machine_clear);
typedef union EVENT_MASK(x87_SIMD_moves_uop)
{
struct
{
uint16 dummy3:3;
uint16 ALLP0:1; // Count all x87/SIMD store/move uops },
uint16 ALLP2:1; // count all x87/SIMD load uops } }
};
uint16 flat;
} EVENT_MASK(x87_SIMD_moves_uop);

1787
external/vpc/public/tier0/eventmodes.h vendored Normal file

File diff suppressed because it is too large Load Diff

625
external/vpc/public/tier0/fasttimer.h vendored Normal file
View File

@@ -0,0 +1,625 @@
//========= Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//===========================================================================//
#ifndef FASTTIMER_H
#define FASTTIMER_H
#ifdef _WIN32
#pragma once
#endif
#include <assert.h>
#include "tier0/platform.h"
#ifdef _PS3
#include "sys/sys_time.h"
#else
inline uint64 sys_time_get_timebase_frequency()
{
DebuggerBreak(); // Error("sys_time_get_timebase_frequency called on non-PS3 platform.");
return 1; // this function should never ever be called.
}
#endif
PLATFORM_INTERFACE uint64 g_ClockSpeed;
PLATFORM_INTERFACE unsigned long g_dwClockSpeed;
PLATFORM_INTERFACE double g_ClockSpeedMicrosecondsMultiplier;
PLATFORM_INTERFACE double g_ClockSpeedMillisecondsMultiplier;
PLATFORM_INTERFACE double g_ClockSpeedSecondsMultiplier;
#ifdef COMPILER_MSVC64
extern "C"
{
unsigned __int64 __rdtsc();
}
#pragma intrinsic(__rdtsc)
#endif
class CCycleCount
{
friend class CFastTimer;
public:
CCycleCount();
CCycleCount( uint64 cycles );
void Sample(); // Sample the clock. This takes about 34 clocks to execute (or 26,000 calls per millisecond on a P900).
void Init(); // Set to zero.
void Init( float initTimeMsec );
void Init( double initTimeMsec ) { Init( (float)initTimeMsec ); }
void Init( uint64 cycles );
bool IsLessThan( CCycleCount const &other ) const; // Compare two counts.
// Convert to other time representations. These functions are slow, so it's preferable to call them
// during display rather than inside a timing block.
unsigned long GetCycles() const;
uint64 GetLongCycles() const;
unsigned long GetMicroseconds() const;
uint64 GetUlMicroseconds() const;
double GetMicrosecondsF() const;
void SetMicroseconds( unsigned long nMicroseconds );
unsigned long GetMilliseconds() const;
double GetMillisecondsF() const;
double GetSeconds() const;
CCycleCount& operator+=( CCycleCount const &other );
// dest = rSrc1 + rSrc2
static void Add( CCycleCount const &rSrc1, CCycleCount const &rSrc2, CCycleCount &dest ); // Add two samples together.
// dest = rSrc1 - rSrc2
static void Sub( CCycleCount const &rSrc1, CCycleCount const &rSrc2, CCycleCount &dest ); // Add two samples together.
static uint64 GetTimestamp();
uint64 m_Int64;
};
class CClockSpeedInit
{
public:
CClockSpeedInit()
{
Init();
}
static void Init()
{
const CPUInformation& pi = GetCPUInformation();
if ( IsX360() )
{
// cycle counter runs as doc'd at 1/64 Xbox 3.2GHz clock speed, thus 50 Mhz
g_ClockSpeed = pi.m_Speed / 64L;
}
else if ( IsPS3() )
{
g_ClockSpeed = sys_time_get_timebase_frequency(); // CPU clock rate is totally unrelated to time base register frequency on PS3
}
else
{
g_ClockSpeed = pi.m_Speed;
}
g_dwClockSpeed = (unsigned long)g_ClockSpeed;
g_ClockSpeedMicrosecondsMultiplier = 1000000.0 / (double)g_ClockSpeed;
g_ClockSpeedMillisecondsMultiplier = 1000.0 / (double)g_ClockSpeed;
g_ClockSpeedSecondsMultiplier = 1.0f / (double)g_ClockSpeed;
}
};
class CFastTimer
{
public:
// These functions are fast to call and should be called from your sampling code.
void Start();
void End();
const CCycleCount & GetDuration() const; // Get the elapsed time between Start and End calls.
CCycleCount GetDurationInProgress() const; // Call without ending. Not that cheap.
// Return number of cycles per second on this processor.
static inline unsigned long GetClockSpeed();
private:
CCycleCount m_Duration;
#ifdef DEBUG_FASTTIMER
bool m_bRunning; // Are we currently running?
#endif
};
// This is a helper class that times whatever block of code it's in
class CTimeScope
{
public:
CTimeScope( CFastTimer *pTimer );
~CTimeScope();
private:
CFastTimer *m_pTimer;
};
inline CTimeScope::CTimeScope( CFastTimer *pTotal )
{
m_pTimer = pTotal;
m_pTimer->Start();
}
inline CTimeScope::~CTimeScope()
{
m_pTimer->End();
}
// This is a helper class that times whatever block of code it's in and
// adds the total (int microseconds) to a global counter.
class CTimeAdder
{
public:
CTimeAdder( CCycleCount *pTotal );
~CTimeAdder();
void End();
private:
CCycleCount *m_pTotal;
CFastTimer m_Timer;
};
inline CTimeAdder::CTimeAdder( CCycleCount *pTotal )
{
m_pTotal = pTotal;
m_Timer.Start();
}
inline CTimeAdder::~CTimeAdder()
{
End();
}
inline void CTimeAdder::End()
{
if( m_pTotal )
{
m_Timer.End();
*m_pTotal += m_Timer.GetDuration();
m_pTotal = 0;
}
}
// -------------------------------------------------------------------------- //
// Simple tool to support timing a block of code, and reporting the results on
// program exit or at each iteration
//
// Macros used because dbg.h uses this header, thus Msg() is unavailable
// -------------------------------------------------------------------------- //
#define PROFILE_SCOPE(name) \
class C##name##ACC : public CAverageCycleCounter \
{ \
public: \
~C##name##ACC() \
{ \
Msg("%-48s: %6.3f avg (%8.1f total, %7.3f peak, %5d iters)\n", \
#name, \
GetAverageMilliseconds(), \
GetTotalMilliseconds(), \
GetPeakMilliseconds(), \
GetIters() ); \
} \
}; \
static C##name##ACC name##_ACC; \
CAverageTimeMarker name##_ATM( &name##_ACC )
#define TIME_SCOPE(name) \
class CTimeScopeMsg_##name \
{ \
public: \
CTimeScopeMsg_##name() { m_Timer.Start(); } \
~CTimeScopeMsg_##name() \
{ \
m_Timer.End(); \
Msg( #name "time: %.4fms\n", m_Timer.GetDuration().GetMillisecondsF() ); \
} \
private: \
CFastTimer m_Timer; \
} name##_TSM;
// -------------------------------------------------------------------------- //
class CAverageCycleCounter
{
public:
CAverageCycleCounter();
void Init();
void MarkIter( const CCycleCount &duration );
unsigned GetIters() const;
double GetAverageMilliseconds() const;
double GetTotalMilliseconds() const;
double GetPeakMilliseconds() const;
private:
unsigned m_nIters;
CCycleCount m_Total;
CCycleCount m_Peak;
bool m_fReport;
const tchar *m_pszName;
};
// -------------------------------------------------------------------------- //
class CAverageTimeMarker
{
public:
CAverageTimeMarker( CAverageCycleCounter *pCounter );
~CAverageTimeMarker();
private:
CAverageCycleCounter *m_pCounter;
CFastTimer m_Timer;
};
// -------------------------------------------------------------------------- //
// CCycleCount inlines.
// -------------------------------------------------------------------------- //
inline CCycleCount::CCycleCount()
{
Init( (uint64)0 );
}
inline CCycleCount::CCycleCount( uint64 cycles )
{
Init( cycles );
}
inline void CCycleCount::Init()
{
Init( (uint64)0 );
}
inline void CCycleCount::Init( float initTimeMsec )
{
if ( g_ClockSpeedMillisecondsMultiplier > 0 )
Init( (uint64)(initTimeMsec / g_ClockSpeedMillisecondsMultiplier) );
else
Init( (uint64)0 );
}
inline void CCycleCount::Init( uint64 cycles )
{
m_Int64 = cycles;
}
#if !COMPILER_GCC
#pragma warning(push)
#pragma warning(disable : 4189) // warning C4189: local variable is initialized but not referenced
#endif
inline void CCycleCount::Sample()
{
#ifdef COMPILER_MSVC64
unsigned __int64* pSample = (unsigned __int64*)&m_Int64;
*pSample = __rdtsc();
// Msg( "Sample = %I64x", pSample );
#elif defined( _X360 )
// only need lower 32 bits, avoids doc'd read bug and 32 bit rollover is in 85 seconds
m_Int64 = (uint64)__mftb32();
// scale back up, needs to be viewed as 1 cycle/clock
#elif defined( _PS3 )
// only need lower 32 bits, avoids doc'd read bug and 32 bit rollover is in 85 seconds
m_Int64 = (uint64)__mftb();
// scale back up, needs to be viewed as 1 cycle/clock
#elif defined( __GNUC__ )
union
{
unsigned long* pSample;
uint64 * pInt64;
} tmp;
tmp.pInt64 = &m_Int64;
__asm__ __volatile__ (
"rdtsc\n\t"
"movl %%eax, (%0)\n\t"
"movl %%edx, 4(%0)\n\t"
: /* no output regs */
: "D" (tmp.pSample)
: "%eax", "%edx" );
#elif defined( _WIN32 )
unsigned long* pSample = (unsigned long *)&m_Int64;
__asm
{
// force the cpu to synchronize the instruction queue
// NJS: CPUID can really impact performance in tight loops.
//cpuid
//cpuid
//cpuid
mov ecx, pSample
rdtsc
mov [ecx], eax
mov [ecx+4], edx
}
#elif defined( POSIX )
unsigned long* pSample = (unsigned long *)&m_Int64;
__asm__ __volatile__ (
"rdtsc\n\t"
"movl %%eax, (%0)\n\t"
"movl %%edx, 4(%0)\n\t"
: /* no output regs */
: "D" (pSample)
: "%eax", "%edx" );
#endif
}
#if !COMPILER_GCC
#pragma warning(pop)
#endif
inline CCycleCount& CCycleCount::operator+=( CCycleCount const &other )
{
m_Int64 += other.m_Int64;
return *this;
}
inline void CCycleCount::Add( CCycleCount const &rSrc1, CCycleCount const &rSrc2, CCycleCount &dest )
{
dest.m_Int64 = rSrc1.m_Int64 + rSrc2.m_Int64;
}
inline void CCycleCount::Sub( CCycleCount const &rSrc1, CCycleCount const &rSrc2, CCycleCount &dest )
{
dest.m_Int64 = rSrc1.m_Int64 - rSrc2.m_Int64;
}
inline uint64 CCycleCount::GetTimestamp()
{
CCycleCount c;
c.Sample();
return c.GetLongCycles();
}
inline bool CCycleCount::IsLessThan(CCycleCount const &other) const
{
return m_Int64 < other.m_Int64;
}
inline unsigned long CCycleCount::GetCycles() const
{
return (unsigned long)m_Int64;
}
inline uint64 CCycleCount::GetLongCycles() const
{
return m_Int64;
}
inline unsigned long CCycleCount::GetMicroseconds() const
{
return (unsigned long)((m_Int64 * 1000000) / g_ClockSpeed);
}
inline uint64 CCycleCount::GetUlMicroseconds() const
{
return ((m_Int64 * 1000000) / g_ClockSpeed);
}
inline double CCycleCount::GetMicrosecondsF() const
{
return (double)( m_Int64 * g_ClockSpeedMicrosecondsMultiplier );
}
inline void CCycleCount::SetMicroseconds( unsigned long nMicroseconds )
{
m_Int64 = ((uint64)nMicroseconds * g_ClockSpeed) / 1000000;
}
inline unsigned long CCycleCount::GetMilliseconds() const
{
return (unsigned long)((m_Int64 * 1000) / g_ClockSpeed);
}
inline double CCycleCount::GetMillisecondsF() const
{
return (double)( m_Int64 * g_ClockSpeedMillisecondsMultiplier );
}
inline double CCycleCount::GetSeconds() const
{
return (double)( m_Int64 * g_ClockSpeedSecondsMultiplier );
}
// -------------------------------------------------------------------------- //
// CFastTimer inlines.
// -------------------------------------------------------------------------- //
inline void CFastTimer::Start()
{
m_Duration.Sample();
#ifdef DEBUG_FASTTIMER
m_bRunning = true;
#endif
}
inline void CFastTimer::End()
{
CCycleCount cnt;
cnt.Sample();
if ( IsX360() )
{
// have to handle rollover, hires timer is only accurate to 32 bits
// more than one overflow should not have occurred, otherwise caller should use a slower timer
if ( (uint64)cnt.m_Int64 <= (uint64)m_Duration.m_Int64 )
{
// rollover occurred
cnt.m_Int64 += 0x100000000LL;
}
}
m_Duration.m_Int64 = cnt.m_Int64 - m_Duration.m_Int64;
#ifdef DEBUG_FASTTIMER
m_bRunning = false;
#endif
}
inline CCycleCount CFastTimer::GetDurationInProgress() const
{
CCycleCount cnt;
cnt.Sample();
if ( IsX360() )
{
// have to handle rollover, hires timer is only accurate to 32 bits
// more than one overflow should not have occurred, otherwise caller should use a slower timer
if ( (uint64)cnt.m_Int64 <= (uint64)m_Duration.m_Int64 )
{
// rollover occurred
cnt.m_Int64 += 0x100000000LL;
}
}
CCycleCount result;
result.m_Int64 = cnt.m_Int64 - m_Duration.m_Int64;
return result;
}
inline unsigned long CFastTimer::GetClockSpeed()
{
return g_dwClockSpeed;
}
inline CCycleCount const& CFastTimer::GetDuration() const
{
#ifdef DEBUG_FASTTIMER
assert( !m_bRunning );
#endif
return m_Duration;
}
// -------------------------------------------------------------------------- //
// CAverageCycleCounter inlines
inline CAverageCycleCounter::CAverageCycleCounter()
: m_nIters( 0 ), m_fReport( false )
{
}
inline void CAverageCycleCounter::Init()
{
m_Total.Init();
m_Peak.Init();
m_nIters = 0;
}
inline void CAverageCycleCounter::MarkIter( const CCycleCount &duration )
{
++m_nIters;
m_Total += duration;
if ( m_Peak.IsLessThan( duration ) )
m_Peak = duration;
}
inline unsigned CAverageCycleCounter::GetIters() const
{
return m_nIters;
}
inline double CAverageCycleCounter::GetAverageMilliseconds() const
{
if ( m_nIters )
return (m_Total.GetMillisecondsF() / (double)m_nIters);
else
return 0;
}
inline double CAverageCycleCounter::GetTotalMilliseconds() const
{
return m_Total.GetMillisecondsF();
}
inline double CAverageCycleCounter::GetPeakMilliseconds() const
{
return m_Peak.GetMillisecondsF();
}
// -------------------------------------------------------------------------- //
inline CAverageTimeMarker::CAverageTimeMarker( CAverageCycleCounter *pCounter )
{
m_pCounter = pCounter;
m_Timer.Start();
}
inline CAverageTimeMarker::~CAverageTimeMarker()
{
m_Timer.End();
m_pCounter->MarkIter( m_Timer.GetDuration() );
}
// CLimitTimer
// Use this to time whether a desired interval of time has passed. It's extremely fast
// to check while running.
class CLimitTimer
{
public:
void SetLimit( uint64 m_cMicroSecDuration );
bool BLimitReached( void );
private:
uint64 m_lCycleLimit;
};
//-----------------------------------------------------------------------------
// Purpose: Initializes the limit timer with a period of time to measure.
// Input : cMicroSecDuration - How long a time period to measure
//-----------------------------------------------------------------------------
inline void CLimitTimer::SetLimit( uint64 m_cMicroSecDuration )
{
uint64 dlCycles = ( ( uint64 ) m_cMicroSecDuration * ( uint64 ) g_dwClockSpeed ) / ( uint64 ) 1000000L;
CCycleCount cycleCount;
cycleCount.Sample( );
m_lCycleLimit = cycleCount.GetLongCycles( ) + dlCycles;
}
//-----------------------------------------------------------------------------
// Purpose: Determines whether our specified time period has passed
// Output: true if at least the specified time period has passed
//-----------------------------------------------------------------------------
inline bool CLimitTimer::BLimitReached( )
{
CCycleCount cycleCount;
cycleCount.Sample( );
return ( cycleCount.GetLongCycles( ) >= m_lCycleLimit );
}
#endif // FASTTIMER_H

383
external/vpc/public/tier0/ia32detect.h vendored Normal file
View File

@@ -0,0 +1,383 @@
//===== Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ======//
//
// Purpose:
//
// $NoKeywords: $
//
//===========================================================================//
#ifndef IA32DETECT_H
#define IA32DETECT_H
#ifdef COMPILER_MSVC64
extern "C" void __cpuid(int* CPUInfo, int InfoType);
#pragma intrinsic (__cpuid)
#endif
/*
This section from http://iss.cs.cornell.edu/ia32.htm
*/
typedef unsigned bit;
enum CPUVendor
{
INTEL,
AMD,
UNKNOWN_VENDOR
};
class ia32detect
{
public:
enum type_t
{
type_OEM,
type_OverDrive,
type_Dual,
type_reserved
};
enum brand_t
{
brand_na,
brand_Celeron,
brand_PentiumIII,
brand_PentiumIIIXeon,
brand_reserved1,
brand_reserved2,
brand_PentiumIIIMobile,
brand_reserved3,
brand_Pentium4,
brand_invalid
};
# pragma pack(push, 1)
struct version_t
{
bit Stepping : 4;
bit Model : 4;
bit Family : 4;
bit Type : 2;
bit Reserved1 : 2;
bit XModel : 4;
bit XFamily : 8;
bit Reserved2 : 4;
};
struct misc_t
{
::byte Brand;
::byte CLFLUSH;
::byte Reserved;
::byte APICId;
};
struct feature_t
{
bit FPU : 1; // Floating Point Unit On-Chip
bit VME : 1; // Virtual 8086 Mode Enhancements
bit DE : 1; // Debugging Extensions
bit PSE : 1; // Page Size Extensions
bit TSC : 1; // Time Stamp Counter
bit MSR : 1; // Model Specific Registers
bit PAE : 1; // Physical Address Extension
bit MCE : 1; // Machine Check Exception
bit CX8 : 1; // CMPXCHG8 Instruction
bit APIC : 1; // APIC On-Chip
bit Reserved1 : 1;
bit SEP : 1; // SYSENTER and SYSEXIT instructions
bit MTRR : 1; // Memory Type Range Registers
bit PGE : 1; // PTE Global Bit
bit MCA : 1; // Machine Check Architecture
bit CMOV : 1; // Conditional Move Instructions
bit PAT : 1; // Page Attribute Table
bit PSE36 : 1; // 32-bit Page Size Extension
bit PSN : 1; // Processor Serial Number
bit CLFSH : 1; // CLFLUSH Instruction
bit Reserved2 : 1;
bit DS : 1; // Debug Store
bit ACPI : 1; // Thermal Monitor and Software Controlled Clock Facilities
bit MMX : 1; // Intel MMX Technology
bit FXSR : 1; // FXSAVE and FXRSTOR Instructions
bit SSE : 1; // Intel SSE Technology
bit SSE2 : 1; // Intel SSE2 Technology
bit SS : 1; // Self Snoop
bit HTT : 1; // Hyper Threading
bit TM : 1; // Thermal Monitor
bit Reserved3 : 1;
bit PBE : 1; // Pending Brk. EN.
};
# pragma pack(pop)
tstring vendor_name;
CPUVendor vendor;
tstring brand;
version_t version;
misc_t misc;
feature_t feature;
::byte *cache;
ia32detect ()
{
cache = 0;
uint32 m = init0();
uint32 *d = new uint32[m * 4];
for (uint32 i = 1; i <= m; i++)
{
#ifdef COMPILER_MSVC64
__cpuid((int *) (d + (i-1) * 4), i);
#else
uint32 *t = d + (i - 1) * 4;
__asm
{
mov eax, i;
mov esi, t;
cpuid;
mov dword ptr [esi + 0x0], eax;
mov dword ptr [esi + 0x4], ebx;
mov dword ptr [esi + 0x8], ecx;
mov dword ptr [esi + 0xC], edx;
}
#endif
}
if (m >= 1)
init1(d);
if (m >= 2)
init2(d[4] & 0xFF);
delete [] d;
init0x80000000();
//-----------------------------------------------------------------------
// Get the vendor of the processor
//-----------------------------------------------------------------------
if (_tcscmp(vendor_name.c_str(), _T("GenuineIntel")) == 0)
{
vendor = INTEL;
}
else if (_tcscmp(vendor_name.c_str(), _T("AuthenticAMD")) == 0)
{
vendor = AMD;
}
else
{
vendor = UNKNOWN_VENDOR;
}
}
const tstring version_text () const
{
tchar b[128];
_stprintf(b, _T("%d.%d.%d %s XVersion(%d.%d)"),
version.Family, version.Model, version.Stepping, type_text(), version.XFamily, version.XModel);
return tstring(b);
}
protected:
const tchar * type_text () const
{
static const tchar *text[] =
{
_T("Intel OEM Processor"),
_T("Intel OverDrive(R) Processor"),
_T("Intel Dual Processor"),
_T("reserved")
};
return text[version.Type];
}
const tstring brand_text () const
{
static const tchar *text[] =
{
_T("n/a"),
_T("Celeron"),
_T("Pentium III"),
_T("Pentium III Xeon"),
_T("reserved (4)"),
_T("reserved (5)"),
_T("Pentium III Mobile"),
_T("reserved (7)"),
_T("Pentium 4")
};
if (misc.Brand < brand_invalid)
return tstring(text[misc.Brand]);
else
{
tchar b[32];
_stprintf(b, _T("Brand %d (Update)"), misc.Brand);
return tstring(b);
}
}
private:
uint32 init0 ()
{
uint32 m;
#ifdef COMPILER_MSVC64
int data[4];
tchar * s1;
s1 = (tchar *) &data[1];
s1[12] = '\0';
__cpuid(data, 0);
m = data[0];
vendor_name = s1;
#else
tchar s1[13];
s1[12] = '\0';
__asm
{
xor eax, eax;
cpuid;
mov m, eax;
mov dword ptr s1 + 0, ebx;
mov dword ptr s1 + 4, edx;
mov dword ptr s1 + 8, ecx;
}
vendor_name = s1;
#endif
return m;
}
void init1 (uint32 *d)
{
version = *(version_t *)&d[0];
misc = *(misc_t *)&d[1];
feature = *(feature_t *)&d[3];
}
void process2 (uint32 d, bool c[])
{
if ((d & 0x80000000) == 0)
for (int i = 0; i < 32; i += 8)
c[(d >> i) & 0xFF] = true;
}
void init2 (::byte count)
{
uint32 d[4];
bool c[256];
for (int ci1 = 0; ci1 < 256; ci1++)
c[ci1] = false;
for (int i = 0; i < count; i++)
{
#ifdef COMPILER_MSVC64
__cpuid((int *) d, 2);
#else
__asm
{
mov eax, 2;
lea esi, d;
cpuid;
mov [esi + 0x0], eax;
mov [esi + 0x4], ebx;
mov [esi + 0x8], ecx;
mov [esi + 0xC], edx;
}
#endif
if (i == 0)
d[0] &= 0xFFFFFF00;
process2(d[0], c);
process2(d[1], c);
process2(d[2], c);
process2(d[3], c);
}
int m = 0;
for (int ci2 = 0; ci2 < 256; ci2++)
if (c[ci2])
m++;
cache = new ::byte[m];
m = 0;
for (int ci3 = 1; ci3 < 256; ci3++)
if (c[ci3])
cache[m++] = ci3;
cache[m] = 0;
}
void init0x80000000 ()
{
uint32 m;
#ifdef COMPILER_MSVC64
int data[4];
__cpuid(data, 0x80000000);
m = data[0];
#else
__asm
{
mov eax, 0x80000000;
cpuid;
mov m, eax
}
#endif
if ((m & 0x80000000) != 0)
{
uint32 *d = new uint32[(m - 0x80000000) * 4];
for (uint32 i = 0x80000001; i <= m; i++)
{
uint32 *t = d + (i - 0x80000001) * 4;
#ifdef COMPILER_MSVC64
__cpuid((int *) (d + (i - 0x80000001) * 4), i);
#else
__asm
{
mov eax, i;
mov esi, t;
cpuid;
mov dword ptr [esi + 0x0], eax;
mov dword ptr [esi + 0x4], ebx;
mov dword ptr [esi + 0x8], ecx;
mov dword ptr [esi + 0xC], edx;
}
#endif
}
if (m >= 0x80000002)
brand = (tchar *)(d + 4);
// note the assignment to brand above does a copy, we need to delete
delete[] d;
}
}
};
#endif // IA32DETECT_H

View File

@@ -0,0 +1,65 @@
//===== Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ======//
//
// Purpose:
//
//===========================================================================//
#ifndef TIER0_ICOMMANDLINE_H
#define TIER0_ICOMMANDLINE_H
#ifdef _WIN32
#pragma once
#endif
#include "tier0/platform.h"
//-----------------------------------------------------------------------------
// Purpose: Interface to engine command line
//-----------------------------------------------------------------------------
abstract_class ICommandLine
{
public:
virtual void CreateCmdLine( const char *commandline ) = 0;
virtual void CreateCmdLine( int argc, char **argv ) = 0;
virtual const char *GetCmdLine( void ) const = 0;
// Check whether a particular parameter exists
virtual const char *CheckParm( const char *psz, const char **ppszValue = 0 ) const = 0;
virtual void RemoveParm( const char *parm ) = 0;
virtual void AppendParm( const char *pszParm, const char *pszValues ) = 0;
// Returns the argument after the one specified, or the default if not found
virtual const char *ParmValue( const char *psz, const char *pDefaultVal = 0 ) const = 0;
virtual int ParmValue( const char *psz, int nDefaultVal ) const = 0;
virtual float ParmValue( const char *psz, float flDefaultVal ) const = 0;
// Gets at particular parameters
virtual int ParmCount() const = 0;
virtual int FindParm( const char *psz ) const = 0; // Returns 0 if not found.
virtual const char* GetParm( int nIndex ) const = 0;
// copies the string passwed
virtual void SetParm( int nIndex, char const *pNewParm ) =0;
};
//-----------------------------------------------------------------------------
// Gets a singleton to the commandline interface
// NOTE: The #define trickery here is necessary for backwards compat:
// this interface used to lie in the vstdlib library.
//-----------------------------------------------------------------------------
PLATFORM_INTERFACE ICommandLine *CommandLine();
//-----------------------------------------------------------------------------
// Process related functions
//-----------------------------------------------------------------------------
PLATFORM_INTERFACE const tchar *Plat_GetCommandLine();
#ifndef _WIN32
// helper function for OS's that don't have a ::GetCommandLine() call
PLATFORM_INTERFACE void Plat_SetCommandLine( const char *cmdLine );
#endif
PLATFORM_INTERFACE const char *Plat_GetCommandLineA();
#endif // TIER0_ICOMMANDLINE_H

29
external/vpc/public/tier0/ioctlcodes.h vendored Normal file
View File

@@ -0,0 +1,29 @@
//========= Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//
//=============================================================================//
#ifndef IOCTLCODES_H
#define IOCTLCODES_H
#pragma once
// Define the IOCTL codes we will use. The IOCTL code contains a command
// identifier, plus other information about the device, the type of access
// with which the file must have been opened, and the type of buffering.
// Device type -- in the "User Defined" range."
#define DEVICE_FILE_TYPE 40000
// The IOCTL function codes from 0x800 to 0xFFF are for customer use.
#define IOCTL_WRITE_MSR \
CTL_CODE( DEVICE_FILE_TYPE, 0x900, METHOD_BUFFERED, FILE_READ_ACCESS )
#define IOCTL_READ_MSR \
CTL_CODE( DEVICE_FILE_TYPE, 0x901, METHOD_BUFFERED, FILE_READ_ACCESS )
#endif IOCTLCODES_H

File diff suppressed because it is too large Load Diff

47
external/vpc/public/tier0/l2cache.h vendored Normal file
View File

@@ -0,0 +1,47 @@
//========= Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================//
#ifndef CL2CACHE_H
#define CL2CACHE_H
#ifdef _WIN32
#pragma once
#endif
class P4Event_BSQ_cache_reference;
class CL2Cache
{
public:
CL2Cache();
~CL2Cache();
void Start( void );
void End( void );
//-------------------------------------------------------------------------
// GetL2CacheMisses
//-------------------------------------------------------------------------
int GetL2CacheMisses( void )
{
return m_iL2CacheMissCount;
}
#ifdef DBGFLAG_VALIDATE
void Validate( CValidator &validator, tchar *pchName ); // Validate our internal structures
#endif // DBGFLAG_VALIDATE
private:
int m_nID;
P4Event_BSQ_cache_reference *m_pL2CacheEvent;
int64 m_i64Start;
int64 m_i64End;
int m_iL2CacheMissCount;
};
#endif // CL2CACHE_H

767
external/vpc/public/tier0/logging.h vendored Normal file
View File

@@ -0,0 +1,767 @@
//============ Copyright (c) Valve Corporation, All rights reserved. ============
//
// Logging system declarations.
//
// The logging system is a channel-based output mechanism which allows
// subsystems to route their text/diagnostic output to various listeners
//
//===============================================================================
#ifndef LOGGING_H
#define LOGGING_H
#if defined( COMPILER_MSVC )
#pragma once
#endif
#include "color.h"
#include "icommandline.h"
#include <stdio.h>
// For XBX_** functions
#if defined( _X360 )
#include "xbox/xbox_console.h"
#endif
// Used by CColorizedLoggingListener
#if defined( _WIN32 ) || (defined(POSIX) && !defined(_GAMECONSOLE))
#include "tier0/win32consoleio.h"
#endif
/*
---- Logging System ----
The logging system is a channel-based mechanism for all code (engine,
mod, tool) across all platforms to output information, warnings,
errors, etc.
This system supersedes the existing Msg(), Warning(), Error(), DevMsg(), ConMsg() etc. functions.
There are channels defined in the new system through which all old messages are routed;
see LOG_GENERAL, LOG_CONSOLE, LOG_DEVELOPER, etc.
To use the system, simply call one of the predefined macros:
Log_Msg( ChannelID, [Color], Message, ... )
Log_Warning( ChannelID, [Color], Message, ... )
Log_Error( ChannelID, [Color], Message, ... )
A ChannelID is typically created by defining a logging channel with the
log channel macros:
DEFINE_LOGGING_CHANNEL_NO_TAGS( LOG_ChannelName, "ChannelName", [Flags], [MinimumSeverity], [Color] );
or
BEGIN_DEFINE_LOGGING_CHANNEL( LOG_ChannelName, "ChannelName", [Flags], [MinimumSeverity], [Color] );
ADD_LOGGING_CHANNEL_TAG( "Tag1" );
ADD_LOGGING_CHANNEL_TAG( "Tag2" );
END_DEFINE_LOGGING_CHANNEL();
These macros create a global channel ID variable with the name specified
by the first parameter (in this example, LOG_ChannelName). This channel ID
can be used by various LoggingSystem_** functions to manipulate the channel settings.
The optional [Flags] parameter is an OR'd together set of LoggingChannelFlags_t
values (default: 0).
The optional [MinimumSeverity] parameter is the lowest threshold
above which messages will be processed (inclusive). The default is LS_MESSAGE,
which results in all messages, warnings, and errors being logged.
Variadic parameters to the Log_** functions will be ignored if a channel
is not enabled for a given severity (for performance reasons).
Logging channels can have their minimum severity modified by name, ID, or tag.
Logging channels are not hierarchical since there are situations in which
a channel needs to belong to multiple hierarchies. Use tags to create
categories or shallow hierarchies.
@TODO (Feature wishlist):
1) Callstack logging support
2) Registering dynamic channels and unregistering channels at runtime
3) Sentient robot to clean up the thousands of places using the old/legacy logging system.
*/
//////////////////////////////////////////////////////////////////////////
// Constants, Types, Forward Declares
//////////////////////////////////////////////////////////////////////////
class CLoggingSystem;
class CThreadFastMutex;
//-----------------------------------------------------------------------------
// Maximum length of a sprintf'ed logging message.
//-----------------------------------------------------------------------------
const int MAX_LOGGING_MESSAGE_LENGTH = 2048;
//-----------------------------------------------------------------------------
// Maximum length of a channel or tag name.
//-----------------------------------------------------------------------------
const int MAX_LOGGING_IDENTIFIER_LENGTH = 32;
//-----------------------------------------------------------------------------
// Maximum number of logging channels. Increase if needed.
//-----------------------------------------------------------------------------
const int MAX_LOGGING_CHANNEL_COUNT = 256;
//-----------------------------------------------------------------------------
// Maximum number of logging tags across all channels. Increase if needed.
//-----------------------------------------------------------------------------
const int MAX_LOGGING_TAG_COUNT = 1024;
//-----------------------------------------------------------------------------
// Maximum number of characters across all logging tags. Increase if needed.
//-----------------------------------------------------------------------------
const int MAX_LOGGING_TAG_CHARACTER_COUNT = 8192;
//-----------------------------------------------------------------------------
// Maximum number of concurrent logging listeners in a given logging state.
//-----------------------------------------------------------------------------
const int MAX_LOGGING_LISTENER_COUNT = 16;
//-----------------------------------------------------------------------------
// An invalid color set on a channel to imply that it should use
// a device-dependent default color where applicable.
//-----------------------------------------------------------------------------
const Color UNSPECIFIED_LOGGING_COLOR( 0, 0, 0, 0 );
//-----------------------------------------------------------------------------
// An ID returned by the logging system to refer to a logging channel.
//-----------------------------------------------------------------------------
typedef int LoggingChannelID_t;
//-----------------------------------------------------------------------------
// A sentinel value indicating an invalid logging channel ID.
//-----------------------------------------------------------------------------
const LoggingChannelID_t INVALID_LOGGING_CHANNEL_ID = -1;
//-----------------------------------------------------------------------------
// The severity of a logging operation.
//-----------------------------------------------------------------------------
enum LoggingSeverity_t
{
//-----------------------------------------------------------------------------
// An informative logging message.
//-----------------------------------------------------------------------------
LS_MESSAGE = 0,
//-----------------------------------------------------------------------------
// A warning, typically non-fatal
//-----------------------------------------------------------------------------
LS_WARNING = 1,
//-----------------------------------------------------------------------------
// A message caused by an Assert**() operation.
//-----------------------------------------------------------------------------
LS_ASSERT = 2,
//-----------------------------------------------------------------------------
// An error, typically fatal/unrecoverable.
//-----------------------------------------------------------------------------
LS_ERROR = 3,
//-----------------------------------------------------------------------------
// A placeholder level, higher than any legal value.
// Not a real severity value!
//-----------------------------------------------------------------------------
LS_HIGHEST_SEVERITY = 4,
};
//-----------------------------------------------------------------------------
// Action which should be taken by logging system as a result of
// a given logged message.
//
// The logging system invokes ILoggingResponsePolicy::OnLog() on
// the specified policy object, which returns a LoggingResponse_t.
//-----------------------------------------------------------------------------
enum LoggingResponse_t
{
LR_CONTINUE,
LR_DEBUGGER,
LR_ABORT,
};
//-----------------------------------------------------------------------------
// Logging channel behavior flags, set on channel creation.
//-----------------------------------------------------------------------------
enum LoggingChannelFlags_t
{
//-----------------------------------------------------------------------------
// Indicates that the spew is only relevant to interactive consoles.
//-----------------------------------------------------------------------------
LCF_CONSOLE_ONLY = 0x00000001,
//-----------------------------------------------------------------------------
// Indicates that spew should not be echoed to any output devices.
// A suitable logging listener must be registered which respects this flag
// (e.g. a file logger).
//-----------------------------------------------------------------------------
LCF_DO_NOT_ECHO = 0x00000002,
};
//-----------------------------------------------------------------------------
// A callback function used to register tags on a logging channel
// during initialization.
//-----------------------------------------------------------------------------
typedef void ( *RegisterTagsFunc )();
//-----------------------------------------------------------------------------
// A context structure passed to logging listeners and response policy classes.
//-----------------------------------------------------------------------------
struct LoggingContext_t
{
// ID of the channel being logged to.
LoggingChannelID_t m_ChannelID;
// Flags associated with the channel.
LoggingChannelFlags_t m_Flags;
// Severity of the logging event.
LoggingSeverity_t m_Severity;
// Color of logging message if one was specified to Log_****() macro.
// If not specified, falls back to channel color.
// If channel color is not specified, this value is UNSPECIFIED_LOGGING_COLOR
// and indicates that a suitable default should be chosen.
Color m_Color;
};
//-----------------------------------------------------------------------------
// Interface for classes to handle logging output.
//
// The Log() function of this class is called synchronously and serially
// by the logging system on all registered instances of ILoggingListener
// in the current "logging state".
//
// Derived classes may do whatever they want with the message (write to disk,
// write to console, send over the network, drop on the floor, etc.).
//
// In general, derived classes should do one, simple thing with the output
// to allow callers to register multiple, orthogonal logging listener classes.
//-----------------------------------------------------------------------------
class ILoggingListener
{
public:
virtual void Log( const LoggingContext_t *pContext, const tchar *pMessage ) = 0;
};
//-----------------------------------------------------------------------------
// Interface for policy classes which determine how to behave when a
// message is logged.
//
// Can return:
// LR_CONTINUE (continue execution)
// LR_DEBUGGER (break into debugger if one is present, otherwise continue)
// LR_ABORT (terminate process immediately with a failure code of 1)
//-----------------------------------------------------------------------------
class ILoggingResponsePolicy
{
public:
virtual LoggingResponse_t OnLog( const LoggingContext_t *pContext ) = 0;
};
//////////////////////////////////////////////////////////////////////////
// Common Logging Listeners & Logging Response Policies
//////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------------
// A basic logging listener which prints to stdout and the debug channel.
//-----------------------------------------------------------------------------
class CSimpleLoggingListener : public ILoggingListener
{
public:
CSimpleLoggingListener( bool bQuietPrintf = false, bool bQuietDebugger = false ) :
m_bQuietPrintf( bQuietPrintf ),
m_bQuietDebugger( bQuietDebugger )
{
}
virtual void Log( const LoggingContext_t *pContext, const tchar *pMessage )
{
#ifdef _X360
if ( !m_bQuietDebugger && XBX_IsConsoleConnected() )
{
// send to console
XBX_DebugString( XMAKECOLOR( 0,0,0 ), pMessage );
}
else
#endif
{
#if !defined( _CERT ) && !defined( DBGFLAG_STRINGS_STRIP )
if ( !m_bQuietPrintf )
{
_tprintf( _T("%s"), pMessage );
}
#endif
#ifdef _WIN32
if ( !m_bQuietDebugger && Plat_IsInDebugSession() )
{
Plat_DebugString( pMessage );
}
#endif
}
}
// If set to true, does not print anything to stdout.
bool m_bQuietPrintf;
// If set to true, does not print anything to debugger.
bool m_bQuietDebugger;
};
//-----------------------------------------------------------------------------
// A basic logging listener for GUI applications
//-----------------------------------------------------------------------------
class CSimpleWindowsLoggingListener : public ILoggingListener
{
public:
virtual void Log( const LoggingContext_t *pContext, const tchar *pMessage )
{
if ( Plat_IsInDebugSession() )
{
Plat_DebugString( pMessage );
}
if ( pContext->m_Severity == LS_ERROR )
{
if ( Plat_IsInDebugSession() )
DebuggerBreak();
Plat_MessageBox( "Error", pMessage );
}
}
};
//-----------------------------------------------------------------------------
// ** NOTE FOR INTEGRATION **
// This was copied over from source 2 rather than integrated because
// source 2 has more significantly refactored tier0 logging.
//
// A logging listener with Win32 console API color support which which prints
// to stdout and the debug channel.
//-----------------------------------------------------------------------------
#if !defined(_GAMECONSOLE)
class CColorizedLoggingListener : public CSimpleLoggingListener
{
public:
CColorizedLoggingListener( bool bQuietPrintf = false, bool bQuietDebugger = false ) : CSimpleLoggingListener( bQuietPrintf, bQuietDebugger )
{
InitWin32ConsoleColorContext( &m_ColorContext );
}
virtual void Log( const LoggingContext_t *pContext, const tchar *pMessage )
{
if ( !m_bQuietPrintf )
{
int nPrevColor = -1;
if ( pContext->m_Color != UNSPECIFIED_LOGGING_COLOR )
{
nPrevColor = SetWin32ConsoleColor( &m_ColorContext,
pContext->m_Color.r(), pContext->m_Color.g(), pContext->m_Color.b(),
MAX( MAX( pContext->m_Color.r(), pContext->m_Color.g() ), pContext->m_Color.b() ) > 128 );
}
_tprintf( _T("%s"), pMessage );
if ( nPrevColor >= 0 )
{
RestoreWin32ConsoleColor( &m_ColorContext, nPrevColor );
}
}
#ifdef _WIN32
if ( !m_bQuietDebugger && Plat_IsInDebugSession() )
{
Plat_DebugString( pMessage );
}
#endif
}
Win32ConsoleColorContext_t m_ColorContext;
};
#endif // !_GAMECONSOLE
//-----------------------------------------------------------------------------
// Default logging response policy used when one is not specified.
//-----------------------------------------------------------------------------
class CDefaultLoggingResponsePolicy : public ILoggingResponsePolicy
{
public:
virtual LoggingResponse_t OnLog( const LoggingContext_t *pContext )
{
if ( pContext->m_Severity == LS_ASSERT && !CommandLine()->FindParm( "-noassert" ) )
{
return LR_DEBUGGER;
}
else if ( pContext->m_Severity == LS_ERROR )
{
return LR_ABORT;
}
else
{
return LR_CONTINUE;
}
}
};
//-----------------------------------------------------------------------------
// A logging response policy which never terminates the process, even on error.
//-----------------------------------------------------------------------------
class CNonFatalLoggingResponsePolicy : public ILoggingResponsePolicy
{
public:
virtual LoggingResponse_t OnLog( const LoggingContext_t *pContext )
{
if ( ( pContext->m_Severity == LS_ASSERT && !CommandLine()->FindParm( "-noassert" ) ) || pContext->m_Severity == LS_ERROR )
{
return LR_DEBUGGER;
}
else
{
return LR_CONTINUE;
}
}
};
//////////////////////////////////////////////////////////////////////////
// Central Logging System
//////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------------
// The central logging system.
//
// Multiple instances can exist, though all exported tier0 functionality
// specifically works with a single global instance
// (via GetGlobalLoggingSystem()).
//-----------------------------------------------------------------------------
class CLoggingSystem
{
public:
struct LoggingChannel_t;
CLoggingSystem();
~CLoggingSystem();
//-----------------------------------------------------------------------------
// Register a logging channel with the logging system.
// The same channel can be registered multiple times, but the parameters
// in each call to RegisterLoggingChannel must either match across all calls
// or be set to defaults on any given call
//
// This function is not thread-safe and should generally only be called
// by a single thread. Using the logging channel definition macros ensures
// that this is called on the static initialization thread.
//-----------------------------------------------------------------------------
LoggingChannelID_t RegisterLoggingChannel( const char *pChannelName, RegisterTagsFunc registerTagsFunc, int flags = 0, LoggingSeverity_t minimumSeverity = LS_MESSAGE, Color spewColor = UNSPECIFIED_LOGGING_COLOR );
//-----------------------------------------------------------------------------
// Gets a channel ID from a string name.
// Performs a simple linear search; cache the value whenever possible
// or re-register the logging channel to get a global ID.
//-----------------------------------------------------------------------------
LoggingChannelID_t FindChannel( const char *pChannelName ) const;
int GetChannelCount() const { return m_nChannelCount; }
//-----------------------------------------------------------------------------
// Gets a pointer to the logging channel description.
//-----------------------------------------------------------------------------
LoggingChannel_t *GetChannel( LoggingChannelID_t channelID );
const LoggingChannel_t *GetChannel( LoggingChannelID_t channelID ) const;
//-----------------------------------------------------------------------------
// Returns true if the given channel has the specified tag.
//-----------------------------------------------------------------------------
bool HasTag( LoggingChannelID_t channelID, const char *pTag ) const { return GetChannel( channelID )->HasTag( pTag ); }
//-----------------------------------------------------------------------------
// Returns true if the given channel has been initialized.
// The main purpose is catching m_nChannelCount being zero because no channels have been registered.
//-----------------------------------------------------------------------------
bool IsValidChannelID( LoggingChannelID_t channelID ) const { return ( channelID >= 0 ) && ( channelID < m_nChannelCount ); }
//-----------------------------------------------------------------------------
// Returns true if the given channel will spew at the given severity level.
//-----------------------------------------------------------------------------
bool IsChannelEnabled( LoggingChannelID_t channelID, LoggingSeverity_t severity ) const { return IsValidChannelID( channelID ) && GetChannel( channelID )->IsEnabled( severity ); }
//-----------------------------------------------------------------------------
// Functions to set the spew level of a channel either directly by ID or
// string name, or for all channels with a given tag.
//
// These functions are not technically thread-safe but calling them across
// multiple threads should cause no significant problems
// (the underlying data types being changed are 32-bit/atomic).
//-----------------------------------------------------------------------------
void SetChannelSpewLevel( LoggingChannelID_t channelID, LoggingSeverity_t minimumSeverity );
void SetChannelSpewLevelByName( const char *pName, LoggingSeverity_t minimumSeverity );
void SetChannelSpewLevelByTag( const char *pTag, LoggingSeverity_t minimumSeverity );
//-----------------------------------------------------------------------------
// Gets or sets the color of a logging channel.
// (The functions are not thread-safe, but the consequences are not
// significant.)
//-----------------------------------------------------------------------------
Color GetChannelColor( LoggingChannelID_t channelID ) const { return GetChannel( channelID )->m_SpewColor; }
void SetChannelColor( LoggingChannelID_t channelID, Color color ) { GetChannel( channelID )->m_SpewColor = color; }
//-----------------------------------------------------------------------------
// Gets or sets the flags on a logging channel.
// (The functions are not thread-safe, but the consequences are not
// significant.)
//-----------------------------------------------------------------------------
LoggingChannelFlags_t GetChannelFlags( LoggingChannelID_t channelID ) const { return GetChannel( channelID )->m_Flags; }
void SetChannelFlags( LoggingChannelID_t channelID, LoggingChannelFlags_t flags ) { GetChannel( channelID )->m_Flags = flags; }
//-----------------------------------------------------------------------------
// Adds a string tag to a channel.
// This is not thread-safe and should only be called by a RegisterTagsFunc
// callback passed in to RegisterLoggingChannel (via the
// channel definition macros).
//-----------------------------------------------------------------------------
void AddTagToCurrentChannel( const char *pTagName );
//-----------------------------------------------------------------------------
// Functions to save/restore the current logging state.
// Set bThreadLocal to true on a matching Push/Pop call if the intent
// is to override the logging listeners on the current thread only.
//
// Pushing the current logging state onto the state stack results
// in the current state being cleared by default (no listeners, default logging response policy).
// Set bClearState to false to copy the existing listener pointers to the new state.
//
// These functions which mutate logging state ARE thread-safe and are
// guarded by m_StateMutex.
//-----------------------------------------------------------------------------
void PushLoggingState( bool bThreadLocal = false, bool bClearState = true );
void PopLoggingState( bool bThreadLocal = false );
//-----------------------------------------------------------------------------
// Registers a logging listener (a class which handles logged messages).
//-----------------------------------------------------------------------------
void RegisterLoggingListener( ILoggingListener *pListener );
//-----------------------------------------------------------------------------
// Removes a logging listener from the registered list
//-----------------------------------------------------------------------------
void UnregisterLoggingListener( ILoggingListener *pListener );
//-----------------------------------------------------------------------------
// Returns whether the specified logging listener is registered.
//-----------------------------------------------------------------------------
bool IsListenerRegistered( ILoggingListener *pListener );
//-----------------------------------------------------------------------------
// Clears out all of the current logging state (removes all listeners,
// sets the response policy to the default).
//-----------------------------------------------------------------------------
void ResetCurrentLoggingState();
//-----------------------------------------------------------------------------
// Sets a policy class to decide what should happen when messages of a
// particular severity are logged
// (e.g. exit on error, break into debugger).
// If pLoggingResponse is NULL, uses the default response policy class.
//-----------------------------------------------------------------------------
void SetLoggingResponsePolicy( ILoggingResponsePolicy *pLoggingResponse );
//-----------------------------------------------------------------------------
// Logs a message to the specified channel using a given severity and
// spew color. Passing in UNSPECIFIED_LOGGING_COLOR for 'color' allows
// the logging listeners to provide a default.
// NOTE: test 'IsChannelEnabled(channelID,severity)' before calling this!
//-----------------------------------------------------------------------------
LoggingResponse_t LogDirect( LoggingChannelID_t channelID, LoggingSeverity_t severity, Color color, const tchar *pMessage );
// Internal data to represent a logging tag
struct LoggingTag_t
{
const char *m_pTagName;
LoggingTag_t *m_pNextTag;
};
// Internal data to represent a logging channel.
struct LoggingChannel_t
{
bool HasTag( const char *pTag ) const
{
LoggingTag_t *pCurrentTag = m_pFirstTag;
while( pCurrentTag != NULL )
{
if ( stricmp( pCurrentTag->m_pTagName, pTag ) == 0 )
{
return true;
}
pCurrentTag = pCurrentTag->m_pNextTag;
}
return false;
}
bool IsEnabled( LoggingSeverity_t severity ) const { return severity >= m_MinimumSeverity; }
void SetSpewLevel( LoggingSeverity_t severity ) { m_MinimumSeverity = severity; }
LoggingChannelID_t m_ID;
LoggingChannelFlags_t m_Flags; // an OR'd combination of LoggingChannelFlags_t
LoggingSeverity_t m_MinimumSeverity; // The minimum severity level required to activate this channel.
Color m_SpewColor;
char m_Name[MAX_LOGGING_IDENTIFIER_LENGTH];
LoggingTag_t *m_pFirstTag;
};
private:
// Represents the current state of the logger (registered listeners, response policy class, etc.) and can
// vary from thread-to-thread. It can also be pushed/popped to save/restore listener/response state.
struct LoggingState_t
{
// Index of the previous entry on the listener set stack.
int m_nPreviousStackEntry;
// Number of active listeners in this set. Cannot exceed MAX_LOGGING_LISTENER_COUNT.
// If set to -1, implies that this state structure is not in use.
int m_nListenerCount;
// Array of registered logging listener objects.
ILoggingListener *m_RegisteredListeners[MAX_LOGGING_LISTENER_COUNT];
// Specific policy class to determine behavior of logging system under specific message types.
ILoggingResponsePolicy *m_pLoggingResponse;
};
// These state functions to assume the caller has already grabbed the mutex.
LoggingState_t *GetCurrentState();
const LoggingState_t *GetCurrentState() const;
int FindUnusedStateIndex();
LoggingTag_t *AllocTag( const char *pTagName );
int m_nChannelCount;
LoggingChannel_t m_RegisteredChannels[MAX_LOGGING_CHANNEL_COUNT];
int m_nChannelTagCount;
LoggingTag_t m_ChannelTags[MAX_LOGGING_TAG_COUNT];
// Index to first free character in name pool.
int m_nTagNamePoolIndex;
// Pool of character data used for tag names.
char m_TagNamePool[MAX_LOGGING_TAG_CHARACTER_COUNT];
// Protects all data in this class except the registered channels
// (which are supposed to be registered using the macros at static/global init time).
// It is assumed that this mutex is reentrant safe on all platforms.
CThreadFastMutex *m_pStateMutex;
// The index of the current "global" state of the logging system. By default, all threads use this state
// for logging unless a given thread has pushed the logging state with bThreadLocal == true.
// If a thread-local state has been pushed, g_nThreadLocalStateIndex (a global thread-local integer) will be non-zero.
// By default, g_nThreadLocalStateIndex is 0 for all threads.
int m_nGlobalStateIndex;
// A pool of logging states used to store a stack (potentially per-thread).
static const int MAX_LOGGING_STATE_COUNT = 16;
LoggingState_t m_LoggingStates[MAX_LOGGING_STATE_COUNT];
// Default policy class which determines behavior.
CDefaultLoggingResponsePolicy m_DefaultLoggingResponse;
// Default spew function.
CSimpleLoggingListener m_DefaultLoggingListener;
};
//////////////////////////////////////////////////////////////////////////
// Logging Macros
//////////////////////////////////////////////////////////////////////////
// This macro will resolve to the most appropriate overload of LoggingSystem_Log() depending on the number of parameters passed in.
#ifdef DBGFLAG_STRINGS_STRIP
#define InternalMsg( Channel, Severity, /* [Color], Message, */ ... ) do { if ( Severity == LS_ERROR && LoggingSystem_IsChannelEnabled( Channel, Severity ) ) LoggingSystem_Log( Channel, Severity, /* [Color], Message, */ ##__VA_ARGS__ ); } while( 0 )
#else
#define InternalMsg( Channel, Severity, /* [Color], Message, */ ... ) do { if ( LoggingSystem_IsChannelEnabled( Channel, Severity ) ) LoggingSystem_Log( Channel, Severity, /* [Color], Message, */ ##__VA_ARGS__ ); } while( 0 )
#endif
//-----------------------------------------------------------------------------
// New macros, use these!
//
// The macros take an optional Color parameter followed by the message
// and the message formatting.
// We rely on the variadic macro (__VA_ARGS__) operator to paste in the
// extra parameters and resolve to the appropriate overload.
//-----------------------------------------------------------------------------
#define Log_Msg( Channel, /* [Color], Message, */ ... ) InternalMsg( Channel, LS_MESSAGE, /* [Color], Message, */ ##__VA_ARGS__ )
#define Log_Warning( Channel, /* [Color], Message, */ ... ) InternalMsg( Channel, LS_WARNING, /* [Color], Message, */ ##__VA_ARGS__ )
#define Log_Error( Channel, /* [Color], Message, */ ... ) InternalMsg( Channel, LS_ERROR, /* [Color], Message, */ ##__VA_ARGS__ )
#ifdef DBGFLAG_STRINGS_STRIP
#define Log_Assert( ... ) LR_CONTINUE
#else
#define Log_Assert( Message, ... ) LoggingSystem_LogAssert( Message, ##__VA_ARGS__ )
#endif
#define DECLARE_LOGGING_CHANNEL( Channel ) extern LoggingChannelID_t Channel
#define DEFINE_LOGGING_CHANNEL_NO_TAGS( Channel, ChannelName, /* [Flags], [Severity], [Color] */ ... ) \
LoggingChannelID_t Channel = LoggingSystem_RegisterLoggingChannel( ChannelName, NULL, ##__VA_ARGS__ )
#define BEGIN_DEFINE_LOGGING_CHANNEL( Channel, ChannelName, /* [Flags], [Severity], [Color] */ ... ) \
static void Register_##Channel##_Tags(); \
LoggingChannelID_t Channel = LoggingSystem_RegisterLoggingChannel( ChannelName, Register_##Channel##_Tags, ##__VA_ARGS__ ); \
void Register_##Channel##_Tags() \
{
#define ADD_LOGGING_CHANNEL_TAG( Tag ) LoggingSystem_AddTagToCurrentChannel( Tag )
#define END_DEFINE_LOGGING_CHANNEL() \
}
//////////////////////////////////////////////////////////////////////////
// DLL Exports
//////////////////////////////////////////////////////////////////////////
// For documentation on these functions, please look at the corresponding function
// in CLoggingSystem (unless otherwise specified).
PLATFORM_INTERFACE LoggingChannelID_t LoggingSystem_RegisterLoggingChannel( const char *pName, RegisterTagsFunc registerTagsFunc, int flags = 0, LoggingSeverity_t severity = LS_MESSAGE, Color color = UNSPECIFIED_LOGGING_COLOR );
PLATFORM_INTERFACE void LoggingSystem_RegisterLoggingListener( ILoggingListener *pListener );
PLATFORM_INTERFACE void LoggingSystem_UnregisterLoggingListener( ILoggingListener *pListener );
PLATFORM_INTERFACE void LoggingSystem_ResetCurrentLoggingState();
PLATFORM_INTERFACE void LoggingSystem_SetLoggingResponsePolicy( ILoggingResponsePolicy *pResponsePolicy );
// NOTE: PushLoggingState() saves the current logging state on a stack and results in a new clear state
// (no listeners, default logging response policy).
PLATFORM_INTERFACE void LoggingSystem_PushLoggingState( bool bThreadLocal = false, bool bClearState = true );
PLATFORM_INTERFACE void LoggingSystem_PopLoggingState( bool bThreadLocal = false );
PLATFORM_INTERFACE void LoggingSystem_AddTagToCurrentChannel( const char *pTagName );
// Returns INVALID_LOGGING_CHANNEL_ID if not found
PLATFORM_INTERFACE LoggingChannelID_t LoggingSystem_FindChannel( const char *pChannelName );
PLATFORM_INTERFACE int LoggingSystem_GetChannelCount();
PLATFORM_INTERFACE LoggingChannelID_t LoggingSystem_GetFirstChannelID();
// Returns INVALID_LOGGING_CHANNEL_ID when there are no channels remaining.
PLATFORM_INTERFACE LoggingChannelID_t LoggingSystem_GetNextChannelID( LoggingChannelID_t channelID );
PLATFORM_INTERFACE const CLoggingSystem::LoggingChannel_t *LoggingSystem_GetChannel( LoggingChannelID_t channelID );
PLATFORM_INTERFACE bool LoggingSystem_HasTag( LoggingChannelID_t channelID, const char *pTag );
PLATFORM_INTERFACE bool LoggingSystem_IsChannelEnabled( LoggingChannelID_t channelID, LoggingSeverity_t severity );
PLATFORM_INTERFACE void LoggingSystem_SetChannelSpewLevel( LoggingChannelID_t channelID, LoggingSeverity_t minimumSeverity );
PLATFORM_INTERFACE void LoggingSystem_SetChannelSpewLevelByName( const char *pName, LoggingSeverity_t minimumSeverity );
PLATFORM_INTERFACE void LoggingSystem_SetChannelSpewLevelByTag( const char *pTag, LoggingSeverity_t minimumSeverity );
// Color is represented as an int32 due to C-linkage restrictions
PLATFORM_INTERFACE int32 LoggingSystem_GetChannelColor( LoggingChannelID_t channelID );
PLATFORM_INTERFACE void LoggingSystem_SetChannelColor( LoggingChannelID_t channelID, int color );
PLATFORM_INTERFACE LoggingChannelFlags_t LoggingSystem_GetChannelFlags( LoggingChannelID_t channelID );
PLATFORM_INTERFACE void LoggingSystem_SetChannelFlags( LoggingChannelID_t channelID, LoggingChannelFlags_t flags );
//-----------------------------------------------------------------------------
// Logs a variable-argument to a given channel with the specified severity.
// NOTE: if adding overloads to this function, remember that the Log_***
// macros simply pass their variadic parameters through to LoggingSystem_Log().
// Therefore, you need to ensure that the parameters are in the same general
// order and that there are no ambiguities with the overload.
//-----------------------------------------------------------------------------
PLATFORM_INTERFACE LoggingResponse_t LoggingSystem_Log( LoggingChannelID_t channelID, LoggingSeverity_t severity, const char *pMessageFormat, ... ) FMTFUNCTION( 3, 4 );
PLATFORM_OVERLOAD LoggingResponse_t LoggingSystem_Log( LoggingChannelID_t channelID, LoggingSeverity_t severity, Color spewColor, const char *pMessageFormat, ... ) FMTFUNCTION( 4, 5 );
PLATFORM_INTERFACE LoggingResponse_t LoggingSystem_LogDirect( LoggingChannelID_t channelID, LoggingSeverity_t severity, Color spewColor, const char *pMessage );
PLATFORM_INTERFACE LoggingResponse_t LoggingSystem_LogAssert( const char *pMessageFormat, ... ) FMTFUNCTION( 1, 2 );
#endif // LOGGING_H

50
external/vpc/public/tier0/mem.h vendored Normal file
View File

@@ -0,0 +1,50 @@
//========= Copyright (c) 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose: Memory allocation!
//
// $NoKeywords: $
//=============================================================================//
#ifndef TIER0_MEM_H
#define TIER0_MEM_H
#ifdef _WIN32
#pragma once
#endif
#include <stddef.h>
#include "tier0/platform.h"
#if !defined(STATIC_TIER0) && !defined(_STATIC_LINKED)
#ifdef TIER0_DLL_EXPORT
# define MEM_INTERFACE DLL_EXPORT
#else
# define MEM_INTERFACE DLL_IMPORT
#endif
#else // BUILD_AS_DLL
#define MEM_INTERFACE extern
#endif // BUILD_AS_DLL
//-----------------------------------------------------------------------------
// DLL-exported methods for particular kinds of memory
//-----------------------------------------------------------------------------
MEM_INTERFACE void *MemAllocScratch( int nMemSize );
MEM_INTERFACE void MemFreeScratch();
#if defined( POSIX )
MEM_INTERFACE void ZeroMemory( void *mem, size_t length );
#endif
//Only works with USE_MEM_DEBUG and memory allocation call stack tracking enabled.
MEM_INTERFACE int GetAllocationCallStack( void *mem, void **pCallStackOut, int iMaxEntriesOut );
#endif /* TIER0_MEM_H */

701
external/vpc/public/tier0/memalloc.h vendored Normal file
View File

@@ -0,0 +1,701 @@
//========= Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose: This header should never be used directly from leaf code!!!
// Instead, just add the file memoverride.cpp into your project and all this
// will automagically be used
//
// $NoKeywords: $
//=============================================================================//
#ifndef TIER0_MEMALLOC_H
#define TIER0_MEMALLOC_H
#ifdef _WIN32
#pragma once
#endif
// These memory debugging switches aren't relevant under Linux builds since memoverride.cpp
// isn't built into Linux projects
#ifndef LINUX
// Define this in release to get memory tracking even in release builds
//#define USE_MEM_DEBUG 1
// Define this in release to get light memory debugging
//#define USE_LIGHT_MEM_DEBUG
// Define this to require -uselmd to turn light memory debugging on
//#define LIGHT_MEM_DEBUG_REQUIRES_CMD_LINE_SWITCH
#endif
#if defined( _MEMTEST )
#if defined( _WIN32 ) || defined( _PS3 )
#define USE_MEM_DEBUG 1
#endif
#endif
#if defined( _PS3 )
// Define STEAM_SHARES_GAME_ALLOCATOR to make Steam use the game's tier0 memory allocator.
// This adds some memory to the game's Small Block Heap and Medium Block Heap, to compensate.
// This configuration was disabled for Portal 2, as we could not sufficiently test it before ship.
//#define STEAM_SHARES_GAME_ALLOCATOR
#endif
#if defined( STEAM_SHARES_GAME_ALLOCATOR )
#define MBYTES_STEAM_SBH_USAGE 2
#define MBYTES_STEAM_MBH_USAGE 4
#else // STEAM_SHARES_GAME_ALLOCATOR
#define MBYTES_STEAM_SBH_USAGE 0
#define MBYTES_STEAM_MBH_USAGE 0
#endif // STEAM_SHARES_GAME_ALLOCATOR
// Undefine this if using a compiler lacking threadsafe RTTI (like vc6)
#define MEM_DEBUG_CLASSNAME 1
#if !defined(STEAM) && !defined(NO_MALLOC_OVERRIDE)
#include <stddef.h>
#ifdef LINUX
#undef offsetof
#define offsetof(s,m) (size_t)&(((s *)0)->m)
#endif
#ifdef _PS3
#define MEMALLOC_SUPPORTS_ALIGNED_ALLOCATIONS 1
#endif
#include "tier0/mem.h"
struct _CrtMemState;
#define MEMALLOC_VERSION 1
typedef size_t (*MemAllocFailHandler_t)( size_t );
struct GenericMemoryStat_t
{
const char *name;
int value;
};
// Virtual memory interface
#include "tier0/memvirt.h"
//-----------------------------------------------------------------------------
// NOTE! This should never be called directly from leaf code
// Just use new,delete,malloc,free etc. They will call into this eventually
//-----------------------------------------------------------------------------
abstract_class IMemAlloc
{
public:
// Release versions
virtual void *Alloc( size_t nSize ) = 0;
public:
virtual void *Realloc( void *pMem, size_t nSize ) = 0;
virtual void Free( void *pMem ) = 0;
virtual void *Expand_NoLongerSupported( void *pMem, size_t nSize ) = 0;
// Debug versions
virtual void *Alloc( size_t nSize, const char *pFileName, int nLine ) = 0;
public:
virtual void *Realloc( void *pMem, size_t nSize, const char *pFileName, int nLine ) = 0;
virtual void Free( void *pMem, const char *pFileName, int nLine ) = 0;
virtual void *Expand_NoLongerSupported( void *pMem, size_t nSize, const char *pFileName, int nLine ) = 0;
#ifdef MEMALLOC_SUPPORTS_ALIGNED_ALLOCATIONS
virtual void *AllocAlign( size_t nSize, size_t align ) = 0;
virtual void *AllocAlign( size_t nSize, size_t align, const char *pFileName, int nLine ) = 0;
virtual void *ReallocAlign( void *pMem, size_t nSize, size_t align ) = 0;
#endif
inline void *IndirectAlloc( size_t nSize ) { return Alloc( nSize ); }
inline void *IndirectAlloc( size_t nSize, const char *pFileName, int nLine ) { return Alloc( nSize, pFileName, nLine ); }
// Returns the size of a particular allocation (NOTE: may be larger than the size requested!)
virtual size_t GetSize( void *pMem ) = 0;
// Force file + line information for an allocation
virtual void PushAllocDbgInfo( const char *pFileName, int nLine ) = 0;
virtual void PopAllocDbgInfo() = 0;
// FIXME: Remove when we have our own allocator
// these methods of the Crt debug code is used in our codebase currently
virtual int32 CrtSetBreakAlloc( int32 lNewBreakAlloc ) = 0;
virtual int CrtSetReportMode( int nReportType, int nReportMode ) = 0;
virtual int CrtIsValidHeapPointer( const void *pMem ) = 0;
virtual int CrtIsValidPointer( const void *pMem, unsigned int size, int access ) = 0;
virtual int CrtCheckMemory( void ) = 0;
virtual int CrtSetDbgFlag( int nNewFlag ) = 0;
virtual void CrtMemCheckpoint( _CrtMemState *pState ) = 0;
// FIXME: Make a better stats interface
virtual void DumpStats() = 0;
virtual void DumpStatsFileBase( char const *pchFileBase ) = 0;
virtual size_t ComputeMemoryUsedBy( char const *pchSubStr ) = 0;
// FIXME: Remove when we have our own allocator
virtual void* CrtSetReportFile( int nRptType, void* hFile ) = 0;
virtual void* CrtSetReportHook( void* pfnNewHook ) = 0;
virtual int CrtDbgReport( int nRptType, const char * szFile,
int nLine, const char * szModule, const char * pMsg ) = 0;
virtual int heapchk() = 0;
virtual bool IsDebugHeap() = 0;
virtual void GetActualDbgInfo( const char *&pFileName, int &nLine ) = 0;
virtual void RegisterAllocation( const char *pFileName, int nLine, size_t nLogicalSize, size_t nActualSize, unsigned nTime ) = 0;
virtual void RegisterDeallocation( const char *pFileName, int nLine, size_t nLogicalSize, size_t nActualSize, unsigned nTime ) = 0;
virtual int GetVersion() = 0;
virtual void CompactHeap() = 0;
// Function called when malloc fails or memory limits hit to attempt to free up memory (can come in any thread)
virtual MemAllocFailHandler_t SetAllocFailHandler( MemAllocFailHandler_t pfnMemAllocFailHandler ) = 0;
virtual void DumpBlockStats( void * ) = 0;
virtual void SetStatsExtraInfo( const char *pMapName, const char *pComment ) = 0;
// Returns 0 if no failure, otherwise the size_t of the last requested chunk
virtual size_t MemoryAllocFailed() = 0;
virtual void CompactIncremental() = 0;
virtual void OutOfMemory( size_t nBytesAttempted = 0 ) = 0;
// Region-based allocations
virtual void *RegionAlloc( int region, size_t nSize ) = 0;
virtual void *RegionAlloc( int region, size_t nSize, const char *pFileName, int nLine ) = 0;
// Replacement for ::GlobalMemoryStatus which accounts for unused memory in our system
virtual void GlobalMemoryStatus( size_t *pUsedMemory, size_t *pFreeMemory ) = 0;
// Obtain virtual memory manager interface
virtual IVirtualMemorySection * AllocateVirtualMemorySection( size_t numMaxBytes ) = 0;
// Request 'generic' memory stats (returns a list of N named values; caller should assume this list will change over time)
virtual int GetGenericMemoryStats( GenericMemoryStat_t **ppMemoryStats ) = 0;
virtual ~IMemAlloc() { };
// handles storing allocation info for coroutines
virtual uint32 GetDebugInfoSize() = 0;
virtual void SaveDebugInfo( void *pvDebugInfo ) = 0;
virtual void RestoreDebugInfo( const void *pvDebugInfo ) = 0;
virtual void InitDebugInfo( void *pvDebugInfo, const char *pchRootFileName, int nLine ) = 0;
};
//-----------------------------------------------------------------------------
// Singleton interface
//-----------------------------------------------------------------------------
#ifdef _PS3
PLATFORM_INTERFACE IMemAlloc * g_pMemAllocInternalPS3;
#ifndef PLATFORM_INTERFACE_MEM_ALLOC_INTERNAL_PS3_OVERRIDE
#define g_pMemAlloc g_pMemAllocInternalPS3
#else
#define g_pMemAlloc PLATFORM_INTERFACE_MEM_ALLOC_INTERNAL_PS3_OVERRIDE
#endif
#else // !_PS3
MEM_INTERFACE IMemAlloc *g_pMemAlloc;
#endif
//-----------------------------------------------------------------------------
#ifdef MEMALLOC_REGIONS
#ifndef MEMALLOC_REGION
#define MEMALLOC_REGION 0
#endif
inline void *MemAlloc_Alloc( size_t nSize )
{
return g_pMemAlloc->RegionAlloc( MEMALLOC_REGION, nSize );
}
inline void *MemAlloc_Alloc( size_t nSize, const char *pFileName, int nLine )
{
return g_pMemAlloc->RegionAlloc( MEMALLOC_REGION, nSize, pFileName, nLine );
}
#else
#undef MEMALLOC_REGION
inline void *MemAlloc_Alloc( size_t nSize )
{
return g_pMemAlloc->IndirectAlloc( nSize );
}
inline void *MemAlloc_Alloc( size_t nSize, const char *pFileName, int nLine )
{
return g_pMemAlloc->IndirectAlloc( nSize, pFileName, nLine );
}
#endif
//-----------------------------------------------------------------------------
#ifdef MEMALLOC_REGIONS
#else
#endif
inline bool ValueIsPowerOfTwo( size_t value ) // don't clash with mathlib definition
{
return (value & ( value - 1 )) == 0;
}
inline void *MemAlloc_AllocAlignedUnattributed( size_t size, size_t align )
{
#ifndef MEMALLOC_SUPPORTS_ALIGNED_ALLOCATIONS
unsigned char *pAlloc, *pResult;
#endif
if (!ValueIsPowerOfTwo(align))
return NULL;
#ifdef MEMALLOC_SUPPORTS_ALIGNED_ALLOCATIONS
return g_pMemAlloc->AllocAlign( size, align );
#else
align = (align > sizeof(void *) ? align : sizeof(void *)) - 1;
if ( (pAlloc = (unsigned char*)MemAlloc_Alloc( sizeof(void *) + align + size ) ) == (unsigned char*)NULL)
return NULL;
pResult = (unsigned char*)( (size_t)(pAlloc + sizeof(void *) + align ) & ~align );
((unsigned char**)(pResult))[-1] = pAlloc;
return (void *)pResult;
#endif
}
inline void *MemAlloc_AllocAlignedFileLine( size_t size, size_t align, const char *pszFile, int nLine )
{
#ifndef MEMALLOC_SUPPORTS_ALIGNED_ALLOCATIONS
unsigned char *pAlloc, *pResult;
#endif
if (!ValueIsPowerOfTwo(align))
return NULL;
#ifdef MEMALLOC_SUPPORTS_ALIGNED_ALLOCATIONS
return g_pMemAlloc->AllocAlign( size, align, pszFile, nLine );
#else
align = (align > sizeof(void *) ? align : sizeof(void *)) - 1;
if ( (pAlloc = (unsigned char*)MemAlloc_Alloc( sizeof(void *) + align + size, pszFile, nLine ) ) == (unsigned char*)NULL)
return NULL;
pResult = (unsigned char*)( (size_t)(pAlloc + sizeof(void *) + align ) & ~align );
((unsigned char**)(pResult))[-1] = pAlloc;
return (void *)pResult;
#endif
}
#ifdef USE_MEM_DEBUG
#define MemAlloc_AllocAligned( s, a ) MemAlloc_AllocAlignedFileLine( s, a, __FILE__, __LINE__ )
#elif defined(USE_LIGHT_MEM_DEBUG)
extern const char *g_pszModule;
#define MemAlloc_AllocAligned( s, a ) MemAlloc_AllocAlignedFileLine( s, a, g_pszModule, 0 )
#else
#define MemAlloc_AllocAligned( s, a ) MemAlloc_AllocAlignedUnattributed( s, a )
#endif
inline void *MemAlloc_ReallocAligned( void *ptr, size_t size, size_t align )
{
if ( !ValueIsPowerOfTwo( align ) )
return NULL;
// Don't change alignment between allocation + reallocation.
if ( ( (size_t)ptr & ( align - 1 ) ) != 0 )
return NULL;
#ifdef MEMALLOC_SUPPORTS_ALIGNED_ALLOCATIONS
return g_pMemAlloc->ReallocAlign( ptr, size, align );
#else
if ( !ptr )
return MemAlloc_AllocAligned( size, align );
void *pAlloc, *pResult;
// Figure out the actual allocation point
pAlloc = ptr;
pAlloc = (void *)(((size_t)pAlloc & ~( sizeof(void *) - 1 ) ) - sizeof(void *));
pAlloc = *( (void **)pAlloc );
// See if we have enough space
size_t nOffset = (size_t)ptr - (size_t)pAlloc;
size_t nOldSize = g_pMemAlloc->GetSize( pAlloc );
if ( nOldSize >= size + nOffset )
return ptr;
pResult = MemAlloc_AllocAligned( size, align );
memcpy( pResult, ptr, nOldSize - nOffset );
g_pMemAlloc->Free( pAlloc );
return pResult;
#endif
}
inline void MemAlloc_FreeAligned( void *pMemBlock )
{
#ifdef MEMALLOC_SUPPORTS_ALIGNED_ALLOCATIONS
g_pMemAlloc->Free( pMemBlock );
#else
void *pAlloc;
if ( pMemBlock == NULL )
return;
pAlloc = pMemBlock;
// pAlloc points to the pointer to starting of the memory block
pAlloc = (void *)(((size_t)pAlloc & ~( sizeof(void *) - 1 ) ) - sizeof(void *));
// pAlloc is the pointer to the start of memory block
pAlloc = *( (void **)pAlloc );
g_pMemAlloc->Free( pAlloc );
#endif
}
inline void MemAlloc_FreeAligned( void *pMemBlock, const char *pszFile, int nLine )
{
#ifdef MEMALLOC_SUPPORTS_ALIGNED_ALLOCATIONS
g_pMemAlloc->Free( pMemBlock, pszFile, nLine );
#else
void *pAlloc;
if ( pMemBlock == NULL )
return;
pAlloc = pMemBlock;
// pAlloc points to the pointer to starting of the memory block
pAlloc = (void *)(((size_t)pAlloc & ~( sizeof(void *) - 1 ) ) - sizeof(void *));
// pAlloc is the pointer to the start of memory block
pAlloc = *( (void **)pAlloc );
g_pMemAlloc->Free( pAlloc, pszFile, nLine );
#endif
}
inline size_t MemAlloc_GetSizeAligned( void *pMemBlock )
{
#ifdef MEMALLOC_SUPPORTS_ALIGNED_ALLOCATIONS
return g_pMemAlloc->GetSize( pMemBlock );
#else
void *pAlloc;
if ( pMemBlock == NULL )
return 0;
pAlloc = pMemBlock;
// pAlloc points to the pointer to starting of the memory block
pAlloc = (void *)(((size_t)pAlloc & ~( sizeof(void *) - 1 ) ) - sizeof(void *));
// pAlloc is the pointer to the start of memory block
pAlloc = *((void **)pAlloc );
return g_pMemAlloc->GetSize( pAlloc ) - ( (::byte *)pMemBlock - (::byte *)pAlloc );
#endif
}
struct aligned_tmp_t
{
// empty base class
};
// template here to allow adding alignment at levels of hierarchy that aren't the base
template< int bytesAlignment = 16, class T = aligned_tmp_t >
class CAlignedNewDelete : public T
{
public:
void *operator new( size_t nSize )
{
return MemAlloc_AllocAligned( nSize, bytesAlignment );
}
void* operator new( size_t nSize, int nBlockUse, const char *pFileName, int nLine )
{
return MemAlloc_AllocAlignedFileLine( nSize, bytesAlignment, pFileName, nLine );
}
void operator delete(void *pData)
{
if ( pData )
{
MemAlloc_FreeAligned( pData );
}
}
void operator delete( void* pData, int nBlockUse, const char *pFileName, int nLine )
{
if ( pData )
{
MemAlloc_FreeAligned( pData, pFileName, nLine );
}
}
};
//-----------------------------------------------------------------------------
#if (defined(_DEBUG) || defined(USE_MEM_DEBUG))
#define MEM_ALLOC_CREDIT_(tag) CMemAllocAttributeAlloction memAllocAttributeAlloction( tag, __LINE__ )
#define MemAlloc_PushAllocDbgInfo( pszFile, line ) g_pMemAlloc->PushAllocDbgInfo( pszFile, line )
#define MemAlloc_PopAllocDbgInfo() g_pMemAlloc->PopAllocDbgInfo()
#define MemAlloc_RegisterAllocation( pFileName, nLine, nLogicalSize, nActualSize, nTime ) g_pMemAlloc->RegisterAllocation( pFileName, nLine, nLogicalSize, nActualSize, nTime )
#define MemAlloc_RegisterDeallocation( pFileName, nLine, nLogicalSize, nActualSize, nTime ) g_pMemAlloc->RegisterDeallocation( pFileName, nLine, nLogicalSize, nActualSize, nTime )
#else
#define MEM_ALLOC_CREDIT_(tag) ((void)0)
#define MemAlloc_PushAllocDbgInfo( pszFile, line ) ((void)0)
#define MemAlloc_PopAllocDbgInfo() ((void)0)
#define MemAlloc_RegisterAllocation( pFileName, nLine, nLogicalSize, nActualSize, nTime ) ((void)0)
#define MemAlloc_RegisterDeallocation( pFileName, nLine, nLogicalSize, nActualSize, nTime ) ((void)0)
#endif
//-----------------------------------------------------------------------------
class CMemAllocAttributeAlloction
{
public:
CMemAllocAttributeAlloction( const char *pszFile, int line )
{
MemAlloc_PushAllocDbgInfo( pszFile, line );
}
~CMemAllocAttributeAlloction()
{
MemAlloc_PopAllocDbgInfo();
}
};
#define MEM_ALLOC_CREDIT() MEM_ALLOC_CREDIT_(__FILE__)
//-----------------------------------------------------------------------------
#if defined(MSVC) && ( defined(_DEBUG) || defined(USE_MEM_DEBUG) )
#pragma warning(disable:4290)
#pragma warning(push)
#include <typeinfo>
// MEM_DEBUG_CLASSNAME is opt-in.
// Note: typeid().name() is not threadsafe, so if the project needs to access it in multiple threads
// simultaneously, it'll need a mutex.
#if defined(_CPPRTTI) && defined(MEM_DEBUG_CLASSNAME)
template <typename T> const char *MemAllocClassName( T *p )
{
static const char *pszName = typeid(*p).name(); // @TODO: support having debug heap ignore certain allocations, and ignore memory allocated here [5/7/2009 tom]
return pszName;
}
#define MEM_ALLOC_CREDIT_CLASS() MEM_ALLOC_CREDIT_( MemAllocClassName( this ) )
#define MEM_ALLOC_CLASSNAME(type) (typeid((type*)(0)).name())
#else
#define MEM_ALLOC_CREDIT_CLASS() MEM_ALLOC_CREDIT_( __FILE__ )
#define MEM_ALLOC_CLASSNAME(type) (__FILE__)
#endif
// MEM_ALLOC_CREDIT_FUNCTION is used when no this pointer is available ( inside 'new' overloads, for example )
#ifdef _MSC_VER
#define MEM_ALLOC_CREDIT_FUNCTION() MEM_ALLOC_CREDIT_( __FUNCTION__ )
#else
#define MEM_ALLOC_CREDIT_FUNCTION() (__FILE__)
#endif
#pragma warning(pop)
#else
#define MEM_ALLOC_CREDIT_CLASS()
#define MEM_ALLOC_CLASSNAME(type) NULL
#define MEM_ALLOC_CREDIT_FUNCTION()
#endif
//-----------------------------------------------------------------------------
#if (defined(_DEBUG) || defined(USE_MEM_DEBUG))
struct MemAllocFileLine_t
{
const char *pszFile;
int line;
};
#define MEMALLOC_DEFINE_EXTERNAL_TRACKING( tag ) \
static CUtlMap<void *, MemAllocFileLine_t, int> s_##tag##Allocs( DefLessFunc( void *) ); \
CUtlMap<void *, MemAllocFileLine_t, int> * g_p##tag##Allocs = &s_##tag##Allocs; \
static CThreadFastMutex s_##tag##AllocsMutex; \
CThreadFastMutex * g_p##tag##AllocsMutex = &s_##tag##AllocsMutex; \
const char * g_psz##tag##Alloc = strcpy( (char *)MemAlloc_Alloc( strlen( #tag "Alloc" ) + 1, "intentional leak", 0 ), #tag "Alloc" );
#define MEMALLOC_DECLARE_EXTERNAL_TRACKING( tag ) \
extern CUtlMap<void *, MemAllocFileLine_t, int> * g_p##tag##Allocs; \
extern CThreadFastMutex *g_p##tag##AllocsMutex; \
extern const char * g_psz##tag##Alloc;
#define MemAlloc_RegisterExternalAllocation( tag, p, size ) \
if ( !p ) \
; \
else \
{ \
AUTO_LOCK_FM( *g_p##tag##AllocsMutex ); \
MemAllocFileLine_t fileLine = { g_psz##tag##Alloc, 0 }; \
g_pMemAlloc->GetActualDbgInfo( fileLine.pszFile, fileLine.line ); \
if ( fileLine.pszFile != g_psz##tag##Alloc ) \
{ \
g_p##tag##Allocs->Insert( p, fileLine ); \
} \
\
MemAlloc_RegisterAllocation( fileLine.pszFile, fileLine.line, size, size, 0); \
}
#define MemAlloc_RegisterExternalDeallocation( tag, p, size ) \
if ( !p ) \
; \
else \
{ \
AUTO_LOCK_FM( *g_p##tag##AllocsMutex ); \
MemAllocFileLine_t fileLine = { g_psz##tag##Alloc, 0 }; \
CUtlMap<void *, MemAllocFileLine_t, int>::IndexType_t iRecordedFileLine = g_p##tag##Allocs->Find( p ); \
if ( iRecordedFileLine != g_p##tag##Allocs->InvalidIndex() ) \
{ \
fileLine = (*g_p##tag##Allocs)[iRecordedFileLine]; \
g_p##tag##Allocs->RemoveAt( iRecordedFileLine ); \
} \
\
MemAlloc_RegisterDeallocation( fileLine.pszFile, fileLine.line, size, size, 0); \
}
#else
#define MEMALLOC_DEFINE_EXTERNAL_TRACKING( tag )
#define MEMALLOC_DECLARE_EXTERNAL_TRACKING( tag )
#define MemAlloc_RegisterExternalAllocation( tag, p, size ) ((void)0)
#define MemAlloc_RegisterExternalDeallocation( tag, p, size ) ((void)0)
#endif
//-----------------------------------------------------------------------------
#endif // !STEAM && !NO_MALLOC_OVERRIDE
//-----------------------------------------------------------------------------
#if !defined(STEAM) && defined(NO_MALLOC_OVERRIDE)
#include <malloc.h>
#define MEM_ALLOC_CREDIT_(tag) ((void)0)
#define MEM_ALLOC_CREDIT() MEM_ALLOC_CREDIT_(__FILE__)
#define MEM_ALLOC_CREDIT_CLASS()
#define MEM_ALLOC_CLASSNAME(type) NULL
#define MemAlloc_PushAllocDbgInfo( pszFile, line )
#define MemAlloc_PopAllocDbgInfo()
#define MemAlloc_RegisterAllocation( a,b,c,d,e ) ((void)0)
#define MemAlloc_RegisterDeallocation( a,b,c,d,e ) ((void)0)
#define MEMALLOC_DEFINE_EXTERNAL_TRACKING( tag )
#define MemAlloc_RegisterExternalAllocation( tag, p, size ) ((void)0)
#define MemAlloc_RegisterExternalDeallocation( tag, p, size ) ((void)0)
inline void *MemAlloc_AllocAligned( size_t size, size_t align )
{
return (void *)_aligned_malloc( size, align );
}
inline void *MemAlloc_AllocAligned( size_t size, size_t align, const char *pszFile, int nLine )
{
pszFile = pszFile;
nLine = nLine;
return (void *)_aligned_malloc( size, align );
}
inline void MemAlloc_FreeAligned( void *pMemBlock )
{
_aligned_free( pMemBlock );
}
inline void MemAlloc_FreeAligned( void *pMemBlock, const char *pszFile, int nLine )
{
pszFile = pszFile;
nLine = nLine;
_aligned_free( pMemBlock );
}
#endif // !STEAM && NO_MALLOC_OVERRIDE
//-----------------------------------------------------------------------------
// linux memory tracking via hooks.
#if defined( POSIX ) && !defined( _PS3 )
PLATFORM_INTERFACE void MemoryLogMessage( char const *s ); // throw a message into the memory log
PLATFORM_INTERFACE void EnableMemoryLogging( bool bOnOff );
PLATFORM_INTERFACE void DumpMemoryLog( int nThresh );
PLATFORM_INTERFACE void DumpMemorySummary( void );
PLATFORM_INTERFACE void SetMemoryMark( void );
PLATFORM_INTERFACE void DumpChangedMemory( int nThresh );
// ApproximateProcessMemoryUsage returns the approximate memory footprint of this process.
PLATFORM_INTERFACE size_t ApproximateProcessMemoryUsage( void );
#else
inline void MemoryLogMessage( char const * )
{
}
inline void EnableMemoryLogging( bool )
{
}
inline void DumpMemoryLog( int )
{
}
inline void DumpMemorySummary( void )
{
}
inline void SetMemoryMark( void )
{
}
inline void DumpChangedMemory( int )
{
}
inline size_t ApproximateProcessMemoryUsage( void )
{
return 0;
}
#endif
#endif /* TIER0_MEMALLOC_H */

25
external/vpc/public/tier0/memdbgoff.h vendored Normal file
View File

@@ -0,0 +1,25 @@
//========= Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose: This header, which must be the final line of a .h file,
// causes all crt methods to stop using debugging versions of the memory allocators.
// NOTE: Use memdbgon.h to re-enable memory debugging.
//
// $NoKeywords: $
//=============================================================================//
#ifdef MEM_OVERRIDE_ON
#undef malloc
#undef realloc
#undef calloc
#undef free
#undef _expand
#undef _msize
#undef new
#undef _aligned_malloc
#undef _aligned_free
#undef _malloc_dbg
#undef MEM_OVERRIDE_ON
#endif

281
external/vpc/public/tier0/memdbgon.h vendored Normal file
View File

@@ -0,0 +1,281 @@
//========= Copyright 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose: This header, which must be the final include in a .cpp (or .h) file,
// causes all crt methods to use debugging versions of the memory allocators.
// NOTE: Use memdbgoff.h to disable memory debugging.
//
// $NoKeywords: $
//=============================================================================//
// SPECIAL NOTE! This file must *not* use include guards; we need to be able
// to include this potentially multiple times (since we can deactivate debugging
// by including memdbgoff.h)
#if !defined(STEAM) && !defined(NO_MALLOC_OVERRIDE)
// SPECIAL NOTE #2: This must be the final include in a .cpp or .h file!!!
#if defined(_DEBUG) && !defined(USE_MEM_DEBUG) && !defined( _PS3 )
#define USE_MEM_DEBUG 1
#endif
// If debug build or ndebug and not already included MS custom alloc files, or already included this file
#if (defined(_DEBUG) || !defined(_INC_CRTDBG)) || defined(MEMDBGON_H)
#include "tier0/basetypes.h"
#include "tier0/valve_off.h"
#ifdef COMPILER_MSVC
#include <tchar.h>
#else
#include <wchar.h>
#endif
#include <string.h>
#ifndef _PS3
#include <malloc.h>
#endif
#include "tier0/valve_on.h"
#include "commonmacros.h"
#include "memalloc.h"
#ifdef _WIN32
#ifndef MEMALLOC_REGION
#define MEMALLOC_REGION 0
#endif
#else
#undef MEMALLOC_REGION
#endif
#if defined(USE_MEM_DEBUG)
#if defined( POSIX ) || defined( _PS3 )
#define _NORMAL_BLOCK 1
#include "tier0/valve_off.h"
#include <cstddef>
#include <new>
#include <sys/types.h>
#if !defined( DID_THE_OPERATOR_NEW )
#define DID_THE_OPERATOR_NEW
// posix doesn't have a new of this form, so we impl our own
void* operator new( size_t nSize, int blah, const char *pFileName, int nLine );
void* operator new[]( size_t nSize, int blah, const char *pFileName, int nLine );
#endif
#else // defined(POSIX)
// Include crtdbg.h and make sure _DEBUG is set to 1.
#if !defined(_DEBUG)
#define _DEBUG 1
#include <crtdbg.h>
#undef _DEBUG
#else
#include <crtdbg.h>
#endif // !defined(_DEBUG)
#endif // defined(POSIX)
#endif
#include "tier0/memdbgoff.h"
// --------------------------------------------------------
// Debug/non-debug agnostic elements
#define MEM_OVERRIDE_ON 1
#undef malloc
#undef realloc
#undef calloc
#undef _expand
#undef free
#undef _msize
#undef _aligned_malloc
#undef _aligned_free
#ifndef MEMDBGON_H
inline void *MemAlloc_InlineCallocMemset( void *pMem, size_t nCount, size_t nElementSize)
{
memset(pMem, 0, nElementSize * nCount);
return pMem;
}
#endif
#define calloc(c, s) MemAlloc_InlineCallocMemset(malloc(c*s), c, s)
#ifndef USE_LIGHT_MEM_DEBUG
#define free(p) g_pMemAlloc->Free( p )
#define _aligned_free( p ) MemAlloc_FreeAligned( p )
#else
extern const char *g_pszModule;
#define free(p) g_pMemAlloc->Free( p, g_pszModule, 0 )
#define _aligned_free( p ) MemAlloc_FreeAligned( p, g_pszModule, 0 )
#endif
#define _msize(p) g_pMemAlloc->GetSize( p )
#define _expand(p, s) _expand_NoLongerSupported(p, s)
// --------------------------------------------------------
// Debug path
#if defined(USE_MEM_DEBUG)
#define malloc(s) MemAlloc_Alloc( s, __FILE__, __LINE__)
#define realloc(p, s) g_pMemAlloc->Realloc( p, s, __FILE__, __LINE__ )
#define _aligned_malloc( s, a ) MemAlloc_AllocAlignedFileLine( s, a, __FILE__, __LINE__ )
#define _malloc_dbg(s, t, f, l) WHYCALLINGTHISDIRECTLY(s)
#undef new
#if defined( _PS3 )
#ifndef PS3_OPERATOR_NEW_WRAPPER_DEFINED
#define PS3_OPERATOR_NEW_WRAPPER_DEFINED
inline void* operator new( size_t nSize, int blah, const char *pFileName, int nLine ) { return g_pMemAlloc->IndirectAlloc( nSize, pFileName, nLine ); }
inline void* operator new[]( size_t nSize, int blah, const char *pFileName, int nLine ) { return g_pMemAlloc->IndirectAlloc( nSize, pFileName, nLine ); }
#endif
#define new new( 1, __FILE__, __LINE__ )
#elif !defined( GNUC )
#if defined(__AFX_H__) && defined(DEBUG_NEW)
#define new DEBUG_NEW
#else
#define MEMALL_DEBUG_NEW new(_NORMAL_BLOCK, __FILE__, __LINE__)
#define new MEMALL_DEBUG_NEW
#endif
#endif
#undef _strdup
#undef strdup
#undef _wcsdup
#undef wcsdup
#define _strdup(s) MemAlloc_StrDup(s, __FILE__, __LINE__)
#define strdup(s) MemAlloc_StrDup(s, __FILE__, __LINE__)
#define _wcsdup(s) MemAlloc_WcStrDup(s, __FILE__, __LINE__)
#define wcsdup(s) MemAlloc_WcStrDup(s, __FILE__, __LINE__)
// Make sure we don't define strdup twice
#if !defined(MEMDBGON_H)
inline char *MemAlloc_StrDup(const char *pString, const char *pFileName, unsigned nLine)
{
char *pMemory;
if (!pString)
return NULL;
size_t len = strlen(pString) + 1;
if ((pMemory = (char *)MemAlloc_Alloc(len, pFileName, nLine)) != NULL)
{
return strcpy( pMemory, pString );
}
return NULL;
}
inline wchar_t *MemAlloc_WcStrDup(const wchar_t *pString, const char *pFileName, unsigned nLine)
{
wchar_t *pMemory;
if (!pString)
return NULL;
size_t len = (wcslen(pString) + 1);
if ((pMemory = (wchar_t *)MemAlloc_Alloc(len * sizeof(wchar_t), pFileName, nLine)) != NULL)
{
return wcscpy( pMemory, pString );
}
return NULL;
}
#endif // DBMEM_DEFINED_STRDUP
#else
// --------------------------------------------------------
// Release path
#ifndef USE_LIGHT_MEM_DEBUG
#define malloc(s) MemAlloc_Alloc( s )
#define realloc(p, s) g_pMemAlloc->Realloc( p, s )
#define _aligned_malloc( s, a ) MemAlloc_AllocAligned( s, a )
#else
#define malloc(s) MemAlloc_Alloc( s, g_pszModule, 0 )
#define realloc(p, s) g_pMemAlloc->Realloc( p, s, g_pszModule, 0 )
#define _aligned_malloc( s, a ) MemAlloc_AllocAlignedFileLine( s, a, g_pszModule, 0 )
#endif
#ifndef _malloc_dbg
#define _malloc_dbg(s, t, f, l) WHYCALLINGTHISDIRECTLY(s)
#endif
#undef new
#if defined( _PS3 ) && !defined( _CERT )
#ifndef PS3_OPERATOR_NEW_WRAPPER_DEFINED
#define PS3_OPERATOR_NEW_WRAPPER_DEFINED
inline void* operator new( size_t nSize, int blah, const char *pFileName, int nLine ) { return g_pMemAlloc->IndirectAlloc( nSize, pFileName, nLine ); }
inline void* operator new[]( size_t nSize, int blah, const char *pFileName, int nLine ) { return g_pMemAlloc->IndirectAlloc( nSize, pFileName, nLine ); }
#endif
#define new new( 1, __FILE__, __LINE__ )
#endif
#undef _strdup
#undef strdup
#undef _wcsdup
#undef wcsdup
#define _strdup(s) MemAlloc_StrDup(s)
#define strdup(s) MemAlloc_StrDup(s)
#define _wcsdup(s) MemAlloc_WcStrDup(s)
#define wcsdup(s) MemAlloc_WcStrDup(s)
// Make sure we don't define strdup twice
#if !defined(MEMDBGON_H)
inline char *MemAlloc_StrDup(const char *pString)
{
char *pMemory;
if (!pString)
return NULL;
size_t len = strlen(pString) + 1;
if ((pMemory = (char *)malloc(len)) != NULL)
{
return strcpy( pMemory, pString );
}
return NULL;
}
inline wchar_t *MemAlloc_WcStrDup(const wchar_t *pString)
{
wchar_t *pMemory;
if (!pString)
return NULL;
size_t len = (wcslen(pString) + 1);
if ((pMemory = (wchar_t *)malloc(len * sizeof(wchar_t))) != NULL)
{
return wcscpy( pMemory, pString );
}
return NULL;
}
#endif // DBMEM_DEFINED_STRDUP
#endif // USE_MEM_DEBUG
#define MEMDBGON_H // Defined here so can be used above
#else
#if defined(USE_MEM_DEBUG)
#ifndef _STATIC_LINKED
#pragma message ("Note: file includes crtdbg.h directly, therefore will cannot use memdbgon.h in non-debug build")
#else
#error "Error: file includes crtdbg.h directly, therefore will cannot use memdbgon.h in non-debug build. Not recoverable in static build"
#endif
#endif
#endif // _INC_CRTDBG
#endif // !STEAM && !NO_MALLOC_OVERRIDE

46
external/vpc/public/tier0/memvirt.h vendored Normal file
View File

@@ -0,0 +1,46 @@
//========== Copyright (C) Valve Corporation, All rights reserved. ==========//
//
// Purpose: CVirtualMemoryManager interface
//
//===========================================================================//
#ifndef MEM_VIRT_H
#define MEM_VIRT_H
#ifdef _WIN32
#pragma once
#endif
#define VMM_KB ( 1024 )
#define VMM_MB ( 1024 * VMM_KB )
#ifdef _PS3
// Total virtual address space reserved by CVirtualMemoryManager on startup:
#define VMM_VIRTUAL_SIZE ( 512 * VMM_MB )
#define VMM_PAGE_SIZE ( 64 * VMM_KB )
#endif
// Allocate virtual sections via IMemAlloc::AllocateVirtualMemorySection
abstract_class IVirtualMemorySection
{
public:
// Information about memory section
virtual void * GetBaseAddress() = 0;
virtual size_t GetPageSize() = 0;
virtual size_t GetTotalSize() = 0;
// Functions to manage physical memory mapped to virtual memory
virtual bool CommitPages( void *pvBase, size_t numBytes ) = 0;
virtual void DecommitPages( void *pvBase, size_t numBytes ) = 0;
// Release the physical memory and associated virtual address space
virtual void Release() = 0;
};
// Get the IVirtualMemorySection associated with a given memory address (if any):
extern IVirtualMemorySection *GetMemorySectionForAddress( void *pAddress );
#endif // MEM_VIRT_H

82
external/vpc/public/tier0/minidump.h vendored Normal file
View File

@@ -0,0 +1,82 @@
//========= Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================//
#ifndef MINIDUMP_H
#define MINIDUMP_H
#ifdef _WIN32
#pragma once
#endif
#include "tier0/platform.h"
// writes out a minidump of the current stack trace with a unique filename
PLATFORM_INTERFACE void WriteMiniDump();
typedef void (*FnWMain)( int , tchar *[] );
#ifdef IS_WINDOWS_PC
// calls the passed in function pointer and catches any exceptions/crashes thrown by it, and writes a minidump
// use from wmain() to protect the whole program
PLATFORM_INTERFACE void CatchAndWriteMiniDump( FnWMain pfn, int argc, tchar *argv[] );
// The ExceptionInfo_t struct is a typeless data struct
// which is OS-dependent and should never be used by external code.
// Just pass it back into MinidumpSetUnhandledExceptionFunction
struct ExceptionInfo_t;
// Replaces the current function pointer with the one passed in.
// Returns the previously-set function.
// The function is called internally by WriteMiniDump() and CatchAndWriteMiniDump()
// The default is the built-in function that uses DbgHlp.dll's MiniDumpWriteDump function
typedef void (*FnMiniDump)( unsigned int uStructuredExceptionCode, ExceptionInfo_t * pExceptionInfo );
PLATFORM_INTERFACE FnMiniDump SetMiniDumpFunction( FnMiniDump pfn );
// Use this to write a minidump explicitly.
// Some of the tools choose to catch the minidump themselves instead of using CatchAndWriteMinidump
// so they can show their own dialog.
//
// ptchMinidumpFileNameBuffer if not-NULL should be a writable tchar buffer of length at
// least _MAX_PATH and on return will contain the name of the minidump file written.
// If ptchMinidumpFileNameBuffer is NULL the name of the minidump file written will not
// be available after the function returns.
//
// NOTE: Matches windows.h
enum MinidumpType_t
{
MINIDUMP_Normal = 0x00000000,
MINIDUMP_WithDataSegs = 0x00000001,
MINIDUMP_WithFullMemory = 0x00000002,
MINIDUMP_WithHandleData = 0x00000004,
MINIDUMP_FilterMemory = 0x00000008,
MINIDUMP_ScanMemory = 0x00000010,
MINIDUMP_WithUnloadedModules = 0x00000020,
MINIDUMP_WithIndirectlyReferencedMemory = 0x00000040,
MINIDUMP_FilterModulePaths = 0x00000080,
MINIDUMP_WithProcessThreadData = 0x00000100,
MINIDUMP_WithPrivateReadWriteMemory = 0x00000200,
MINIDUMP_WithoutOptionalData = 0x00000400,
MINIDUMP_WithFullMemoryInfo = 0x00000800,
MINIDUMP_WithThreadInfo = 0x00001000,
MINIDUMP_WithCodeSegs = 0x00002000
};
PLATFORM_INTERFACE bool WriteMiniDumpUsingExceptionInfo(
unsigned int uStructuredExceptionCode,
ExceptionInfo_t *pExceptionInfo,
uint32 nMinidumpTypeFlags, // OR-ed together MinidumpType_t flags
tchar *ptchMinidumpFileNameBuffer = NULL
);
PLATFORM_INTERFACE void MinidumpSetUnhandledExceptionFunction( FnMiniDump pfn );
#endif
#endif // MINIDUMP_H

View File

@@ -0,0 +1,322 @@
//========= Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//
//=============================================================================//
#ifndef P4PERFORMANCECOUNTERS_H
#define P4PERFORMANCECOUNTERS_H
#pragma once
// Pentium 4 support
/*
http://developer.intel.com/design/Pentium4/documentation.htm
IA-32 Intel Architecture Software Developer's Manual Volume 1: Basic Architecture
IA-32 Intel Architecture Software Developer's Manual Volume 2A: Instruction Set Reference, A-M
IA-32 Intel Architecture Software Developer's Manual Volume 2B: Instruction Set Reference, N-Z
IA-32 Intel Architecture Software Developer's Manual Volume 3: System Programming Guide
From Mikael Pettersson's perfctr:
http://user.it.uu.se/~mikpe/linux/perfctr/
* Known quirks:
- OVF_PMI+FORCE_OVF counters must have an ireset value of -1.
This allows the regular overflow check to also handle FORCE_OVF
counters. Not having this restriction would lead to MAJOR
complications in the driver's "detect overflow counters" code.
There is no loss of functionality since the ireset value doesn't
affect the counter's PMI rate for FORCE_OVF counters.
- In experiments with FORCE_OVF counters, and regular OVF_PMI
counters with small ireset values between -8 and -1, it appears
that the faulting instruction is subjected to a new PMI before
it can complete, ad infinitum. This occurs even though the driver
clears the CCCR (and in testing also the ESCR) and invokes a
user-space signal handler before restoring the CCCR and resuming
the instruction.
*/
#define NCOUNTERS 18
// The 18 counters
enum Counters
{
MSR_BPU_COUNTER0,
MSR_BPU_COUNTER1,
MSR_BPU_COUNTER2,
MSR_BPU_COUNTER3,
MSR_MS_COUNTER0,
MSR_MS_COUNTER1,
MSR_MS_COUNTER2,
MSR_MS_COUNTER3,
MSR_FLAME_COUNTER0,
MSR_FLAME_COUNTER1,
MSR_FLAME_COUNTER2,
MSR_FLAME_COUNTER3,
MSR_IQ_COUNTER0,
MSR_IQ_COUNTER1,
MSR_IQ_COUNTER2,
MSR_IQ_COUNTER3,
MSR_IQ_COUNTER4,
MSR_IQ_COUNTER5
};
// register base for counters
#define MSR_COUNTER_BASE 0x300
// register base for CCCR register
#define MSR_CCCR_BASE 0x360
#pragma pack(push, 1)
// access to these bits is through the methods
typedef union ESCR
{
struct
{
uint64 Reserved0_1 : 2; //
uint64 USR : 1; //
uint64 OS : 1; //
uint64 TagEnable : 1; //
uint64 TagValue : 4; //
uint64 EventMask : 16; // from event select
uint64 ESCREventSelect : 6; // 31:25 class of event
uint64 Reserved31 : 1; //
uint64 Reserved32_63 : 32; //
};
uint64 flat;
} ESCR;
typedef union CCCR
{
struct
{
uint64 Reserved0_11 : 12;// 0 -11
uint64 Enable : 1; // 12
uint64 CCCRSelect : 3; // 13-15
uint64 Reserved16_17 : 2; // 16 17
uint64 Compare : 1; // 18
uint64 Complement : 1; // 19
uint64 Threshold : 4; // 20-23
uint64 Edge : 1; // 24
uint64 FORCE_OVF : 1; // 25
uint64 OVF_PMI : 1; // 26
uint64 Reserved27_29 : 3; // 27-29
uint64 Cascade : 1; // 30
uint64 OVF : 1; // 31
uint64 Reserved32_63 : 32; //
};
uint64 flat;
} CCCR;
#pragma pack(pop)
extern const unsigned short cccr_escr_map[NCOUNTERS][8];
enum P4TagState
{
TagDisable, //
TagEnable, //
};
enum P4ForceOverflow
{
ForceOverflowDisable,
ForceOverflowEnable,
};
enum P4OverflowInterrupt
{
OverflowInterruptDisable,
OverflowInterruptEnable,
};
// Turn off the no return value warning in ReadCounter.
#pragma warning( disable : 4035 )
class P4BaseEvent
{
int m_counter;
protected:
void SetCounter(int counter)
{
m_counter = counter;
cccrPort = MSR_CCCR_BASE + m_counter;
counterPort = MSR_COUNTER_BASE + m_counter;
escrPort = cccr_escr_map[m_counter][cccr.CCCRSelect];
}
public:
unsigned short m_eventMask;
const tchar *description;
PME *pme;
ESCR escr;
CCCR cccr;
int counterPort;
int cccrPort;
int escrPort;
P4BaseEvent()
{
pme = PME::Instance();
m_eventMask = 0;
description = _T("");
escr.flat = 0;
cccr.flat = 0;
cccr.Reserved16_17 = 3; // must be set
escrPort = 0;
m_counter = -1;
}
void StartCounter()
{
cccr.Enable = 1;
pme->WriteMSR( cccrPort, cccr.flat );
}
void StopCounter()
{
cccr.Enable = 0;
pme->WriteMSR( cccrPort, cccr.flat );
}
void ClearCounter()
{
pme->WriteMSR( counterPort, 0ui64 ); // clear
}
void WriteCounter( int64 value )
{
pme->WriteMSR( counterPort, value ); // clear
}
int64 ReadCounter()
{
#if PME_DEBUG
if ( escr.USR == 0 && escr.OS == 0 )
return -1; // no area to collect, use SetCaptureMode
if ( escr.EventMask == 0 )
return -2; // no event mask set
if ( m_counter == -1 )
return -3; // counter not legal
#endif
// ReadMSR should work here too, but RDPMC should be faster
int64 value = 0;
pme->ReadMSR( counterPort, &value );
return value;
#if 0
// we need to copy this into a temp for some reason
int temp = m_counter;
_asm
{
mov ecx, temp
RDPMC
}
#endif
}
void SetCaptureMode( PrivilegeCapture priv )
{
switch ( priv )
{
case OS_Only:
{
escr.USR = 0;
escr.OS = 1;
break;
}
case USR_Only:
{
escr.USR = 1;
escr.OS = 0;
break;
}
case OS_and_USR:
{
escr.USR = 1;
escr.OS = 1;
break;
}
}
escr.EventMask = m_eventMask;
pme->WriteMSR( escrPort, escr.flat );
}
void SetTagging( P4TagState tagEnable, uint8 tagValue )
{
escr.TagEnable = tagEnable;
escr.TagValue = tagValue;
pme->WriteMSR( escrPort, escr.flat );
}
void SetFiltering( CompareState compareEnable, CompareMethod compareMethod, uint8 threshold, EdgeState edgeEnable )
{
cccr.Compare = compareEnable;
cccr.Complement = compareMethod;
cccr.Threshold = threshold;
cccr.Edge = edgeEnable;
pme->WriteMSR( cccrPort, cccr.flat );
}
void SetOverflowEnables( P4ForceOverflow overflowEnable, P4OverflowInterrupt overflowInterruptEnable )
{
cccr.FORCE_OVF = overflowEnable;
cccr.OVF_PMI = overflowInterruptEnable;
pme->WriteMSR( cccrPort, cccr.flat );
}
void SetOverflow()
{
cccr.OVF = 1;
pme->WriteMSR( cccrPort, cccr.flat );
}
void ClearOverflow()
{
cccr.OVF = 0;
pme->WriteMSR( cccrPort, cccr.flat );
}
bool isOverflow()
{
CCCR cccr_temp;
pme->ReadMSR( cccrPort, &cccr_temp.flat );
return cccr_temp.OVF;
}
void SetCascade()
{
cccr.Cascade = 1;
pme->WriteMSR( cccrPort, cccr.flat );
}
void ClearCascade()
{
cccr.Cascade = 0;
pme->WriteMSR( cccrPort, cccr.flat );
}
};
#pragma warning( default : 4035 )
#include "eventmasks.h"
#include "eventmodes.h"
#endif // P4PERFORMANCECOUNTERS_H

View File

@@ -0,0 +1,225 @@
//========= Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//
//=============================================================================//
#ifndef P5P6PERFORMANCECOUNTERS_H
#define P5P6PERFORMANCECOUNTERS_H
// defined for < Pentium 4
//---------------------------------------------------------------------------
// Format of the performance event IDs within this header file in case you
// wish to add any additional events that may not be present here.
//
// BITS 0-8 Unit Mask, Unsed on P5 processors
// BIT 9 Set if event can be set on counter 0
// BIT 10 Set if event can be set on counter 1
// BITS 11-15 Unused Set to zero
// BITS 16-23 Event Select ID, Only bits 16-21 used on P5 Family
// BITS 24-27 Unused set to zero
// BITS 28-32 Process family that the event belong to, as returned by
// the CPUID instruction.
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
// PENTIUM PERFORMANCE COUNTERS.
//---------------------------------------------------------------------------
#define P5_DTCRD 0x50000300 //Data Cache Reads
#define P5_DWRIT 0x50010300 //Data Cache Writes
#define P5_DTTLB 0x50020300 //Data TLB Miss
#define P5_DTRMS 0x50030300 //Data Read Misses
#define P5_DWRMS 0x50040300 //Data Write Miss
#define P5_WHLCL 0x50050300 //Write (Hit) to M- or E-state line
#define P5_DCLWB 0x50060300 //Data Cache Lines Written Back
#define P5_DCSNP 0x50070300 //External Snoops
#define P5_DCSHT 0x50080300 //Data Cache Snoop Hits
#define P5_MAIBP 0x50090300 //Memory Access in Both Pipes
#define P5_BANKS 0x500A0300 //Bank Conflicts
#define P5_MISAL 0x500B0300 //Misaligned Data Memory Reference
#define P5_COCRD 0x500C0300 //Code Cache Reads
#define P5_COTLB 0x500D0300 //Code TLB Misses
#define P5_COCMS 0x500E0300 //Code Cache Misses
#define P5_ANYSG 0x500F0300 //Any Segment Register Loaded
#define P5_BRANC 0x50120300 //Branches
#define P5_BTBHT 0x50130300 //BTB Hits
#define P5_TBRAN 0x50140300 //Taken Branch or BTB hit
#define P5_PFLSH 0x50150300 //Pipeline flushes
#define P5_INSTR 0x50160300 //Instructions Executed
#define P5_INSTV 0x50170300 //Instructions Executed in the V-Pipe (Pairing)
#define P5_CLOCL 0x50180300 //Bus active
#define P5_PSDWR 0x50190300 //Full write buffers
#define P5_PSWDR 0x501A0300 //Waiting for Data Memory Read
#define P5_NCLSW 0x501B0300 //Clocks stalled writing an E or M state line
#define P5_IORWC 0x501D0300 //I/O Read or Write Cycle
#define P5_NOCMR 0x501E0300 //Non-Cacheable Memory Reads
#define P5_PSLDA 0x501F0300 //Clocks stalled due to AGI
#define P5_FLOPS 0x50220300 //Floating Point Operations
#define P5_DBGR0 0x50230300 //Breakpoint match on DR0
#define P5_DBGR1 0x50240300 //Breakpoint match on DR1
#define P5_DBGR2 0x50250300 //Breakpoint match on DR2
#define P5_DBGR3 0x50260300 //Breakpoint match on DR3
#define P5_HWINT 0x50270300 //Hardware interrupts
#define P5_DTRWR 0x50280300 //Data reads or writes
#define P5_DTRWM 0x50290300 //Data read or write miss
#define P5_BOLAT 0x502A0100 //Bus ownership latency
#define P5_BOTFR 0x502A0200 //Bus ownership transfer
#define P5_MMXA1 0x502B0100 //MMX Instruction Executed in U-pipe
#define P5_MMXA2 0x502B0200 //MMX Instruction Executed in V-pipe
#define P5_MMXMS 0x502C0100 //Cache M state line sharing
#define P5_MMSLS 0x502C0200 //Cache line sharing
#define P5_MMXB1 0x502D0100 //EMMS Instructions Executed
#define P5_MMXB2 0x502D0200 //Transition from MMX to FP instructions
#define P5_NOCMW 0x502E0200 //Non-Cacheable Memory Writes
#define P5_MMXC1 0x502F0100 //Saturated MMX Instructions Executed
#define P5_MMXC2 0x502F0200 //Saturations Performed
#define P5_MMXHS 0x50300100 //Cycles Not in HALT State
#define P5_MMXD2 0x50310100 //MMX Data Read
#define P5_MMXFP 0x50320100 //Floating Point Stalls
#define P5_MMXTB 0x50320200 //Taken Branches
#define P5_MMXD0 0x50330100 //D1 Starvation and FIFO Empty
#define P5_MMXD1 0x50330200 //D1 Starvation and one instruction in FIFO
#define P5_MMXE1 0x50340100 //MMX Data Writes
#define P5_MMXE2 0x50340200 //MMX Data Write Misses
#define P5_MMXWB 0x50350100 //Pipeline flushes, wrong branch prediction
#define P5_MMXWJ 0x50350200 //Pipeline flushes, branch prediction WB-stage
#define P5_MMXF1 0x50360100 //Misaligned MMX Data Memory Reference
#define P5_MMXF2 0x50360200 //Pipeline Stalled Waiting for MMX data read
#define P5_MMXRI 0x50370100 //Returns Predicted Incorrectly
#define P5_MMXRP 0x50370200 //Returns Predicted
#define P5_MMXG1 0x50380100 //MMX Multiply Unit Interlock
#define P5_MMXG2 0x50380200 //MOVD/MOVQ store stall, previous operation
#define P5_MMXRT 0x50390100 //Returns
#define P5_MMXRO 0x50390200 //RSB Overflows
#define P5_MMXBF 0x503A0100 //BTB False entries
#define P5_MMXBM 0x503A0200 //BTB misprediction on a Not-Taken Branch
#define P5_PXDWR 0x503B0100 //stalled due MMX Full write buffers
#define P5_PXZWR 0x503B0200 //stalled on MMX write to E or M state line
#define P5_CLOCK 0x503F0300 //Special value to count clocks on P5
//---------------------------------------------------------------------------
// PENTIUM PRO / PENTIUM II PERFORMANCE COUNTERS.
//---------------------------------------------------------------------------
#define P6_STRBB 0x60030300 //Store Buffer Block
#define P6_STBDC 0x60040300 //Store Buffer Drain Cycles
#define P6_MISMM 0x60050300 //Misaligned Data Memory Reference
#define P6_SEGLD 0x60060300 //Segment register loads
#define P6_FPOPE 0x60100100 //FP Computational Op. (COUNTER 0 ONLY)
#define P6_FPEOA 0x60110200 //FP Microcode Exceptions (COUNTER 1 ONLY)
#define P6_FMULT 0x60120200 //Multiplies (COUNTER 1 ONLY)
#define P6_FPDIV 0x60130200 //Divides (COUNTER 1 ONLY)
#define P6_DBUSY 0x60140200 //Cycles Divider Busy (COUNTER 1 ONLY)
#define P6_L2STR 0x60210300 //L2 address strobes => address bus utilization
#define P6_L2BBS 0x60220300 //Cycles L2 Bus Busy
#define P6_L2BBT 0x60230300 //Cycles L2 Bus Busy transferring data to CPU
#define P6_L2ALO 0x60240300 //L2 Lines Allocated
#define P6_L2MAL 0x60250300 //L2 M-state Lines Allocated
#define P6_L2CEV 0x60260300 //L2 Lines Evicted
#define P6_L2MEV 0x60270300 //L2 M-state Lines Evicted
#define P6_L2MCF 0x60280301 //L2 Cache Instruction Fetch Misses
#define P6_L2FET 0x6028030F //L2 Cache Instruction Fetches
#define P6_L2DRM 0x60290301 //L2 Cache Read Misses
#define P6_L2DMR 0x6029030F //L2 Cache Reads
#define P6_L2DWM 0x602A0301 //L2 Cache Write Misses
#define P6_L2DMW 0x602A030F //L2 Cache Writes
#define P6_L2CMS 0x602E0301 //L2 Cache Request Misses
#define P6_L2DCR 0x602E030F //L2 Cache Requests
#define P6_DMREF 0x60430300 //Data Memory References
#define P6_DCALO 0x6045030F //L1 Lines Allocated
#define P6_DCMAL 0x60460300 //L1 M-state Data Cache Lines Allocated
#define P6_DCMEV 0x60470300 //L1 M-state Data Cache Lines Evicted
#define P6_DCOUT 0x60480300 //L1 Misses outstanding
#define P6_TSMCD 0x60520300 //Time Self-Modifiying Code Detected
#define P6_BRWRA 0x60600300 //External Bus Cycles While Receive Active
#define P6_BRDCD 0x60600300 //External Bus Request Outstanding
#define P6_BRBNR 0x60610300 //External Bus Cycles While BNR Asserted
#define P6_BUSBS 0x60620300 //External Bus Cycles-DRDY Asserted (busy)
#define P6_BLOCK 0x60630300 //External Bus Cycles-LOCK signal asserted
#define P6_BBRCV 0x60640300 //External Bus Cycles-Processor receiving data
#define P6_BURST 0x60650300 //External Bus Burst Read Operations
#define P6_BRINV 0x60660300 //External Bus Read for Ownership Transaction
#define P6_BMLEV 0x60670300 //External Bus Writeback M-state Evicted
#define P6_BBIFT 0x60680300 //External Bus Burst Instruction Fetches
#define P6_BINVL 0x60690300 //External Bus Invalidate Transactions
#define P6_BPRBT 0x606A0300 //External Bus Partial Read Transactions
#define P6_BPTMO 0x606B0300 //External Bus Partial Memory Transactions
#define P6_BUSIO 0x606C0300 //External Bus I/O Bus Transactions
#define P6_BUSDF 0x606D0300 //External Bus Deferred Transactions
#define P6_BUSTB 0x606E0300 //External Bus Burst Transactions
#define P6_BMALL 0x606F0300 //External Bus Memory Transactions
#define P6_BSALL 0x60700300 //External Bus Transactions
#define P6_CLOCK 0x60790300 //Clockticks
#define P6_BRHIT 0x607A0300 //External Bus Cycles While HIT Asserted
#define P6_BRHTM 0x607B0300 //External Bus Cycles While HITM Asserted
#define P6_BRSST 0x607E0300 //External Bus Cycles While Snoop Stalled
#define P6_CMREF 0x60800300 //Total Instruction Fetches
#define P6_TOIFM 0x60810300 //Total Instruction Fetch Misses
#define P6_INTLB 0x60850300 //Instructions TLB Misses
#define P6_CSFET 0x60860300 //Cycles Instruction Fetch Stalled
#define P6_FTSTL 0x60870300 //Cycles Instruction Fetch stalled
#define P6_RSTAL 0x60A20300 //Resource Related Stalls
#define P6_MMXIE 0x60B00300 //MMX Instructions Executed
#define P6_SAISE 0x60B10300 //Saturated Arithmetic Instructions Executed
#define P6_PORT0 0x60B20301 //MMX micro-ops executed on Port 0
#define P6_PORT1 0x60B20302 //MMX micro-ops executed on Port 1
#define P6_PORT2 0x60B20304 //MMX micro-ops executed on Port 2
#define P6_PORT3 0x60B20308 //MMX micro-ops executed on Port 3
#define P6_MMXPA 0x60B30300 //MMX Packed Arithmetic
#define P6_MMXPM 0x60B30301 //MMX Packed Multiply
#define P6_MMXPS 0x60B30302 //MMX Packed Shift
#define P6_MMXPO 0x60B30304 //MMX Packed Operations
#define P6_MMXUO 0x60B30308 //MMX Unpacked Operations
#define P6_MMXPL 0x60B30310 //MMX Packed Logical
#define P6_INSTR 0x60C00300 //Instructions Retired
#define P6_FPOPS 0x60C10100 //FP operations retired (COUNTER 0 ONLY)
#define P6_UOPSR 0x60C20300 //Micro-Ops Retired
#define P6_BRRET 0x60C40300 //Branch Instructions Retired
#define P6_BRMSR 0x60C50300 //Branch Mispredictions Retired
#define P6_MASKD 0x60C60300 //Clocks while interrupts masked
#define P6_MSKPN 0x60C70300 //Clocks while interrupt is pending
#define P6_HWINT 0x60C80300 //Hardware Interrupts Received
#define P6_BTAKR 0x60C90300 //Taken Branch Retired
#define P6_BTAKM 0x60CA0300 //Taken Branch Mispredictions
#define P6_FPMMX 0x60CC0301 //Transitions from Floating Point to MMX
#define P6_MMXFP 0x60CC0300 //Transitions from MMX to Floating Point
#define P6_SIMDA 0x60CD0300 //SIMD Assists (EMMS Instructions Executed)
#define P6_MMXIR 0x60CE0300 //MMX Instructions Retired
#define P6_SAISR 0x60CF0300 //Saturated Arithmetic Instructions Retired
#define P6_INSTD 0x60D00300 //Instructions Decoded
#define P6_NPRTL 0x60D20300 //Renaming Stalls
#define P6_SRSES 0x60D40301 //Segment Rename Stalls - ES
#define P6_SRSDS 0x60D40302 //Segment Rename Stalls - DS
#define P6_SRSFS 0x60D40304 //Segment Rename Stalls - FS
#define P6_SRSGS 0x60D40308 //Segment Rename Stalls - GS
#define P6_SRSXS 0x60D4030F //Segment Rename Stalls - ES DS FS GS
#define P6_SRNES 0x60D50301 //Segment Renames - ES
#define P6_SRNDS 0x60D50302 //Segment Renames - DS
#define P6_SRNFS 0x60D50304 //Segment Renames - FS
#define P6_SRNGS 0x60D50308 //Segment Renames - GS
#define P6_SRNXS 0x60D5030F //Segment Renames - ES DS FS GS
#define P6_BRDEC 0x60E00300 //Branch Instructions Decoded
#define P6_BTBMS 0x60E20301 //BTB Misses
#define P6_RETDC 0x60E40300 //Bogus Branches
#define P6_BACLR 0x60E60300 //BACLEARS Asserted (Testing)
// INTEL
#define PENTIUM_FAMILY 5 // define for pentium
#define PENTIUMPRO_FAMILY 6 // define for pentium pro
#define PENTIUM4_FAMILY 15 // define for pentium 4
// AMD
#define K6_FAMILY 5
#define K8_FAMILY 6
#define EXTENDED_FAMILY 15 // AMD 64 and AMD Opteron
#endif // P5P6PERFORMANCECOUNTERS_H

2017
external/vpc/public/tier0/platform.h vendored Normal file

File diff suppressed because it is too large Load Diff

212
external/vpc/public/tier0/pmelib.h vendored Normal file
View File

@@ -0,0 +1,212 @@
//===== Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ======//
//
// Purpose:
//
// $NoKeywords: $
//
//===========================================================================//
#ifndef PMELIB_H
#define PMELIB_H
//#include "windows.h"
#include "tier0/platform.h"
// Get rid of a bunch of STL warnings!
#pragma warning( push, 3 )
#pragma warning( disable : 4018 )
#define VERSION "1.0.2"
// uncomment this list to add some runtime checks
//#define PME_DEBUG
#include "tier0/valve_off.h"
#include <string>
#include "tier0/valve_on.h"
using namespace std;
// RDTSC Instruction macro
#ifdef COMPILER_MSVC64
#define RDTSC(var) (var = __rdtsc())
#else
#define RDTSC(var) \
_asm RDTSC \
_asm mov DWORD PTR var,eax \
_asm mov DWORD PTR var+4,edx
#endif
// RDPMC Instruction macro
#ifdef COMPILER_MSVC64
#define RDPMC(counter, var) (var = __readpmc(counter))
#else
#define RDPMC(counter, var) \
_asm mov ecx, counter \
_asm RDPMC \
_asm mov DWORD PTR var,eax \
_asm mov DWORD PTR var+4,edx
#endif
// RDPMC Instruction macro, for performance counter 1 (ecx = 1)
#ifdef COMPILER_MSVC64
#define RDPMC0(var) (var = __readpmc(0))
#else
#define RDPMC0(var) \
_asm mov ecx, 0 \
_asm RDPMC \
_asm mov DWORD PTR var,eax \
_asm mov DWORD PTR var+4,edx
#endif
#ifdef COMPILER_MSVC64
#define RDPMC1(var) (var = __readpmc(1))
#else
#define RDPMC1(var) \
_asm mov ecx, 1 \
_asm RDPMC \
_asm mov DWORD PTR var,eax \
_asm mov DWORD PTR var+4,edx
#endif
#define EVENT_TYPE(mode) EventType##mode
#define EVENT_MASK(mode) EventMask##mode
#include "ia32detect.h"
enum ProcessPriority
{
ProcessPriorityNormal,
ProcessPriorityHigh,
};
enum PrivilegeCapture
{
OS_Only, // ring 0, kernel level
USR_Only, // app level
OS_and_USR, // all levels
};
enum CompareMethod
{
CompareGreater, //
CompareLessEqual, //
};
enum EdgeState
{
RisingEdgeDisabled, //
RisingEdgeEnabled, //
};
enum CompareState
{
CompareDisable, //
CompareEnable, //
};
// Singletion Class
class PME : public ia32detect
{
public:
//private:
static PME* _singleton;
HANDLE hFile;
bool bDriverOpen;
double m_CPUClockSpeed;
//ia32detect detect;
HRESULT Init();
HRESULT Close();
protected:
PME()
{
hFile = NULL;
bDriverOpen = FALSE;
m_CPUClockSpeed = 0;
Init();
}
public:
static PME* Instance(); // gives back a real object
~PME()
{
Close();
}
double GetCPUClockSpeedSlow( void );
double GetCPUClockSpeedFast( void );
HRESULT SelectP5P6PerformanceEvent( uint32 dw_event, uint32 dw_counter, bool b_user, bool b_kernel );
HRESULT ReadMSR( uint32 dw_reg, int64 * pi64_value );
HRESULT ReadMSR( uint32 dw_reg, uint64 * pi64_value );
HRESULT WriteMSR( uint32 dw_reg, const int64 & i64_value );
HRESULT WriteMSR( uint32 dw_reg, const uint64 & i64_value );
void SetProcessPriority( ProcessPriority priority )
{
switch( priority )
{
case ProcessPriorityNormal:
{
SetPriorityClass (GetCurrentProcess(),NORMAL_PRIORITY_CLASS);
SetThreadPriority (GetCurrentThread(),THREAD_PRIORITY_NORMAL);
break;
}
case ProcessPriorityHigh:
{
SetPriorityClass (GetCurrentProcess(),REALTIME_PRIORITY_CLASS);
SetThreadPriority (GetCurrentThread(),THREAD_PRIORITY_HIGHEST);
break;
}
}
}
//---------------------------------------------------------------------------
// Return the family of the processor
//---------------------------------------------------------------------------
CPUVendor GetVendor(void)
{
return vendor;
}
int GetProcessorFamily(void)
{
return version.Family;
}
#ifdef DBGFLAG_VALIDATE
void Validate( CValidator &validator, tchar *pchName ); // Validate our internal structures
#endif // DBGFLAG_VALIDATE
};
#include "p5p6performancecounters.h"
#include "p4performancecounters.h"
#include "k8performancecounters.h"
enum PerfErrors
{
E_UNKNOWN_CPU_VENDOR = -1,
E_BAD_COUNTER = -2,
E_UNKNOWN_CPU = -3,
E_CANT_OPEN_DRIVER = -4,
E_DRIVER_ALREADY_OPEN = -5,
E_DRIVER_NOT_OPEN = -6,
E_DISABLED = -7,
E_BAD_DATA = -8,
E_CANT_CLOSE = -9,
E_ILLEGAL_OPERATION = -10,
};
#pragma warning( pop )
#endif // PMELIB_H

966
external/vpc/public/tier0/stackstats.h vendored Normal file
View File

@@ -0,0 +1,966 @@
//========= Copyright <20> 1996-2008, Valve Corporation, All rights reserved. ============//
//
// Purpose: Tools for grabbing/dumping the stack at runtime
//
// $NoKeywords: $
//=============================================================================//
#ifndef TIER0_STACKSTATS_H
#define TIER0_STACKSTATS_H
#ifdef _WIN32
#pragma once
#endif
#include "tier0/stacktools.h"
#include "tier0/threadtools.h"
#if defined ENABLE_RUNTIME_STACK_TRANSLATION
#define ENABLE_STACK_STATS_GATHERING //uncomment to enable the gathering class
#endif
#if defined ENABLE_STACK_STATS_GATHERING
#include "tier0/valve_off.h"
# include <map> //needed for CCallStackStatsGatherer
# include <vector>
#include "tier0/valve_on.h"
#define CDefaultStatsGathererAllocator std::allocator
#else
template<class _Ty> class CNullStatsGathererAllocator { CNullStatsGathererAllocator( void ) { } };
#define CDefaultStatsGathererAllocator CNullStatsGathererAllocator
#endif
typedef size_t (*FN_DescribeStruct)( uint8 *, size_t );
class CCallStackStatsGatherer_Standardized_t;
struct CCallStackStatsGatherer_FunctionTable_t
{
void (*pfn_GetDumpInfo)( void *, const char *&, size_t &, size_t &, void *&, size_t &, CCallStackStatsGatherer_Standardized_t *&, size_t & );
void (*pfn_PushSubTree)( void *, const CCallStackStatsGatherer_Standardized_t &, const CCallStackStorage & );
void (*pfn_PopSubTree)( void * );
size_t (*pfn_DescribeCallStackStatStruct)( uint8 *, size_t );
void (*pfn_SyncMutexes)( void *, bool );
void *(*pfn_GetEntry)( void *, uint32 );
void (*pfn_ApplyTreeAccessLock)( void *, bool );
void (*pfn_LockEntry)( void *, uint32, bool );
};
//templatized classes are fun, can't really use a base pointer effectively, so we'll have a translator struct and store pointers to instances of the translator function
class CCallStackStatsGatherer_Standardized_t
{
public:
CCallStackStatsGatherer_Standardized_t( void ) {};
CCallStackStatsGatherer_Standardized_t( void *pThis, const CCallStackStatsGatherer_FunctionTable_t &FnTable ) : pGatherer( pThis ), pFunctionTable( &FnTable ) {};
//go ahead and create some helper functions that are likely to be used by helper code
void PushSubTree( const CCallStackStatsGatherer_Standardized_t &SubTree, const CCallStackStorage &PushStack = CCallStackStorage() ) const
{
pFunctionTable->pfn_PushSubTree( pGatherer, SubTree, PushStack );
}
inline void PopSubTree( void ) const
{
pFunctionTable->pfn_PopSubTree( pGatherer );
}
void *pGatherer;
const CCallStackStatsGatherer_FunctionTable_t *pFunctionTable;
};
//Designed to be called by an instance of CCallStackStatsGatherer to dump it's data
PLATFORM_INTERFACE bool _CCallStackStatsGatherer_Internal_DumpStatsToFile( const char *szFileName, const CCallStackStatsGatherer_Standardized_t &StatsGatherer, bool bAllowMemoryAllocations );
template <class STATSTRUCT>
class CCallStackStatsGatherer_StructAccessor_Base
{
public:
CCallStackStatsGatherer_StructAccessor_Base( const CCallStackStatsGatherer_Standardized_t &Gatherer, int iEntryIndex ) : m_Gatherer( Gatherer ), m_iEntryIndex( iEntryIndex ) {};
protected:
uint32 m_iEntryIndex; //index of the stat entry we want in the vector. Stored as index as the vector base address can change.
CCallStackStatsGatherer_Standardized_t m_Gatherer; //so we can lock the vector memory in place while manipulating the values
};
class CCallStackStatsGatherer_StatMutexBase
{
public:
void LockEntry( uint32 iEntryIndex, bool bLock ) {} //true to increase lock refcount, false to decrease
};
template <uint32 SHAREDENTRYMUTEXES> //must be a power of 2
class CCallStackStatsGatherer_StatMutexPool
{
public:
void LockEntry( uint32 iEntryIndex, bool bLock )
{
#if defined( ENABLE_STACK_STATS_GATHERING )
COMPILE_TIME_ASSERT( (SHAREDENTRYMUTEXES & (SHAREDENTRYMUTEXES - 1)) == 0 ); //must be a power of 2
if( bLock )
{
m_IndividualEntryMutexes[iEntryIndex & (SHAREDENTRYMUTEXES - 1)].Lock();
}
else
{
m_IndividualEntryMutexes[iEntryIndex & (SHAREDENTRYMUTEXES - 1)].Unlock();
}
#endif
}
protected:
CThreadFastMutex m_IndividualEntryMutexes[SHAREDENTRYMUTEXES];
};
//STATSTRUCT - The structure you'll use to track whatever it is you're tracking.
//CAPTUREDCALLSTACKLENGTH - The maximum length of your stack trace that we'll use to distinguish entries
//STACKACQUISITIONFUNCTION - The function to use to gather the current call stack. GetCallStack() is safe, GetCallStack_Fast() is faster, but has special requirements
//STATMUTEXHANDLER - If you want automatic mutex management for your individual entries, supply a handler here.
// You'll need to not only call GetEntry(), but lock/unlock the entry while accessing it.
//TEMPLATIZEDMEMORYALLOCATOR - We'll need to allocate memory, supply an allocator if you want to manage that
template <class STATSTRUCT, size_t CAPTUREDCALLSTACKLENGTH, FN_GetCallStack STACKACQUISITIONFUNCTION = GetCallStack, typename STATMUTEXHANDLER = CCallStackStatsGatherer_StatMutexPool<4>, template <typename T> class TEMPLATIZEDMEMORYALLOCATOR = CDefaultStatsGathererAllocator>
class CCallStackStatsGatherer : public STATMUTEXHANDLER
{
public:
#if !defined( ENABLE_STACK_STATS_GATHERING )
CCallStackStatsGatherer( void )
{
for( size_t i = 0; i != CAPTUREDCALLSTACKLENGTH; ++i )
m_SingleCallStack[i] = NULL;
}
#endif
CCallStackStatsGatherer_StructAccessor_Base<STATSTRUCT> GetEntry( void * const CallStack[CAPTUREDCALLSTACKLENGTH] ); //get the entry using some callstack grabbed a while ago. Assumes ALL invalid entries have been nullified
CCallStackStatsGatherer_StructAccessor_Base<STATSTRUCT> GetEntry( void * const CallStack[CAPTUREDCALLSTACKLENGTH], uint32 iValidEntries ); //same as above, but does the work of nullifying invalid entries
CCallStackStatsGatherer_StructAccessor_Base<STATSTRUCT> GetEntry( const CCallStackStorage &PushStack = CCallStackStorage( STACKACQUISITIONFUNCTION ) );
CCallStackStatsGatherer_StructAccessor_Base<STATSTRUCT> GetEntry( uint32 iEntryIndex );
//get the entry index for the caller's current call stack. Pre-nullified entries count as valid entries (and save re-nullification work)
uint32 GetEntryIndex( void * const CallStack[CAPTUREDCALLSTACKLENGTH], uint32 iValidEntries ); //index is unchanging, safe to keep and use later (designed for exactly that purpose)
uint32 GetEntryIndex( const CCallStackStorage &PushStack = CCallStackStorage( STACKACQUISITIONFUNCTION ) );
typedef void *(&StackReference)[CAPTUREDCALLSTACKLENGTH];
StackReference GetCallStackForIndex( uint32 iEntryIndex )
{
#if defined( ENABLE_STACK_STATS_GATHERING )
return m_StatEntries[iEntryIndex].m_CallStack;
#else
return m_SingleCallStack;
#endif
}
void GetCallStackForIndex( uint32 iEntryIndex, void *CallStackOut[CAPTUREDCALLSTACKLENGTH] );
size_t NumEntries( void ) const;
bool DumpToFile( const char *szFileName, bool bAllowMemoryAllocations = true );
static const CCallStackStatsGatherer_FunctionTable_t &GetFunctionTable( void );
static void GetDumpInfo( void *pThis, const char *&szStructName, size_t &iCapturedStackLength, size_t &iEntrySizeWithStack, void *&pEntries, size_t &iEntryCount, CCallStackStatsGatherer_Standardized_t *&pSubTrees, size_t &iSubTreeCount );
static void PushSubTree( void *pParent, const CCallStackStatsGatherer_Standardized_t &SubTree, const CCallStackStorage &PushStack );
void PushSubTree( CCallStackStatsGatherer_Standardized_t &Parent, const CCallStackStorage &PushStack = CCallStackStorage( STACKACQUISITIONFUNCTION ) );
static void PopSubTree( void *pParent );
static void SyncMutexes( void *pParent, bool bLock ); //true for lock, false for unlock
static void *GetEntry( void *pParent, uint32 iEntryIndex );
static void ApplyTreeAccessLock( void *pParent, bool bLock );
static void LockEntry( void *pParent, uint32 iEntryIndex, bool bLock );
void Reset( void );
CCallStackStatsGatherer_Standardized_t Standardized( void );
operator CCallStackStatsGatherer_Standardized_t( void );
const static FN_GetCallStack StackFunction; //publish the requested acquisition function so you can easily key all your stack gathering to the class instance
const static size_t CapturedCallStackLength;
private:
#pragma pack(push)
#pragma pack(1)
struct StackAndStats_t
{
void *m_CallStack[CAPTUREDCALLSTACKLENGTH];
STATSTRUCT m_Stats;
};
#pragma pack(pop)
typedef CCallStackStatsGatherer<STATSTRUCT, CAPTUREDCALLSTACKLENGTH, STACKACQUISITIONFUNCTION, STATMUTEXHANDLER, TEMPLATIZEDMEMORYALLOCATOR> ThisCast;
#if defined( ENABLE_STACK_STATS_GATHERING )
struct IndexMapKey_t
{
IndexMapKey_t( void * const CallStack[CAPTUREDCALLSTACKLENGTH] )
{
m_Hash = 0;
for( int i = 0; i < CAPTUREDCALLSTACKLENGTH; ++i )
{
m_CallStack[i] = CallStack[i];
m_Hash += (uintp)CallStack[i];
}
}
bool operator<( const IndexMapKey_t &key ) const
{
if( m_Hash != key.m_Hash )
return m_Hash < key.m_Hash;
//only here if there's a hash match. Do a full check. Extremely likely to be the exact same call stack. But not 100% guaranteed.
for( int i = 0; i < CAPTUREDCALLSTACKLENGTH; ++i )
{
if( m_CallStack[i] == key.m_CallStack[i] )
{
continue;
}
return m_CallStack[i] < key.m_CallStack[i];
}
return false; //exact same call stack
}
uintp m_Hash;
void *m_CallStack[CAPTUREDCALLSTACKLENGTH];
};
void KeepSubTree( CCallStackStatsGatherer_Standardized_t &SubTree )
{
AUTO_LOCK_FM( m_SubTreeMutex );
for( typename StoredSubTreeVector_t::iterator treeIter = m_StoredSubTrees.begin(); treeIter != m_StoredSubTrees.end(); ++treeIter )
{
if( SubTree.pGatherer == treeIter->pGatherer )
return;
}
//Warning( "Storing subtree\n" );
m_StoredSubTrees.push_back( SubTree );
}
uint32 PatchInSubTrees( void * const CallStackIn[CAPTUREDCALLSTACKLENGTH], void *CallStackOut[CAPTUREDCALLSTACKLENGTH], uint32 iValidEntries )
{
if( iValidEntries > CAPTUREDCALLSTACKLENGTH )
{
iValidEntries = CAPTUREDCALLSTACKLENGTH;
}
AUTO_LOCK_FM( m_SubTreeMutex );
if( m_PushedSubTrees.size() == 0 )
{
memcpy( CallStackOut, CallStackIn, sizeof( void * ) * iValidEntries );
return iValidEntries;
}
unsigned long iThreadID = ThreadGetCurrentId();
typename PushedSubTreeVector_t::reverse_iterator treeIter;
for( treeIter = m_PushedSubTrees.rbegin(); treeIter != m_PushedSubTrees.rend(); ++treeIter )
{
if( treeIter->iThreadID == iThreadID )
{
break;
}
}
if( treeIter == m_PushedSubTrees.rend() )
{
memcpy( CallStackOut, CallStackIn, sizeof( void * ) * iValidEntries );
return iValidEntries;
}
//char szTemp[4096];
//TranslateStackInfo( CallStackIn, CAPTUREDCALLSTACKLENGTH, szTemp, sizeof( szTemp ), "\n\t" );
//Warning( "Attempting to link trees:\n=======================ONE=======================\n\t%s\n", szTemp );
//TranslateStackInfo( treeIter->Stack, CAPTUREDCALLSTACKLENGTH, szTemp, sizeof( szTemp ), "\n\t" );
//Warning( "=======================TWO=======================\n\t%s\n", szTemp );
void *pMatchAddress = treeIter->Stack[1]; //while the first entry is where the actual push was made. The second entry is the first that is matchable in most cases
uint32 i;
for( i = 0; i < iValidEntries; ++i )
{
if( CallStackIn[i] == pMatchAddress )
{
//TranslateStackInfo( CallStackIn, i, szTemp, sizeof( szTemp ), "\n\t" );
//Warning( "======================MATCH======================\n\t%s\n", szTemp );
CallStackOut[i] = treeIter->tree.pGatherer; //tag this entry as leading into the sub-tree
KeepSubTree( treeIter->tree ); //store the sub-tree forever
return i + 1;
}
CallStackOut[i] = CallStackIn[i];
}
return iValidEntries;
//Warning( "=======================END=======================\n" );
}
struct StatIndex_t
{
StatIndex_t( void ) : m_Index((unsigned int)-1) {};
unsigned int m_Index;
};
typedef std::vector<StackAndStats_t, TEMPLATIZEDMEMORYALLOCATOR<StackAndStats_t> > StatVector_t;
typedef std::map< IndexMapKey_t, StatIndex_t, std::less<IndexMapKey_t>, TEMPLATIZEDMEMORYALLOCATOR<std::pair<const IndexMapKey_t, StatIndex_t> > > IndexMap_t;
typedef typename IndexMap_t::iterator IndexMapIter_t;
typedef typename IndexMap_t::value_type IndexMapEntry_t;
StatVector_t m_StatEntries;
IndexMap_t m_IndexMap;
struct PushedSubTree_t
{
unsigned long iThreadID;
CCallStackStatsGatherer_Standardized_t tree;
void *Stack[CAPTUREDCALLSTACKLENGTH];
};
typedef std::vector<PushedSubTree_t, TEMPLATIZEDMEMORYALLOCATOR<PushedSubTree_t> > PushedSubTreeVector_t;
PushedSubTreeVector_t m_PushedSubTrees;
typedef std::vector<CCallStackStatsGatherer_Standardized_t, TEMPLATIZEDMEMORYALLOCATOR<CCallStackStatsGatherer_Standardized_t> > StoredSubTreeVector_t;
StoredSubTreeVector_t m_StoredSubTrees;
CThreadFastMutex m_IndexMapMutex;
CThreadFastMutex m_SubTreeMutex;
//only for locking the memory in place, locked for write when the entry addresses might change.
//Locked for read when you've claimed you're manipulating a value.
//You're on your own for making sure two threads don't access the same index simultaneously
CThreadRWLock m_StatEntryLock;
#else //#if defined( ENABLE_STACK_STATS_GATHERING )
STATSTRUCT m_SingleEntry; //the class is disabled, we'll always return this same struct
void *m_SingleCallStack[CAPTUREDCALLSTACKLENGTH];
static size_t NULL_DescribeCallStackStatStruct( uint8 *pDescribeWriteBuffer, size_t iDescribeMaxLength ) { return 0; }
#endif //#if defined( ENABLE_STACK_STATS_GATHERING )
};
template <class STATSTRUCT, size_t CAPTUREDCALLSTACKLENGTH, FN_GetCallStack STACKACQUISITIONFUNCTION, typename STATMUTEXHANDLER, template <typename T> class TEMPLATIZEDMEMORYALLOCATOR>
const FN_GetCallStack CCallStackStatsGatherer<STATSTRUCT, CAPTUREDCALLSTACKLENGTH, STACKACQUISITIONFUNCTION, STATMUTEXHANDLER, TEMPLATIZEDMEMORYALLOCATOR>::StackFunction = STACKACQUISITIONFUNCTION;
template <class STATSTRUCT, size_t CAPTUREDCALLSTACKLENGTH, FN_GetCallStack STACKACQUISITIONFUNCTION, typename STATMUTEXHANDLER, template <typename T> class TEMPLATIZEDMEMORYALLOCATOR>
const size_t CCallStackStatsGatherer<STATSTRUCT, CAPTUREDCALLSTACKLENGTH, STACKACQUISITIONFUNCTION, STATMUTEXHANDLER, TEMPLATIZEDMEMORYALLOCATOR>::CapturedCallStackLength = CAPTUREDCALLSTACKLENGTH;
#if defined( ENABLE_STACK_STATS_GATHERING )
class CallStackStatStructDescFuncs;
PLATFORM_INTERFACE size_t _CCallStackStatsGatherer_Write_FieldDescriptions( CallStackStatStructDescFuncs *pFieldDescriptions, uint8 *pWriteBuffer, size_t iWriteBufferSize );
//PLATFORM_INTERFACE size_t _CCallStackStatsGatherer_Write_FieldMergeScript( CallStackStatStructDescFuncs *pFieldDescriptions, CallStackStatStructDescFuncs::MergeScript_Language scriptMergeLanguage, uint8 *pWriteBuffer, size_t iWriteBufferSize );
#define DECLARE_CALLSTACKSTATSTRUCT() static const char *STATSTRUCTSTRINGNAME;\
static size_t DescribeCallStackStatStruct( uint8 *pDescribeWriteBuffer, size_t iDescribeMaxLength );
#define BEGIN_STATSTRUCTDESCRIPTION( className ) const char *className::STATSTRUCTSTRINGNAME = #className;\
size_t className::DescribeCallStackStatStruct( uint8 *pDescribeWriteBuffer, size_t iDescribeMaxLength ) {\
size_t iWroteBytes = 0;
#define END_STATSTRUCTDESCRIPTION() return iWroteBytes; }
#define DECLARE_CALLSTACKSTATSTRUCT_FIELDDESCRIPTION() static CallStackStatStructDescFuncs *GetStatStructFieldDescriptions( void );
#define BEGIN_STATSTRUCTFIELDDESCRIPTION( className ) CallStackStatStructDescFuncs * className::GetStatStructFieldDescriptions( void ) {\
typedef className ThisStruct;\
CallStackStatStructDescFuncs *_pHeadLinkage = NULL;\
CallStackStatStructDescFuncs **_pLinkageHelperVar = &_pHeadLinkage;
#define _DEFINE_STATSTRUCTFIELD_VARNAME( varName, fieldName, fieldStruct, fieldParmsInParentheses ) static fieldStruct varName##_desc##fieldParmsInParentheses;\
varName##_desc.m_szFieldName = #fieldName;\
varName##_desc.m_iFieldOffset = (size_t)(&((ThisStruct *)NULL)->fieldName);\
varName##_desc.m_pNext = NULL;\
*_pLinkageHelperVar = &varName##_desc;\
_pLinkageHelperVar = &varName##_desc.m_pNext;
#define DEFINE_STATSTRUCTFIELD( fieldName, fieldStruct, fieldParmsInParentheses ) _DEFINE_STATSTRUCTFIELD_VARNAME( fieldName, fieldName, fieldStruct, fieldParmsInParentheses )
#define DEFINE_STATSTRUCTFIELD_ARRAYENTRY( arrayName, arrayIndex, fieldStruct, fieldParmsInParentheses ) _DEFINE_STATSTRUCTFIELD_VARNAME( arrayName##_##arrayIndex, arrayName##[##arrayIndex##], fieldStruct, fieldParmsInParentheses )
#define END_STATSTRUCTFIELDDESCRIPTION() static CallStackStatStructDescFuncs *s_pHeadStruct = _pHeadLinkage;\
return s_pHeadStruct; }
#define WRITE_STATSTRUCT_FIELDDESCRIPTION() iWroteBytes += _CCallStackStatsGatherer_Write_FieldDescriptions( GetStatStructFieldDescriptions(), pDescribeWriteBuffer + iWroteBytes, iDescribeMaxLength - iWroteBytes );
//#define WRITE_STATSTRUCT_FIELDMERGESCRIPT( scriptMergeLanguage ) iWroteBytes += _CCallStackStatsGatherer_Write_FieldMergeScript( GetStatStructFieldDescriptions(), CallStackStatStructDescFuncs::scriptMergeLanguage, pDescribeWriteBuffer + iWroteBytes, iDescribeMaxLength - iWroteBytes );
#else //#if defined( ENABLE_STACK_STATS_GATHERING )
#define DECLARE_CALLSTACKSTATSTRUCT()
#define BEGIN_STATSTRUCTDESCRIPTION( className )
#define END_STATSTRUCTDESCRIPTION()
#define DECLARE_CALLSTACKSTATSTRUCT_FIELDDESCRIPTION()
#define BEGIN_STATSTRUCTFIELDDESCRIPTION( className )
#define DEFINE_STATSTRUCTFIELD( fieldName, fieldStruct, fieldParmsInParentheses )
#define END_STATSTRUCTFIELDDESCRIPTION()
#define WRITE_STATSTRUCT_FIELDDESCRIPTION()
//#define WRITE_STATSTRUCT_FIELDMERGESCRIPT( scriptMergeLanguage )
#endif //#if defined( ENABLE_STACK_STATS_GATHERING )
template <class STATSTRUCT, size_t CAPTUREDCALLSTACKLENGTH, FN_GetCallStack STACKACQUISITIONFUNCTION, typename STATMUTEXHANDLER, template <typename T> class TEMPLATIZEDMEMORYALLOCATOR>
CCallStackStatsGatherer_StructAccessor_Base<STATSTRUCT> CCallStackStatsGatherer<STATSTRUCT, CAPTUREDCALLSTACKLENGTH, STACKACQUISITIONFUNCTION, STATMUTEXHANDLER, TEMPLATIZEDMEMORYALLOCATOR>::GetEntry( void * const CallStack[CAPTUREDCALLSTACKLENGTH] ) //get the entry using some callstack grabbed a while ago. Assumes ALL invalid entries have been nullified
{
#if defined( ENABLE_STACK_STATS_GATHERING )
return GetEntry( GetEntryIndex( CallStack ) );
#else
return CCallStackStatsGatherer_StructAccessor_Base<STATSTRUCT>( Standardized(), 0 );
#endif
}
template <class STATSTRUCT, size_t CAPTUREDCALLSTACKLENGTH, FN_GetCallStack STACKACQUISITIONFUNCTION, typename STATMUTEXHANDLER, template <typename T> class TEMPLATIZEDMEMORYALLOCATOR>
CCallStackStatsGatherer_StructAccessor_Base<STATSTRUCT> CCallStackStatsGatherer<STATSTRUCT, CAPTUREDCALLSTACKLENGTH, STACKACQUISITIONFUNCTION, STATMUTEXHANDLER, TEMPLATIZEDMEMORYALLOCATOR>::GetEntry( void * const CallStack[CAPTUREDCALLSTACKLENGTH], uint32 iValidEntries ) //same as above, but does the work of nullifying invalid entries
{
#if defined( ENABLE_STACK_STATS_GATHERING )
void *CleanedCallStack[CAPTUREDCALLSTACKLENGTH];
size_t i;
for( i = 0; i < CAPTUREDCALLSTACKLENGTH; ++i )
{
CleanedCallStack[i] = CallStack[i];
}
for( ; i < CAPTUREDCALLSTACKLENGTH; ++i )
{
CleanedCallStack[i] = NULL;
}
return GetEntry( GetEntryIndex( CleanedCallStack ) );
#else
return CCallStackStatsGatherer_StructAccessor_Base<STATSTRUCT>( Standardized(), 0 );
#endif
}
template <class STATSTRUCT, size_t CAPTUREDCALLSTACKLENGTH, FN_GetCallStack STACKACQUISITIONFUNCTION, typename STATMUTEXHANDLER, template <typename T> class TEMPLATIZEDMEMORYALLOCATOR>
CCallStackStatsGatherer_StructAccessor_Base<STATSTRUCT> CCallStackStatsGatherer<STATSTRUCT, CAPTUREDCALLSTACKLENGTH, STACKACQUISITIONFUNCTION, STATMUTEXHANDLER, TEMPLATIZEDMEMORYALLOCATOR>::GetEntry( const CCallStackStorage &PushStack )
{
#if defined( ENABLE_STACK_STATS_GATHERING )
COMPILE_TIME_ASSERT( CAPTUREDCALLSTACKLENGTH <= ARRAYSIZE( PushStack.pStack ) );
return GetEntry( GetEntryIndex( PushStack.pStack, PushStack.iValidEntries ) );
#else
return CCallStackStatsGatherer_StructAccessor_Base<STATSTRUCT>( Standardized(), 0 );
#endif
}
template <class STATSTRUCT, size_t CAPTUREDCALLSTACKLENGTH, FN_GetCallStack STACKACQUISITIONFUNCTION, typename STATMUTEXHANDLER, template <typename T> class TEMPLATIZEDMEMORYALLOCATOR>
uint32 CCallStackStatsGatherer<STATSTRUCT, CAPTUREDCALLSTACKLENGTH, STACKACQUISITIONFUNCTION, STATMUTEXHANDLER, TEMPLATIZEDMEMORYALLOCATOR>::GetEntryIndex( const CCallStackStorage &PushStack )
{
#if defined( ENABLE_STACK_STATS_GATHERING )
COMPILE_TIME_ASSERT( CAPTUREDCALLSTACKLENGTH <= ARRAYSIZE( PushStack.pStack ) );
return GetEntryIndex( PushStack.pStack, PushStack.iValidEntries );
#else
return 0;
#endif
}
template <class STATSTRUCT, size_t CAPTUREDCALLSTACKLENGTH, FN_GetCallStack STACKACQUISITIONFUNCTION, typename STATMUTEXHANDLER, template <typename T> class TEMPLATIZEDMEMORYALLOCATOR>
CCallStackStatsGatherer_StructAccessor_Base<STATSTRUCT> CCallStackStatsGatherer<STATSTRUCT, CAPTUREDCALLSTACKLENGTH, STACKACQUISITIONFUNCTION, STATMUTEXHANDLER, TEMPLATIZEDMEMORYALLOCATOR>::GetEntry( uint32 iEntryIndex )
{
#if defined( ENABLE_STACK_STATS_GATHERING )
return CCallStackStatsGatherer_StructAccessor_Base<STATSTRUCT>( Standardized(), iEntryIndex );
#else
return CCallStackStatsGatherer_StructAccessor_Base<STATSTRUCT>( Standardized(), 0 );
#endif
}
template <class STATSTRUCT, size_t CAPTUREDCALLSTACKLENGTH, FN_GetCallStack STACKACQUISITIONFUNCTION, typename STATMUTEXHANDLER, template <typename T> class TEMPLATIZEDMEMORYALLOCATOR>
uint32 CCallStackStatsGatherer<STATSTRUCT, CAPTUREDCALLSTACKLENGTH, STACKACQUISITIONFUNCTION, STATMUTEXHANDLER, TEMPLATIZEDMEMORYALLOCATOR>::GetEntryIndex( void * const CallStack[CAPTUREDCALLSTACKLENGTH], uint32 iValidEntries ) //index is unchanging, safe to keep and use later (designed for exactly that purpose)
{
#if defined( ENABLE_STACK_STATS_GATHERING )
AUTO_LOCK_FM( m_IndexMapMutex );
std::pair<IndexMapIter_t, bool> indexMapIter;
void *PatchedStack[CAPTUREDCALLSTACKLENGTH];
//if we have a sub-tree. We'll be splicing it into the original call stack as if it were a return address. Then patching that when we interpret the results later
//A stack with a sub-tree along the line is treated as distinctly different than one without a sub-tree
iValidEntries = PatchInSubTrees( CallStack, PatchedStack, iValidEntries );
Assert( iValidEntries <= CAPTUREDCALLSTACKLENGTH );
for( int i = iValidEntries; i < CAPTUREDCALLSTACKLENGTH; ++i )
{
PatchedStack[i] = NULL;
}
indexMapIter = m_IndexMap.insert( IndexMapEntry_t( IndexMapKey_t( PatchedStack ), StatIndex_t() ) );
if( indexMapIter.first->second.m_Index == -1 )
{
m_StatEntryLock.LockForWrite();
indexMapIter.first->second.m_Index = (unsigned int)m_StatEntries.size();
m_StatEntries.push_back( StackAndStats_t() );
memcpy( m_StatEntries[indexMapIter.first->second.m_Index].m_CallStack, PatchedStack, sizeof( void * ) * CAPTUREDCALLSTACKLENGTH );
m_StatEntryLock.UnlockWrite();
}
return indexMapIter.first->second.m_Index;
#else
return 0;
#endif
}
template <class STATSTRUCT, size_t CAPTUREDCALLSTACKLENGTH, FN_GetCallStack STACKACQUISITIONFUNCTION, typename STATMUTEXHANDLER, template <typename T> class TEMPLATIZEDMEMORYALLOCATOR>
void CCallStackStatsGatherer<STATSTRUCT, CAPTUREDCALLSTACKLENGTH, STACKACQUISITIONFUNCTION, STATMUTEXHANDLER, TEMPLATIZEDMEMORYALLOCATOR>::GetCallStackForIndex( uint32 iEntryIndex, void *CallStackOut[CAPTUREDCALLSTACKLENGTH] )
{
#if defined( ENABLE_STACK_STATS_GATHERING )
m_StatEntryLock.LockForRead();
for( size_t i = 0; i != CAPTUREDCALLSTACKLENGTH; ++i )
{
CallStackOut[i] = m_StatEntries[iEntryIndex].m_CallStack[i];
}
m_StatEntryLock.UnlockRead();
#else
for( size_t i = 0; i != CAPTUREDCALLSTACKLENGTH; ++i )
CallStackOut[i] = NULL;
#endif
}
template <class STATSTRUCT, size_t CAPTUREDCALLSTACKLENGTH, FN_GetCallStack STACKACQUISITIONFUNCTION, typename STATMUTEXHANDLER, template <typename T> class TEMPLATIZEDMEMORYALLOCATOR>
size_t CCallStackStatsGatherer<STATSTRUCT, CAPTUREDCALLSTACKLENGTH, STACKACQUISITIONFUNCTION, STATMUTEXHANDLER, TEMPLATIZEDMEMORYALLOCATOR>::NumEntries( void ) const
{
#if defined( ENABLE_STACK_STATS_GATHERING )
return m_StatEntries.size();
#else
return 0;
#endif
}
template <class STATSTRUCT, size_t CAPTUREDCALLSTACKLENGTH, FN_GetCallStack STACKACQUISITIONFUNCTION, typename STATMUTEXHANDLER, template <typename T> class TEMPLATIZEDMEMORYALLOCATOR>
bool CCallStackStatsGatherer<STATSTRUCT, CAPTUREDCALLSTACKLENGTH, STACKACQUISITIONFUNCTION, STATMUTEXHANDLER, TEMPLATIZEDMEMORYALLOCATOR>::DumpToFile( const char *szFileName, bool bAllowMemoryAllocations )
{
#if defined( ENABLE_STACK_STATS_GATHERING )
CCallStackStatsGatherer_Standardized_t StandardThis = Standardized();
SyncMutexes( this, true );
bool bRetVal = _CCallStackStatsGatherer_Internal_DumpStatsToFile( szFileName, StandardThis, bAllowMemoryAllocations );
SyncMutexes( this, false );
return bRetVal;
#else
return false;
#endif
}
template <class STATSTRUCT, size_t CAPTUREDCALLSTACKLENGTH, FN_GetCallStack STACKACQUISITIONFUNCTION, typename STATMUTEXHANDLER, template <typename T> class TEMPLATIZEDMEMORYALLOCATOR>
const CCallStackStatsGatherer_FunctionTable_t &CCallStackStatsGatherer<STATSTRUCT, CAPTUREDCALLSTACKLENGTH, STACKACQUISITIONFUNCTION, STATMUTEXHANDLER, TEMPLATIZEDMEMORYALLOCATOR>::GetFunctionTable( void )
{
static CCallStackStatsGatherer_FunctionTable_t retVal =
{ GetDumpInfo,
PushSubTree,
PopSubTree,
#if defined( ENABLE_STACK_STATS_GATHERING )
STATSTRUCT::DescribeCallStackStatStruct,
#else
NULL_DescribeCallStackStatStruct,
#endif
SyncMutexes,
GetEntry,
ApplyTreeAccessLock,
LockEntry };
return retVal;
}
template <class STATSTRUCT, size_t CAPTUREDCALLSTACKLENGTH, FN_GetCallStack STACKACQUISITIONFUNCTION, typename STATMUTEXHANDLER, template <typename T> class TEMPLATIZEDMEMORYALLOCATOR>
void CCallStackStatsGatherer<STATSTRUCT, CAPTUREDCALLSTACKLENGTH, STACKACQUISITIONFUNCTION, STATMUTEXHANDLER, TEMPLATIZEDMEMORYALLOCATOR>::GetDumpInfo( void *pThis, const char *&szStructName, size_t &iCapturedStackLength, size_t &iEntrySizeWithStack, void *&pEntries, size_t &iEntryCount, CCallStackStatsGatherer_Standardized_t *&pSubTrees, size_t &iSubTreeCount )
{
ThisCast *pThisCast = (ThisCast *)pThis;
iCapturedStackLength = CAPTUREDCALLSTACKLENGTH;
iEntrySizeWithStack = sizeof( CCallStackStatsGatherer<STATSTRUCT, CAPTUREDCALLSTACKLENGTH, STACKACQUISITIONFUNCTION, STATMUTEXHANDLER, TEMPLATIZEDMEMORYALLOCATOR>::StackAndStats_t );
#if defined( ENABLE_STACK_STATS_GATHERING )
szStructName = STATSTRUCT::STATSTRUCTSTRINGNAME;
iEntryCount = pThisCast->m_StatEntries.size();
pEntries = iEntryCount > 0 ? &pThisCast->m_StatEntries[0] : NULL;
iSubTreeCount = pThisCast->m_StoredSubTrees.size();
pSubTrees = iSubTreeCount > 0 ? &pThisCast->m_StoredSubTrees[0] : NULL;
#else
szStructName = "";
iEntryCount = 0;
pEntries = NULL;
iSubTreeCount = 0;
pSubTrees = NULL;
#endif
}
template <class STATSTRUCT, size_t CAPTUREDCALLSTACKLENGTH, FN_GetCallStack STACKACQUISITIONFUNCTION, typename STATMUTEXHANDLER, template <typename T> class TEMPLATIZEDMEMORYALLOCATOR>
void CCallStackStatsGatherer<STATSTRUCT, CAPTUREDCALLSTACKLENGTH, STACKACQUISITIONFUNCTION, STATMUTEXHANDLER, TEMPLATIZEDMEMORYALLOCATOR>::PushSubTree( void *pParent, const CCallStackStatsGatherer_Standardized_t &SubTree, const CCallStackStorage &PushStack )
{
#if defined( ENABLE_STACK_STATS_GATHERING )
ThisCast *pParentCast = (ThisCast *)pParent;
PushedSubTree_t pushVal;
pushVal.iThreadID = ThreadGetCurrentId();
pushVal.tree = SubTree;
memcpy( pushVal.Stack, PushStack.pStack, MIN( CAPTUREDCALLSTACKLENGTH, PushStack.iValidEntries ) * sizeof( void * ) );
for( int i = PushStack.iValidEntries; i < CAPTUREDCALLSTACKLENGTH; ++i )
{
pushVal.Stack[i] = NULL;
}
pParentCast->m_SubTreeMutex.Lock();
pParentCast->m_PushedSubTrees.push_back( pushVal );
pParentCast->m_SubTreeMutex.Unlock();
#endif
}
template <class STATSTRUCT, size_t CAPTUREDCALLSTACKLENGTH, FN_GetCallStack STACKACQUISITIONFUNCTION, typename STATMUTEXHANDLER, template <typename T> class TEMPLATIZEDMEMORYALLOCATOR>
void CCallStackStatsGatherer<STATSTRUCT, CAPTUREDCALLSTACKLENGTH, STACKACQUISITIONFUNCTION, STATMUTEXHANDLER, TEMPLATIZEDMEMORYALLOCATOR>::PushSubTree( CCallStackStatsGatherer_Standardized_t &Parent, const CCallStackStorage &PushStack )
{
#if defined( ENABLE_STACK_STATS_GATHERING )
CCallStackStatsGatherer_Standardized_t StandardThis = Standardized();
Parent.PushSubTree( StandardThis, PushStack );
#endif
}
template <class STATSTRUCT, size_t CAPTUREDCALLSTACKLENGTH, FN_GetCallStack STACKACQUISITIONFUNCTION, typename STATMUTEXHANDLER, template <typename T> class TEMPLATIZEDMEMORYALLOCATOR>
void CCallStackStatsGatherer<STATSTRUCT, CAPTUREDCALLSTACKLENGTH, STACKACQUISITIONFUNCTION, STATMUTEXHANDLER, TEMPLATIZEDMEMORYALLOCATOR>::PopSubTree( void *pParent )
{
#if defined( ENABLE_STACK_STATS_GATHERING )
ThisCast *pParentCast = (ThisCast *)pParent;
pParentCast->m_SubTreeMutex.Lock();
unsigned long iThreadID = ThreadGetCurrentId();
for( typename PushedSubTreeVector_t::reverse_iterator treeIter = pParentCast->m_PushedSubTrees.rbegin(); treeIter != pParentCast->m_PushedSubTrees.rend(); ++treeIter )
{
if( treeIter->iThreadID == iThreadID )
{
++treeIter; //[24.4.1/1] &*(reverse_iterator(i)) == &*(i - 1)
typename PushedSubTreeVector_t::iterator eraseIter = treeIter.base();
pParentCast->m_PushedSubTrees.erase(eraseIter);
break;
}
}
pParentCast->m_SubTreeMutex.Unlock();
#endif
}
template <class STATSTRUCT, size_t CAPTUREDCALLSTACKLENGTH, FN_GetCallStack STACKACQUISITIONFUNCTION, typename STATMUTEXHANDLER, template <typename T> class TEMPLATIZEDMEMORYALLOCATOR>
void CCallStackStatsGatherer<STATSTRUCT, CAPTUREDCALLSTACKLENGTH, STACKACQUISITIONFUNCTION, STATMUTEXHANDLER, TEMPLATIZEDMEMORYALLOCATOR>::SyncMutexes( void *pParent, bool bLock ) //true for lock, false for unlock
{
#if defined( ENABLE_STACK_STATS_GATHERING )
ThisCast *pParentCast = (ThisCast *)pParent;
if( bLock )
{
pParentCast->m_IndexMapMutex.Lock();
pParentCast->m_SubTreeMutex.Lock();
for( typename StoredSubTreeVector_t::iterator treeIter = pParentCast->m_StoredSubTrees.begin(); treeIter != pParentCast->m_StoredSubTrees.end(); ++treeIter )
{
treeIter->pFunctionTable->pfn_SyncMutexes( treeIter->pGatherer, true );
}
}
else
{
for( typename StoredSubTreeVector_t::iterator treeIter = pParentCast->m_StoredSubTrees.begin(); treeIter != pParentCast->m_StoredSubTrees.end(); ++treeIter )
{
treeIter->pFunctionTable->pfn_SyncMutexes( treeIter->pGatherer, false );
}
pParentCast->m_IndexMapMutex.Unlock();
pParentCast->m_SubTreeMutex.Unlock();
}
#endif
}
template <class STATSTRUCT, size_t CAPTUREDCALLSTACKLENGTH, FN_GetCallStack STACKACQUISITIONFUNCTION, typename STATMUTEXHANDLER, template <typename T> class TEMPLATIZEDMEMORYALLOCATOR>
void *CCallStackStatsGatherer<STATSTRUCT, CAPTUREDCALLSTACKLENGTH, STACKACQUISITIONFUNCTION, STATMUTEXHANDLER, TEMPLATIZEDMEMORYALLOCATOR>::GetEntry( void *pParent, uint32 iEntryIndex )
{
ThisCast *pParentCast = (ThisCast *)pParent;
#if defined( ENABLE_STACK_STATS_GATHERING )
return &pParentCast->m_StatEntries[iEntryIndex].m_Stats;
#else
return &pParentCast->m_SingleEntry;
#endif
}
template <class STATSTRUCT, size_t CAPTUREDCALLSTACKLENGTH, FN_GetCallStack STACKACQUISITIONFUNCTION, typename STATMUTEXHANDLER, template <typename T> class TEMPLATIZEDMEMORYALLOCATOR>
void CCallStackStatsGatherer<STATSTRUCT, CAPTUREDCALLSTACKLENGTH, STACKACQUISITIONFUNCTION, STATMUTEXHANDLER, TEMPLATIZEDMEMORYALLOCATOR>::ApplyTreeAccessLock( void *pParent, bool bLock )
{
#if defined( ENABLE_STACK_STATS_GATHERING )
ThisCast *pParentCast = (ThisCast *)pParent;
if( bLock )
{
pParentCast->m_StatEntryLock.LockForRead();
}
else
{
pParentCast->m_StatEntryLock.UnlockRead();
}
#endif
}
template <class STATSTRUCT, size_t CAPTUREDCALLSTACKLENGTH, FN_GetCallStack STACKACQUISITIONFUNCTION, typename STATMUTEXHANDLER, template <typename T> class TEMPLATIZEDMEMORYALLOCATOR>
void CCallStackStatsGatherer<STATSTRUCT, CAPTUREDCALLSTACKLENGTH, STACKACQUISITIONFUNCTION, STATMUTEXHANDLER, TEMPLATIZEDMEMORYALLOCATOR>::LockEntry( void *pParent, uint32 iEntryIndex, bool bLock )
{
#if defined( ENABLE_STACK_STATS_GATHERING )
ThisCast *pParentCast = (ThisCast *)pParent;
pParentCast->STATMUTEXHANDLER::LockEntry( iEntryIndex, bLock );
#endif
}
template <class STATSTRUCT, size_t CAPTUREDCALLSTACKLENGTH, FN_GetCallStack STACKACQUISITIONFUNCTION, typename STATMUTEXHANDLER, template <typename T> class TEMPLATIZEDMEMORYALLOCATOR>
void CCallStackStatsGatherer<STATSTRUCT, CAPTUREDCALLSTACKLENGTH, STACKACQUISITIONFUNCTION, STATMUTEXHANDLER, TEMPLATIZEDMEMORYALLOCATOR>::Reset( void )
{
#if defined( ENABLE_STACK_STATS_GATHERING )
m_StatEntryLock.LockForWrite();
m_IndexMapMutex.Lock();
m_SubTreeMutex.Lock();
m_StatEntries.clear();
m_IndexMap.clear();
m_StoredSubTrees.clear();
m_SubTreeMutex.Unlock();
m_IndexMapMutex.Unlock();
m_StatEntryLock.UnlockWrite();
#endif
}
template <class STATSTRUCT, size_t CAPTUREDCALLSTACKLENGTH, FN_GetCallStack STACKACQUISITIONFUNCTION, typename STATMUTEXHANDLER, template <typename T> class TEMPLATIZEDMEMORYALLOCATOR>
CCallStackStatsGatherer<STATSTRUCT, CAPTUREDCALLSTACKLENGTH, STACKACQUISITIONFUNCTION, STATMUTEXHANDLER, TEMPLATIZEDMEMORYALLOCATOR>::operator CCallStackStatsGatherer_Standardized_t( void )
{
return CCallStackStatsGatherer_Standardized_t( this, GetFunctionTable() );
}
template <class STATSTRUCT, size_t CAPTUREDCALLSTACKLENGTH, FN_GetCallStack STACKACQUISITIONFUNCTION, typename STATMUTEXHANDLER, template <typename T> class TEMPLATIZEDMEMORYALLOCATOR>
CCallStackStatsGatherer_Standardized_t CCallStackStatsGatherer<STATSTRUCT, CAPTUREDCALLSTACKLENGTH, STACKACQUISITIONFUNCTION, STATMUTEXHANDLER, TEMPLATIZEDMEMORYALLOCATOR>::Standardized( void )
{
return CCallStackStatsGatherer_Standardized_t( this, GetFunctionTable() );
}
class PLATFORM_CLASS CallStackStatStructDescFuncs
{
public:
//description file format
//1 byte version per entry. Assuming that the field will get more descriptive over time, reserving this now.
virtual size_t DescribeField( uint8 *pDescribeWriteBuffer, size_t iDescribeMaxLength ) = 0;
enum MergeScript_Language
{
SSMSL_Squirrel, //Only support squirrel for now, theoretically expandable to any vscript supported language
};
#if 0 //embedded script handling not ready yet
//this is expected to write a piece of script code into the body of a function that will merge two values of this type
//The function will have two parameters, "mergeTo", and "mergeFrom". Both are tables with your field defined by name
//So, an example to merge an integer count defined as "foo" in the stack struct would look like this "mergeTo.foo += mergeFrom.foo\n"
virtual size_t DescribeMergeOperation( MergeScript_Language scriptLanguage, uint8 *pDescribeWriteBuffer, size_t iDescribeMaxLength ) = 0;
#endif
//reserve your description field versions here to avoid stomping others
enum DescribeFieldVersions_t
{
DFV_BasicStatStructFieldTypes_t, //Format: 1 byte BasicStatStructFieldTypes_t type, 4 byte field offset, null terminated string field name
};
const char *m_szFieldName;
size_t m_iFieldOffset;
CallStackStatStructDescFuncs *m_pNext; //needed for how the description macros are laid out. Couldn't figure out a way to store the static struct instances as a static array
};
enum StatStructDescription_LumpID
{
SSDLID_UNKNOWN,
SSDLID_STATICINTERPRETER,
SSDLID_FIELDDESC,
SSDLID_EMBEDDEDSCRIPT,
SSDLID_COUNT,
SSDLID_FORCE_UINT32 = 0xFFFFFFFF,
};
enum BasicStatStructFieldTypes_t
{
BSSFT_UNKNOWN,
BSSFT_BOOL,
BSSFT_INT8,
BSSFT_UINT8,
BSSFT_INT16,
BSSFT_UINT16,
BSSFT_INT32,
BSSFT_UINT32,
BSSFT_INT64,
BSSFT_UINT64,
BSSFT_FLOAT,
BSSFT_DOUBLE,
BSSFT_VECTOR2D,
BSSFT_VECTOR3D,
BSSFT_VECTOR4D,
BSSFT_COUNT,
};
#define BSSFT_INT (sizeof( int ) == sizeof( int32 ) ? BSSFT_INT32 : BSSFT_INT64)
#define BSSFT_UINT (sizeof( unsigned int ) == sizeof( uint32 ) ? BSSFT_UINT32 : BSSFT_UINT64)
#define BSSFT_SIZE_T (sizeof( size_t ) == sizeof( uint32 ) ? BSSFT_UINT32 : BSSFT_UINT64)
enum BasicStatStructFieldCombineMethods_t
{
BSSFCM_UNKNOWN,
BSSFCM_CUSTOM, //rely on some outside handler
BSSFCM_ADD, //add the values
//BSSFCM_SUBTRACT, //what would subtract even mean? which one from which?
BSSFCM_MAX, //keep max value
BSSFCM_MIN, //keep min value
BSSFCM_AND, // &= , Non-integer behavior undefined
BSSFCM_OR, // |= , Non-integer behavior undefined
BSSFCM_XOR, // ^= , Non-integer behavior undefined
/*BSSFCM_LIST, //keep a list of each value (probably complicated)*/
BSSFCM_COUNT,
};
class PLATFORM_CLASS BasicStatStructFieldDesc : public CallStackStatStructDescFuncs
{
public:
BasicStatStructFieldDesc( BasicStatStructFieldTypes_t type, BasicStatStructFieldCombineMethods_t combineMethod ) : m_Type(type), m_Combine(combineMethod) {};
size_t DescribeField( uint8 *pDescribeWriteBuffer, size_t iDescribeMaxLength );
#if 0 //embedded script handling not ready yet
size_t DescribeMergeOperation( MergeScript_Language scriptLanguage, uint8 *pDescribeWriteBuffer, size_t iDescribeMaxLength );
#endif
BasicStatStructFieldTypes_t m_Type;
BasicStatStructFieldCombineMethods_t m_Combine;
};
//struct is locked in place while you're holding onto one of these. Get a base, then create one of these from it
template <class STATSTRUCT>
class CCallStackStatsGatherer_StructAccessor_AutoLock : CCallStackStatsGatherer_StructAccessor_Base<STATSTRUCT>
{
public:
CCallStackStatsGatherer_StructAccessor_AutoLock( CCallStackStatsGatherer_StructAccessor_Base<STATSTRUCT> &copyFrom )
: CCallStackStatsGatherer_StructAccessor_Base<STATSTRUCT>( copyFrom )
{
this->m_Gatherer.pFunctionTable->pfn_ApplyTreeAccessLock( this->m_Gatherer.pGatherer, true );
this->m_Gatherer.pFunctionTable->pfn_LockEntry( this->m_Gatherer.pGatherer, this->m_iEntryIndex, true );
this->m_pStruct = (STATSTRUCT *)this->m_Gatherer.pFunctionTable->pfn_GetEntry( this->m_Gatherer.pGatherer, this->m_iEntryIndex );
}
~CCallStackStatsGatherer_StructAccessor_AutoLock( void )
{
this->m_Gatherer.pFunctionTable->pfn_LockEntry( this->m_Gatherer.pGatherer, this->m_iEntryIndex, false );
this->m_Gatherer.pFunctionTable->pfn_ApplyTreeAccessLock( this->m_Gatherer.pGatherer, false );
}
STATSTRUCT *operator->()
{
return this->m_pStruct;
}
STATSTRUCT *GetStruct( void ) //do not hold this pointer outside the lock period
{
return this->m_pStruct;
}
protected:
STATSTRUCT *m_pStruct;
};
//struct is locked in place only between Lock() and paired Unlock() calls. Get a base, then create one of these from it.
//It's safe to hold onto this for an extended period of time. The entry index is unchanging in the gatherer tree.
template <class STATSTRUCT>
class CCallStackStatsGatherer_StructAccessor_Manual : CCallStackStatsGatherer_StructAccessor_Base<STATSTRUCT>
{
public:
CCallStackStatsGatherer_StructAccessor_Manual( CCallStackStatsGatherer_StructAccessor_Base<STATSTRUCT> &copyFrom )
: CCallStackStatsGatherer_StructAccessor_Base<STATSTRUCT>( copyFrom ), m_pStruct( NULL )
{ }
STATSTRUCT *operator->()
{
return this->m_pStruct; //NULL while entry is not locked.
}
STATSTRUCT *GetStruct( void ) //do not hold this pointer outside the lock period
{
return this->m_pStruct; //NULL while entry is not locked.
}
void Lock( void )
{
this->m_Gatherer.pFunctionTable->pfn_ApplyTreeAccessLock( this->m_Gatherer.pGatherer, true );
this->m_Gatherer.pFunctionTable->pfn_LockEntry( this->m_Gatherer.pGatherer, this->m_iEntryIndex, true );
this->m_pStruct = (STATSTRUCT *)this->m_Gatherer.pFunctionTable->pfn_GetEntry( this->m_Gatherer.pGatherer, this->m_iEntryIndex );
}
void Unlock( void )
{
this->m_pStruct = NULL;
this->m_Gatherer.pFunctionTable->pfn_LockEntry( this->m_Gatherer.pGatherer, this->m_iEntryIndex, false );
this->m_Gatherer.pFunctionTable->pfn_ApplyTreeAccessLock( this->m_Gatherer.pGatherer, false );
}
protected:
STATSTRUCT *m_pStruct;
};
class CCallStackStats_PushSubTree_AutoPop
{
public:
CCallStackStats_PushSubTree_AutoPop( const CCallStackStatsGatherer_Standardized_t &Parent, const CCallStackStatsGatherer_Standardized_t &Child, const CCallStackStorage &PushStack = CCallStackStorage() )
: m_PopFrom( Parent )
{
Parent.pFunctionTable->pfn_PushSubTree( Parent.pGatherer, Child, PushStack );
}
~CCallStackStats_PushSubTree_AutoPop( void )
{
m_PopFrom.PopSubTree();
}
CCallStackStatsGatherer_Standardized_t m_PopFrom;
};
#endif //#ifndef TIER0_STACKTOOLS_H

153
external/vpc/public/tier0/stacktools.h vendored Normal file
View File

@@ -0,0 +1,153 @@
//========= Copyright <20> 1996-2008, Valve Corporation, All rights reserved. ============//
//
// Purpose: Tools for grabbing/dumping the stack at runtime
//
// $NoKeywords: $
//=============================================================================//
#ifndef TIER0_STACKTOOLS_H
#define TIER0_STACKTOOLS_H
#ifdef _WIN32
#pragma once
#endif
#include "tier0/platform.h"
#if (defined( PLATFORM_WINDOWS ) || defined( PLATFORM_X360 )) && !defined( STEAM ) && !defined( _CERT ) && defined( TCHAR_IS_CHAR ) //designed for windows/x360, not built/tested with wide characters, not intended for release builds (but probably wouldn't damage anything)
# define ENABLE_RUNTIME_STACK_TRANSLATION //uncomment to enable runtime stack translation tools. All of which use on-demand loading of necessary dll's and pdb's
#endif
#if defined( ENABLE_RUNTIME_STACK_TRANSLATION )
//#define ENABLE_THREAD_PARENT_STACK_TRACING 1 //uncomment to actually enable tracking stack traces from threads and jobs to their parent thread. Must also define THREAD_PARENT_STACK_TRACE_SUPPORTED in threadtools.h
# if defined( ENABLE_THREAD_PARENT_STACK_TRACING )
# define THREAD_PARENT_STACK_TRACE_LENGTH 32
# endif
#endif
PLATFORM_INTERFACE int GetCallStack( void **pReturnAddressesOut, int iArrayCount, int iSkipCount );
//ONLY WORKS IF THE CRAWLED PORTION OF THE STACK DISABLES FRAME POINTER OMISSION (/Oy-) "vpc /nofpo"
PLATFORM_INTERFACE int GetCallStack_Fast( void **pReturnAddressesOut, int iArrayCount, int iSkipCount );
typedef int (*FN_GetCallStack)( void **pReturnAddressesOut, int iArrayCount, int iSkipCount );
//where we'll find our PDB's for win32.
PLATFORM_INTERFACE void SetStackTranslationSymbolSearchPath( const char *szSemicolonSeparatedList = NULL );
PLATFORM_INTERFACE void StackToolsNotify_LoadedLibrary( const char *szLibName );
//maximum output sample "tier0.dll!TranslateStackInfo - u:\Dev\L4D\src\tier0\stacktools.cpp(162) + 4 bytes"
enum TranslateStackInfo_StyleFlags_t
{
TSISTYLEFLAG_NONE = 0,
TSISTYLEFLAG_MODULENAME = (1<<0), //start with module Sample: "tier0.dll!"
TSISTYLEFLAG_SYMBOLNAME = (1<<1), //include the symbol name Sample: "TranslateStackInfo"
TSISTYLEFLAG_FULLPATH = (1<<2), //include full path Sample: "u:\Dev\L4D\src\tier0\stacktools.cpp"
TSISTYLEFLAG_SHORTPATH = (1<<3), //only include 2 directories Sample: "\src\tier0\stacktools.cpp"
TSISTYLEFLAG_LINE = (1<<4), //file line number Sample: "(162)"
TSISTYLEFLAG_LINEANDOFFSET = (1<<5), //file line + offset Sample: "(162) + 4 bytes"
TSISTYLEFLAG_LAST = TSISTYLEFLAG_LINEANDOFFSET,
TSISTYLEFLAG_DEFAULT = (TSISTYLEFLAG_MODULENAME | TSISTYLEFLAG_SYMBOLNAME | TSISTYLEFLAG_FULLPATH | TSISTYLEFLAG_LINEANDOFFSET), //produces sample above
};
//Generates a formatted list of function information, returns number of translated entries
//On 360 this generates a string that can be decoded by VXConsole in print functions. Optimal path for translation because it's one way. Other paths require multiple transactions.
PLATFORM_INTERFACE int TranslateStackInfo( const void * const *pCallStack, int iCallStackCount, tchar *szOutput, int iOutBufferSize, const tchar *szEntrySeparator, TranslateStackInfo_StyleFlags_t style = TSISTYLEFLAG_DEFAULT );
PLATFORM_INTERFACE void PreloadStackInformation( void * const *pAddresses, int iAddressCount ); //caches data and reduces communication with VXConsole to speed up 360 decoding when using any of the Get***FromAddress() functions. Nop on PC.
PLATFORM_INTERFACE bool GetFileAndLineFromAddress( const void *pAddress, tchar *pFileNameOut, int iMaxFileNameLength, uint32 &iLineNumberOut, uint32 *pDisplacementOut = NULL );
PLATFORM_INTERFACE bool GetSymbolNameFromAddress( const void *pAddress, tchar *pSymbolNameOut, int iMaxSymbolNameLength, uint64 *pDisplacementOut = NULL );
PLATFORM_INTERFACE bool GetModuleNameFromAddress( const void *pAddress, tchar *pModuleNameOut, int iMaxModuleNameLength );
class PLATFORM_CLASS CCallStackStorage //a helper class to grab a stack trace as close to the leaf code surface as possible, then pass it on to deeper functions intact with less unpredictable inlining pollution
{
public:
CCallStackStorage( FN_GetCallStack GetStackFunction = GetCallStack, uint32 iSkipCalls = 0 );
CCallStackStorage( const CCallStackStorage &copyFrom )
{
iValidEntries = copyFrom.iValidEntries;
memcpy( pStack, copyFrom.pStack, sizeof( void * ) * copyFrom.iValidEntries );
}
void *pStack[128]; //probably too big, possibly too small for some applications. Don't want to spend the time figuring out how to generalize this without templatizing pollution or mallocs
uint32 iValidEntries;
};
//Hold onto one of these to denote the top of a functional stack trace. Also allows us to string together threads to their parents
class PLATFORM_CLASS CStackTop_Base
{
protected:
#if defined( ENABLE_RUNTIME_STACK_TRANSLATION )
CStackTop_Base *m_pPrevTop;
void *m_pStackBase;
void *m_pReplaceAddress;
void * const *m_pParentStackTrace;
int m_iParentStackTraceLength;
#endif
};
//makes a copy of the parent stack
class PLATFORM_CLASS CStackTop_CopyParentStack : public CStackTop_Base
{
public:
CStackTop_CopyParentStack( void * const * pParentStackTrace, int iParentStackTraceLength );
~CStackTop_CopyParentStack( void );
};
//just references the parent stack. Assuming that you'll keep that memory around as long as you're keeping this Stack Top marker.
class PLATFORM_CLASS CStackTop_ReferenceParentStack : public CStackTop_Base
{
public:
CStackTop_ReferenceParentStack( void * const * pParentStackTrace = NULL, int iParentStackTraceLength = 0 );
~CStackTop_ReferenceParentStack( void );
void ReleaseParentStackReferences( void ); //in case you need to delete the parent stack trace before this class goes out of scope
};
//Encodes data so that every byte's most significant bit is a 1. Ensuring no null terminators.
//This puts the encoded data in the 128-255 value range. Leaving all standard ascii characters for control.
//Returns string length (not including the written null terminator as is standard).
//Or if the buffer is too small. Returns negative of necessary buffer size (including room needed for null terminator)
PLATFORM_INTERFACE int EncodeBinaryToString( const void *pToEncode, int iDataLength, char *pEncodeOut, int iEncodeBufferSize );
//Decodes a string produced by EncodeBinaryToString(). Safe to decode in place if you don't mind trashing your string, binary byte count always less than string byte count.
//Returns:
// >= 0 is the decoded data size
// INT_MIN (most negative value possible) indicates an improperly formatted string (not our data)
// all other negative values are the negative of how much dest buffer size is necessary.
PLATFORM_INTERFACE int DecodeBinaryFromString( const char *pString, void *pDestBuffer, int iDestBufferSize, char **ppParseFinishOut = NULL );
// 360<->VXConsole specific communication definitions
#define XBX_CALLSTACKDECODEPREFIX ":CSDECODE["
enum StackTranslation_BinaryHandler_Command_t
{
ST_BHC_LOADEDLIBARY,
ST_BHC_GETTRANSLATIONINFO,
};
#pragma pack(push)
#pragma pack(1)
struct FullStackInfo_t
{
const void *pAddress;
char szModuleName[24];
char szFileName[MAX_PATH/2];
char szSymbol[64];
uint32 iLine;
uint32 iSymbolOffset;
};
#pragma pack(pop)
#endif //#ifndef TIER0_STACKTOOLS_H

2402
external/vpc/public/tier0/threadtools.h vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,630 @@
#ifndef THREADTOOLS_INL
#define THREADTOOLS_INL
// This file is included in threadtools.h for PS3 and threadtools.cpp for all other platforms
//
// Do not #include other files here
#ifndef _PS3
// this is defined in the .cpp for the PS3 to avoid introducing a dependency for files including the header
CTHREADLOCALPTR(CThread) g_pCurThread;
#define INLINE_ON_PS3
#else
// Inlining these functions on PS3 (which are called across PRX boundaries) saves us over 1ms per frame
#define INLINE_ON_PS3 inline
#endif
INLINE_ON_PS3 CThread::CThread() :
#ifdef _WIN32
m_hThread( NULL ),
m_threadId( 0 ),
#elif defined( _PS3 ) || defined(_POSIX)
m_threadId( 0 ),
m_threadZombieId( 0 ) ,
#endif
m_result( 0 ),
m_pStackBase( NULL ),
m_flags( 0 )
{
m_szName[0] = 0;
m_NotSuspendedEvent.Set();
}
//---------------------------------------------------------
INLINE_ON_PS3 CThread::~CThread()
{
#ifdef MSVC
if (m_hThread)
#elif defined(POSIX) && !defined( _PS3 )
if ( m_threadId )
#endif
{
if ( IsAlive() )
{
Msg( "Illegal termination of worker thread! Threads must negotiate an end to the thread before the CThread object is destroyed.\n" );
#ifdef _WIN32
DoNewAssertDialog( __FILE__, __LINE__, "Illegal termination of worker thread! Threads must negotiate an end to the thread before the CThread object is destroyed.\n" );
#endif
if ( GetCurrentCThread() == this )
{
Stop(); // BUGBUG: Alfred - this doesn't make sense, this destructor fires from the hosting thread not the thread itself!!
}
}
}
#if defined(POSIX) || defined( _PS3 )
if ( m_threadZombieId )
{
// just clean up zombie threads immediately (the destructor is fired from the hosting thread)
Join();
}
#endif
}
//---------------------------------------------------------
INLINE_ON_PS3 const char *CThread::GetName()
{
AUTO_LOCK( m_Lock );
if ( !m_szName[0] )
{
#if defined( _WIN32 )
_snprintf( m_szName, sizeof(m_szName) - 1, "Thread(%p/%p)", this, m_hThread );
#elif defined( _PS3 )
snprintf( m_szName, sizeof(m_szName) - 1, "Thread(%p)", this );
#elif defined( POSIX )
_snprintf( m_szName, sizeof(m_szName) - 1, "Thread(%p/0x%x)", this, (uint)m_threadId );
#endif
m_szName[sizeof(m_szName) - 1] = 0;
}
return m_szName;
}
//---------------------------------------------------------
INLINE_ON_PS3 void CThread::SetName(const char *pszName)
{
AUTO_LOCK( m_Lock );
strncpy( m_szName, pszName, sizeof(m_szName) - 1 );
m_szName[sizeof(m_szName) - 1] = 0;
}
//-----------------------------------------------------
// Functions for the other threads
//-----------------------------------------------------
// Start thread running - error if already running
INLINE_ON_PS3 bool CThread::Start( unsigned nBytesStack, ThreadPriorityEnum_t nPriority )
{
AUTO_LOCK( m_Lock );
if ( IsAlive() )
{
AssertMsg( 0, "Tried to create a thread that has already been created!" );
return false;
}
bool bInitSuccess = false;
CThreadEvent createComplete;
ThreadInit_t init = { this, &createComplete, &bInitSuccess };
#if defined( THREAD_PARENT_STACK_TRACE_ENABLED )
{
int iValidEntries = GetCallStack_Fast( init.ParentStackTrace, ARRAYSIZE( init.ParentStackTrace ), 0 );
for( int i = iValidEntries; i < ARRAYSIZE( init.ParentStackTrace ); ++i )
{
init.ParentStackTrace[i] = NULL;
}
}
#endif
#ifdef PLATFORM_WINDOWS
m_hThread = (HANDLE)CreateThread( NULL,
nBytesStack,
(LPTHREAD_START_ROUTINE)GetThreadProc(),
new ThreadInit_t(init),
0,
(LPDWORD)&m_threadId );
if( nPriority != PRIORITY_DEFAULT )
{
SetThreadPriority( m_hThread, nPriority );
}
if ( !m_hThread )
{
AssertMsg1( 0, "Failed to create thread (error 0x%x)", GetLastError() );
return false;
}
#elif PLATFORM_PS3
// On the PS3, a stack size of 0 doesn't imply a default stack size, so we need to force it to our
// own default size.
if ( nBytesStack == 0 )
{
nBytesStack = PS3_SYS_PPU_THREAD_COMMON_STACK_SIZE;
}
//The thread is about to begin
m_threadEnd.Reset();
// sony documentation:
// "If the PPU thread is not joined by sys_ppu_thread_join() after exit,
// it should always be created as non-joinable (not specifying
// SYS_PPU_THREAD_CREATE_JOINABLE). Otherwise, some resources are left
// allocated after termination of the PPU thread as if memory leaks."
const char* threadName=m_szName;
if ( sys_ppu_thread_create( &m_threadId,
(void(*)(uint64_t))GetThreadProc(),
(uint64_t)(new ThreadInit_t( init )),
nPriority,
nBytesStack,
SYS_PPU_THREAD_CREATE_JOINABLE ,
threadName ) != CELL_OK )
{
AssertMsg1( 0, "Failed to create thread (error 0x%x)", errno );
return false;
}
bInitSuccess = true;
#elif PLATFORM_POSIX
pthread_attr_t attr;
pthread_attr_init( &attr );
pthread_attr_setstacksize( &attr, MAX( nBytesStack, 1024u*1024 ) );
if ( pthread_create( &m_threadId, &attr, (void *(*)(void *))GetThreadProc(), new ThreadInit_t( init ) ) != 0 )
{
AssertMsg1( 0, "Failed to create thread (error 0x%x)", GetLastError() );
return false;
}
bInitSuccess = true;
#endif
if ( !WaitForCreateComplete( &createComplete ) )
{
Msg( "Thread failed to initialize\n" );
#ifdef _WIN32
CloseHandle( m_hThread );
m_hThread = NULL;
#elif defined( _PS3 )
m_threadEnd.Set();
m_threadId = NULL;
m_threadZombieId = 0;
#endif
return false;
}
if ( !bInitSuccess )
{
Msg( "Thread failed to initialize\n" );
#ifdef _WIN32
CloseHandle( m_hThread );
m_hThread = NULL;
#elif defined(POSIX) && !defined( _PS3 )
m_threadId = 0;
m_threadZombieId = 0;
#endif
return false;
}
#ifdef _WIN32
if ( !m_hThread )
{
Msg( "Thread exited immediately\n" );
}
#endif
#ifdef _WIN32
AddThreadHandleToIDMap( m_hThread, m_threadId );
return !!m_hThread;
#elif defined(POSIX)
return !!m_threadId;
#endif
}
//---------------------------------------------------------
//
// Return true if the thread has been created and hasn't yet exited
//
INLINE_ON_PS3 bool CThread::IsAlive()
{
#ifdef PLATFORM_WINDOWS
DWORD dwExitCode;
return (
m_hThread
&& GetExitCodeThread(m_hThread, &dwExitCode)
&& dwExitCode == STILL_ACTIVE );
#elif defined(POSIX)
return !!m_threadId;
#endif
}
// This method causes the current thread to wait until this thread
// is no longer alive.
INLINE_ON_PS3 bool CThread::Join( unsigned timeout )
{
#ifdef _WIN32
if ( m_hThread )
#elif defined(POSIX)
if ( m_threadId || m_threadZombieId )
#endif
{
AssertMsg(GetCurrentCThread() != this, _T("Thread cannot be joined with self"));
#ifdef _WIN32
return ThreadJoin( (ThreadHandle_t)m_hThread, timeout );
#elif defined(POSIX)
bool ret = ThreadJoin( (ThreadHandle_t)(m_threadId ? m_threadId : m_threadZombieId), timeout );
m_threadZombieId = 0;
return ret;
#endif
}
return true;
}
//---------------------------------------------------------
INLINE_ON_PS3 ThreadHandle_t CThread::GetThreadHandle()
{
#ifdef _WIN32
return (ThreadHandle_t)m_hThread;
#else
return (ThreadHandle_t)m_threadId;
#endif
}
//---------------------------------------------------------
INLINE_ON_PS3 int CThread::GetResult()
{
return m_result;
}
//-----------------------------------------------------
// Functions for both this, and maybe, and other threads
//-----------------------------------------------------
// Forcibly, abnormally, but relatively cleanly stop the thread
//
INLINE_ON_PS3 void CThread::Stop(int exitCode)
{
if ( !IsAlive() )
return;
if ( GetCurrentCThread() == this )
{
#if !defined( _PS3 )
m_result = exitCode;
if ( !( m_flags & SUPPORT_STOP_PROTOCOL ) )
{
OnExit();
g_pCurThread = NULL;
#ifdef _WIN32
CloseHandle( m_hThread );
RemoveThreadHandleToIDMap( m_hThread );
m_hThread = NULL;
#else
m_threadId = 0;
m_threadZombieId = 0;
#endif
}
else
{
throw exitCode;
}
#else
AssertMsg( false, "Called CThread::Stop() for a platform that doesn't have it!\n");
#endif
}
else
AssertMsg( 0, "Only thread can stop self: Use a higher-level protocol");
}
//---------------------------------------------------------
// Get the priority
INLINE_ON_PS3 int CThread::GetPriority() const
{
#ifdef _WIN32
return GetThreadPriority(m_hThread);
#elif defined( _PS3 )
return ThreadGetPriority( (ThreadHandle_t) m_threadId );
#elif defined(POSIX)
struct sched_param thread_param;
int policy;
pthread_getschedparam( m_threadId, &policy, &thread_param );
return thread_param.sched_priority;
#endif
}
//---------------------------------------------------------
// Set the priority
INLINE_ON_PS3 bool CThread::SetPriority(int priority)
{
#ifdef WIN32
return ThreadSetPriority( (ThreadHandle_t)m_hThread, priority );
#else
return ThreadSetPriority( (ThreadHandle_t)m_threadId, priority );
#endif
}
//---------------------------------------------------------
// Suspend a thread
INLINE_ON_PS3 unsigned CThread::Suspend()
{
AssertMsg( ThreadGetCurrentId() == (ThreadId_t)m_threadId, "Cannot call CThread::Suspend from outside thread" );
if ( ThreadGetCurrentId() != (ThreadId_t)m_threadId )
{
DebuggerBreakIfDebugging();
}
m_NotSuspendedEvent.Reset();
m_NotSuspendedEvent.Wait();
return 0;
}
//---------------------------------------------------------
INLINE_ON_PS3 unsigned CThread::Resume()
{
if ( m_NotSuspendedEvent.Check() )
{
DevWarning( "Called Resume() on a thread that is not suspended!\n" );
}
m_NotSuspendedEvent.Set();
return 0;
}
//---------------------------------------------------------
// Force hard-termination of thread. Used for critical failures.
INLINE_ON_PS3 bool CThread::Terminate(int exitCode)
{
#if defined( _X360 )
AssertMsg( 0, "Cannot terminate a thread on the Xbox!" );
return false;
#elif defined( _WIN32 )
// I hope you know what you're doing!
if (!TerminateThread(m_hThread, exitCode))
return false;
CloseHandle( m_hThread );
RemoveThreadHandleToIDMap( m_hThread );
m_hThread = NULL;
#elif defined( _PS3 )
m_threadEnd.Set();
m_threadId = NULL;
#elif defined(POSIX)
pthread_kill( m_threadId, SIGKILL );
m_threadId = 0;
#endif
return true;
}
//-----------------------------------------------------
// Global methods
//-----------------------------------------------------
// Get the Thread object that represents the current thread, if any.
// Can return NULL if the current thread was not created using
// CThread
//
INLINE_ON_PS3 CThread *CThread::GetCurrentCThread()
{
#ifdef _PS3
return GetCurThreadPS3();
#else
return g_pCurThread;
#endif
}
//---------------------------------------------------------
//
// Offer a context switch. Under Win32, equivalent to Sleep(0)
//
#ifdef Yield
#undef Yield
#endif
INLINE_ON_PS3 void CThread::Yield()
{
#ifdef _WIN32
::Sleep(0);
#elif defined( _PS3 )
// sys_ppu_thread_yield doesn't seem to function properly, so sleep instead.
sys_timer_usleep( 60 );
#elif defined(POSIX)
pthread_yield();
#endif
}
//---------------------------------------------------------
//
// This method causes the current thread to yield and not to be
// scheduled for further execution until a certain amount of real
// time has elapsed, more or less. Duration is in milliseconds
INLINE_ON_PS3 void CThread::Sleep( unsigned duration )
{
#ifdef _WIN32
::Sleep(duration);
#elif defined (_PS3)
sys_timer_usleep( duration * 1000 );
#elif defined(POSIX)
usleep( duration * 1000 );
#endif
}
//---------------------------------------------------------
// Optional pre-run call, with ability to fail-create. Note Init()
// is forced synchronous with Start()
INLINE_ON_PS3 bool CThread::Init()
{
return true;
}
//---------------------------------------------------------
#if defined( _PS3 )
INLINE_ON_PS3 int CThread::Run()
{
return -1;
}
#endif // _PS3
// Called when the thread exits
INLINE_ON_PS3 void CThread::OnExit() { }
// Allow for custom start waiting
INLINE_ON_PS3 bool CThread::WaitForCreateComplete( CThreadEvent *pEvent )
{
// Force serialized thread creation...
if (!pEvent->Wait(60000))
{
AssertMsg( 0, "Probably deadlock or failure waiting for thread to initialize." );
return false;
}
return true;
}
//---------------------------------------------------------
INLINE_ON_PS3 CThread::ThreadProc_t CThread::GetThreadProc()
{
return ThreadProc;
}
#ifdef PLATFORM_WINDOWS
unsigned long STDCALL CThread::ThreadProc(LPVOID pv)
#else
INLINE_ON_PS3 void* CThread::ThreadProc(LPVOID pv)
#endif
{
#if defined( POSIX ) || defined( _PS3 )
ThreadInit_t *pInit = reinterpret_cast<ThreadInit_t*>(pv);
#else
std::unique_ptr<ThreadInit_t> pInit((ThreadInit_t *)pv);
#endif
#ifdef _X360
// Make sure all threads are consistent w.r.t floating-point math
SetupFPUControlWord();
#endif
AllocateThreadID();
CThread *pThread = pInit->pThread;
#ifdef _PS3
SetCurThreadPS3( pThread );
#else
g_pCurThread = pThread;
#endif
pThread->m_pStackBase = AlignValue( &pThread, 4096 );
pInit->pThread->m_result = -1;
#if defined( THREAD_PARENT_STACK_TRACE_ENABLED )
CStackTop_ReferenceParentStack stackTop( pInit->ParentStackTrace, ARRAYSIZE( pInit->ParentStackTrace ) );
#endif
bool bInitSuccess = true;
if ( pInit->pfInitSuccess )
*(pInit->pfInitSuccess) = false;
#ifdef _PS3
*(pInit->pfInitSuccess) = pInit->pThread->Init();
#else
try
{
bInitSuccess = pInit->pThread->Init();
}
catch (...)
{
pInit->pInitCompleteEvent->Set();
throw;
}
#endif // _PS3
if ( pInit->pfInitSuccess )
*(pInit->pfInitSuccess) = bInitSuccess;
pInit->pInitCompleteEvent->Set();
if (!bInitSuccess)
return 0;
if ( !Plat_IsInDebugSession() && (pInit->pThread->m_flags & SUPPORT_STOP_PROTOCOL) )
{
#ifndef _PS3
try
#endif
{
pInit->pThread->m_result = pInit->pThread->Run();
}
#ifndef _PS3
catch (...)
{
}
#endif
}
else
{
pInit->pThread->m_result = pInit->pThread->Run();
}
pInit->pThread->OnExit();
#ifdef _PS3
SetCurThreadPS3( NULL );
#else
g_pCurThread = NULL;
#endif
FreeThreadID();
AUTO_LOCK( pThread->m_Lock );
#ifdef _WIN32
CloseHandle( pThread->m_hThread );
RemoveThreadHandleToIDMap( pThread->m_hThread );
pThread->m_hThread = NULL;
#elif defined( _PS3 )
pThread->m_threadZombieId = pThread->m_threadId;
pThread->m_threadEnd.Set();
pThread->m_threadId = 0;
#elif defined(POSIX)
pThread->m_threadZombieId = pThread->m_threadId;
pThread->m_threadId = 0;
#else
#error
#endif
pThread->m_ExitEvent.Set();
#ifdef _PS3
{
pThread->m_Lock.Unlock();
sys_ppu_thread_exit( pInit->pThread->m_result );
// reacquire the lock in case thread exit didn't actually exit the thread, so that
// AUTO_LOCK won't double-unlock the lock (to keep it paired)
pThread->m_Lock.Lock();
}
#endif
#if defined( POSIX )|| defined( _PS3 )
return (void*)pInit->pThread->m_result;
#else
return pInit->pThread->m_result;
#endif
}
#endif // THREADTOOLS_INL

858
external/vpc/public/tier0/tslist.h vendored Normal file
View File

@@ -0,0 +1,858 @@
//========== Copyright <20> 2005, Valve Corporation, All rights reserved. ========
//
// Purpose:
//
// LIFO from disassembly of Windows API and http://perso.wanadoo.fr/gmem/evenements/jim2002/articles/L17_Fober.pdf
// FIFO from http://perso.wanadoo.fr/gmem/evenements/jim2002/articles/L17_Fober.pdf
//
//=============================================================================
#ifndef TSLIST_H
#define TSLIST_H
#if defined( _WIN32 )
#pragma once
#endif
#if ( defined( PLATFORM_X360 ) || defined( PLATFORM_WINDOWS_PC64 ) )
#define USE_NATIVE_SLIST
#endif
#if defined( USE_NATIVE_SLIST ) && !defined( _X360 ) && !defined( _PS3 )
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#endif
#include "tier0/dbg.h"
#include "tier0/threadtools.h"
#include "tier0/memdbgon.h"
//-----------------------------------------------------------------------------
#if defined(PLATFORM_WINDOWS_PC64)
#define TSLIST_HEAD_ALIGNMENT 16 //MEMORY_ALLOCATION_ALIGNMENT
#define TSLIST_NODE_ALIGNMENT 16 //MEMORY_ALLOCATION_ALIGNMENT
#define TSLIST_HEAD_ALIGN ALIGN16
#define TSLIST_NODE_ALIGN ALIGN16
#define TSLIST_HEAD_ALIGN_POST ALIGN16_POST
#define TSLIST_NODE_ALIGN_POST ALIGN16_POST
#else
#define TSLIST_HEAD_ALIGNMENT 8
#define TSLIST_NODE_ALIGNMENT 8
#define TSLIST_HEAD_ALIGN ALIGN8
#define TSLIST_NODE_ALIGN ALIGN8
#define TSLIST_HEAD_ALIGN_POST ALIGN8_POST
#define TSLIST_NODE_ALIGN_POST ALIGN8_POST
#endif
//-----------------------------------------------------------------------------
PLATFORM_INTERFACE bool RunTSQueueTests( int nListSize = 10000, int nTests = 1 );
PLATFORM_INTERFACE bool RunTSListTests( int nListSize = 10000, int nTests = 1 );
//-----------------------------------------------------------------------------
// Lock free list.
//-----------------------------------------------------------------------------
//#define USE_NATIVE_SLIST
#ifdef USE_NATIVE_SLIST
typedef SLIST_ENTRY TSLNodeBase_t;
typedef SLIST_HEADER TSLHead_t;
#else
struct TSLIST_NODE_ALIGN TSLNodeBase_t
{
TSLNodeBase_t *Next; // name to match Windows
}
TSLIST_NODE_ALIGN_POST;
union TSLHead_t
{
struct Value_t
{
TSLNodeBase_t *Next;
// <sergiy> Depth must be in the least significant halfword when atomically loading into register,
// to avoid carrying digits from Sequence. Carrying digits from Depth to Sequence is ok,
// because Sequence can be pretty much random. We could operate on both of them separately,
// but it could perhaps (?) lead to problems with store forwarding. I don't know 'cause I didn't
// performance-test or design original code, I'm just making it work on PowerPC.
#ifdef PLAT_BIG_ENDIAN
int16 Sequence;
int16 Depth;
#else
int16 Depth;
int16 Sequence;
#endif
} value;
struct Value32_t
{
TSLNodeBase_t *Next_do_not_use_me;
int32 DepthAndSequence;
} value32;
int64 value64;
};
#endif
//-------------------------------------
class TSLIST_HEAD_ALIGN CTSListBase
{
public:
CTSListBase()
{
if ( ((size_t)&m_Head) % TSLIST_HEAD_ALIGNMENT != 0 )
{
Error( _T( "CTSListBase: Misaligned list\n" ) );
DebuggerBreak();
}
#ifdef USE_NATIVE_SLIST
InitializeSListHead( &m_Head );
#else
m_Head.value64 = (int64)0;
#endif
}
~CTSListBase()
{
Detach();
}
TSLNodeBase_t *Push( TSLNodeBase_t *pNode )
{
#ifdef _DEBUG
if ( (size_t)pNode % TSLIST_NODE_ALIGNMENT != 0 )
{
Error( _T( "CTSListBase: Misaligned node\n" ) );
DebuggerBreak();
}
#endif
#ifdef USE_NATIVE_SLIST
#ifdef _X360
// integrated write-release barrier
return (TSLNodeBase_t *)InterlockedPushEntrySListRelease( &m_Head, pNode );
#else
return (TSLNodeBase_t *)InterlockedPushEntrySList( &m_Head, pNode );
#endif
#else
TSLHead_t oldHead;
TSLHead_t newHead;
#if defined( PLATFORM_PS3 ) || defined( PLATFORM_X360 )
__lwsync(); // write-release barrier
#endif
for (;;)
{
oldHead.value64 = m_Head.value64;
pNode->Next = oldHead.value.Next;
newHead.value.Next = pNode;
newHead.value32.DepthAndSequence = oldHead.value32.DepthAndSequence + 0x10001;
if ( ThreadInterlockedAssignIf64( &m_Head.value64, newHead.value64, oldHead.value64 ) )
{
break;
}
ThreadPause();
};
return (TSLNodeBase_t *)oldHead.value.Next;
#endif
}
TSLNodeBase_t *Pop()
{
#ifdef USE_NATIVE_SLIST
#ifdef _X360
// integrated read-acquire barrier
TSLNodeBase_t *pNode = (TSLNodeBase_t *)InterlockedPopEntrySListAcquire( &m_Head );
#else
TSLNodeBase_t *pNode = (TSLNodeBase_t *)InterlockedPopEntrySList( &m_Head );
#endif
return pNode;
#else
TSLHead_t oldHead;
TSLHead_t newHead;
for (;;)
{
oldHead.value64 = m_Head.value64;
if ( !oldHead.value.Next )
return NULL;
newHead.value.Next = oldHead.value.Next->Next;
newHead.value32.DepthAndSequence = oldHead.value32.DepthAndSequence - 1;
if ( ThreadInterlockedAssignIf64( &m_Head.value64, newHead.value64, oldHead.value64 ) )
{
#if defined( PLATFORM_PS3 ) || defined( PLATFORM_X360 )
__lwsync(); // read-acquire barrier
#endif
break;
}
ThreadPause();
};
return (TSLNodeBase_t *)oldHead.value.Next;
#endif
}
TSLNodeBase_t *Detach()
{
#ifdef USE_NATIVE_SLIST
TSLNodeBase_t *pBase = (TSLNodeBase_t *)InterlockedFlushSList( &m_Head );
#if defined( _X360 ) || defined( _PS3 )
__lwsync(); // read-acquire barrier
#endif
return pBase;
#else
TSLHead_t oldHead;
TSLHead_t newHead;
do
{
ThreadPause();
oldHead.value64 = m_Head.value64;
if ( !oldHead.value.Next )
return NULL;
newHead.value.Next = NULL;
// <sergiy> the reason for AND'ing it instead of poking a short into memory
// is probably to avoid store forward issues, but I'm not sure because
// I didn't construct this code. In any case, leaving it as is on big-endian
newHead.value32.DepthAndSequence = oldHead.value32.DepthAndSequence & 0xffff0000;
} while( !ThreadInterlockedAssignIf64( &m_Head.value64, newHead.value64, oldHead.value64 ) );
return (TSLNodeBase_t *)oldHead.value.Next;
#endif
}
TSLHead_t *AccessUnprotected()
{
return &m_Head;
}
int Count() const
{
#ifdef USE_NATIVE_SLIST
return QueryDepthSList( const_cast<TSLHead_t*>( &m_Head ) );
#else
return m_Head.value.Depth;
#endif
}
private:
TSLHead_t m_Head;
}
TSLIST_HEAD_ALIGN_POST;
//-------------------------------------
template <typename T>
class TSLIST_HEAD_ALIGN CTSSimpleList : public CTSListBase
{
public:
void Push( T *pNode )
{
Assert( sizeof(T) >= sizeof(TSLNodeBase_t) );
CTSListBase::Push( (TSLNodeBase_t *)pNode );
}
T *Pop()
{
return (T *)CTSListBase::Pop();
}
}
TSLIST_HEAD_ALIGN_POST;
//-------------------------------------
// this is a replacement for CTSList<> and CObjectPool<> that does not
// have a per-item, per-alloc new/delete overhead
// similar to CTSSimpleList except that it allocates it's own pool objects
// and frees them on destruct. Also it does not overlay the TSNodeBase_t memory
// on T's memory
template< class T >
class TSLIST_HEAD_ALIGN CTSPool : public CTSListBase
{
// packs the node and the item (T) into a single struct and pools those
struct TSLIST_NODE_ALIGN simpleTSPoolStruct_t : public TSLNodeBase_t
{
T elem;
} TSLIST_NODE_ALIGN_POST;
public:
~CTSPool()
{
simpleTSPoolStruct_t *pNode = NULL;
while ( 1 )
{
pNode = (simpleTSPoolStruct_t *)CTSListBase::Pop();
if ( !pNode )
break;
delete pNode;
}
}
void PutObject( T *pInfo )
{
char *pElem = (char *)pInfo;
pElem -= offsetof(simpleTSPoolStruct_t,elem);
simpleTSPoolStruct_t *pNode = (simpleTSPoolStruct_t *)pElem;
CTSListBase::Push( pNode );
}
T *GetObject()
{
simpleTSPoolStruct_t *pNode = (simpleTSPoolStruct_t *)CTSListBase::Pop();
if ( !pNode )
{
pNode = new simpleTSPoolStruct_t;
}
return &pNode->elem;
}
// omg windows sdk - why do you #define GetObject()?
FORCEINLINE T *Get()
{
return GetObject();
}
} TSLIST_HEAD_ALIGN_POST;
//-------------------------------------
template <typename T>
class TSLIST_HEAD_ALIGN CTSList : public CTSListBase
{
public:
struct TSLIST_NODE_ALIGN Node_t : public TSLNodeBase_t
{
Node_t() {}
Node_t( const T &init ) : elem( init ) {}
T elem;
} TSLIST_NODE_ALIGN_POST;
~CTSList()
{
Purge();
}
void Purge()
{
Node_t *pCurrent = Detach();
Node_t *pNext;
while ( pCurrent )
{
pNext = (Node_t *)pCurrent->Next;
delete pCurrent;
pCurrent = pNext;
}
}
void RemoveAll()
{
Purge();
}
Node_t *Push( Node_t *pNode )
{
return (Node_t *)CTSListBase::Push( pNode );
}
Node_t *Pop()
{
return (Node_t *)CTSListBase::Pop();
}
void PushItem( const T &init )
{
Push( new Node_t( init ) );
}
bool PopItem( T *pResult)
{
Node_t *pNode = Pop();
if ( !pNode )
return false;
*pResult = pNode->elem;
delete pNode;
return true;
}
Node_t *Detach()
{
return (Node_t *)CTSListBase::Detach();
}
} TSLIST_HEAD_ALIGN_POST;
//-------------------------------------
template <typename T>
class TSLIST_HEAD_ALIGN CTSListWithFreeList : public CTSListBase
{
public:
struct TSLIST_NODE_ALIGN Node_t : public TSLNodeBase_t
{
Node_t() {}
Node_t( const T &init ) : elem( init ) {}
T elem;
} TSLIST_NODE_ALIGN_POST;
~CTSListWithFreeList()
{
Purge();
}
void Purge()
{
Node_t *pCurrent = Detach();
Node_t *pNext;
while ( pCurrent )
{
pNext = (Node_t *)pCurrent->Next;
delete pCurrent;
pCurrent = pNext;
}
pCurrent = (Node_t *)m_FreeList.Detach();
while ( pCurrent )
{
pNext = (Node_t *)pCurrent->Next;
delete pCurrent;
pCurrent = pNext;
}
}
void RemoveAll()
{
Node_t *pCurrent = Detach();
Node_t *pNext;
while ( pCurrent )
{
pNext = (Node_t *)pCurrent->Next;
m_FreeList.Push( pCurrent );
pCurrent = pNext;
}
}
Node_t *Push( Node_t *pNode )
{
return (Node_t *)CTSListBase::Push( pNode );
}
Node_t *Pop()
{
return (Node_t *)CTSListBase::Pop();
}
void PushItem( const T &init )
{
Node_t *pNode = (Node_t *)m_FreeList.Pop();
if ( !pNode )
{
pNode = new Node_t;
}
pNode->elem = init;
Push( pNode );
}
bool PopItem( T *pResult)
{
Node_t *pNode = Pop();
if ( !pNode )
return false;
*pResult = pNode->elem;
m_FreeList.Push( pNode );
return true;
}
Node_t *Detach()
{
return (Node_t *)CTSListBase::Detach();
}
void FreeNode( Node_t *pNode )
{
m_FreeList.Push( pNode );
}
private:
CTSListBase m_FreeList;
} TSLIST_HEAD_ALIGN_POST;
//-----------------------------------------------------------------------------
// Lock free queue
//
// A special consideration: the element type should be simple. This code
// actually dereferences freed nodes as part of pop, but later detects
// that. If the item in the queue is a complex type, only bad things can
// come of that. Also, therefore, if you're using Push/Pop instead of
// push item, be aware that the node memory cannot be freed until
// all threads that might have been popping have completed the pop.
// The PushItem()/PopItem() for handles this by keeping a persistent
// free list. Dont mix Push/PushItem. Note also nodes will be freed at the end,
// and are expected to have been allocated with operator new.
//-----------------------------------------------------------------------------
template <typename T, bool bTestOptimizer = false, bool bFreeList = true>
class TSLIST_HEAD_ALIGN CTSQueue
{
public:
struct TSLIST_NODE_ALIGN Node_t
{
Node_t() {}
Node_t( const T &init ) : elem( init ) {}
Node_t *pNext;
T elem;
} TSLIST_NODE_ALIGN_POST;
union TSLIST_HEAD_ALIGN NodeLink_t
{
struct Value_t
{
Node_t *pNode;
int32 sequence;
} value;
int64 value64;
} TSLIST_HEAD_ALIGN_POST;
CTSQueue()
{
COMPILE_TIME_ASSERT( sizeof(Node_t) >= sizeof(TSLNodeBase_t) );
if ( ((size_t)&m_Head) % TSLIST_HEAD_ALIGNMENT != 0 )
{
Error( "CTSQueue: Misaligned queue\n" );
DebuggerBreak();
}
if ( ((size_t)&m_Tail) % TSLIST_HEAD_ALIGNMENT != 0 )
{
Error( "CTSQueue: Misaligned queue\n" );
DebuggerBreak();
}
m_Count = 0;
m_Head.value.sequence = m_Tail.value.sequence = 0;
m_Head.value.pNode = m_Tail.value.pNode = new Node_t; // list always contains a dummy node
m_Head.value.pNode->pNext = End();
}
~CTSQueue()
{
Purge();
Assert( m_Count == 0 );
Assert( m_Head.value.pNode == m_Tail.value.pNode );
Assert( m_Head.value.pNode->pNext == End() );
delete m_Head.value.pNode;
}
// Note: Purge, RemoveAll, and Validate are *not* threadsafe
void Purge()
{
if ( IsDebug() )
{
Validate();
}
Node_t *pNode;
while ( ( pNode = Pop() ) != NULL )
{
delete pNode;
}
while ( bFreeList && ( pNode = (Node_t *)m_FreeNodes.Pop() ) != NULL )
{
delete pNode;
}
Assert( m_Count == 0 );
Assert( m_Head.value.pNode == m_Tail.value.pNode );
Assert( m_Head.value.pNode->pNext == End() );
m_Head.value.sequence = m_Tail.value.sequence = 0;
}
void RemoveAll()
{
if ( IsDebug() )
{
Validate();
}
Node_t *pNode;
while ( bFreeList && ( pNode = Pop() ) != NULL )
{
m_FreeNodes.Push( (TSLNodeBase_t *)pNode );
}
}
bool Validate()
{
bool bResult = true;
int nNodes = 0;
if ( m_Count == 0 )
{
if ( m_Head.value.pNode != m_Tail.value.pNode )
{
DebuggerBreakIfDebugging();
bResult = false;
}
}
Node_t *pNode = m_Head.value.pNode;
while ( pNode != End() )
{
nNodes++;
pNode = pNode->pNext;
}
nNodes--;// skip dummy node
if ( nNodes != m_Count )
{
DebuggerBreakIfDebugging();
bResult = false;
}
if ( !bResult )
{
Msg( "Corrupt CTSQueueDetected" );
}
return bResult;
}
void FinishPush( Node_t *pNode, const NodeLink_t &oldTail )
{
NodeLink_t newTail;
newTail.value.pNode = pNode;
newTail.value.sequence = oldTail.value.sequence + 1;
ThreadMemoryBarrier();
InterlockedCompareExchangeNodeLink( &m_Tail, newTail, oldTail );
}
Node_t *Push( Node_t *pNode )
{
#ifdef _DEBUG
if ( (size_t)pNode % TSLIST_NODE_ALIGNMENT != 0 )
{
Error( "CTSListBase: Misaligned node\n" );
DebuggerBreak();
}
#endif
NodeLink_t oldTail;
pNode->pNext = End();
for (;;)
{
oldTail.value.sequence = m_Tail.value.sequence;
oldTail.value.pNode = m_Tail.value.pNode;
if ( InterlockedCompareExchangeNode( &(oldTail.value.pNode->pNext), pNode, End() ) == End() )
{
break;
}
else
{
// Another thread is trying to push, help it along
FinishPush( oldTail.value.pNode->pNext, oldTail );
}
}
FinishPush( pNode, oldTail ); // This can fail if another thread pushed between the sequence and node grabs above. Later pushes or pops corrects
m_Count++;
return oldTail.value.pNode;
}
Node_t *Pop()
{
#define TSQUEUE_BAD_NODE_LINK ( (Node_t *)INT_TO_POINTER( 0xdeadbeef ) )
NodeLink_t * volatile pHead = &m_Head;
NodeLink_t * volatile pTail = &m_Tail;
Node_t * volatile * pHeadNode = &m_Head.value.pNode;
volatile int * volatile pHeadSequence = &m_Head.value.sequence;
Node_t * volatile * pTailNode = &pTail->value.pNode;
NodeLink_t head;
NodeLink_t newHead;
Node_t *pNext;
int tailSequence;
T elem;
for (;;)
{
head.value.sequence = *pHeadSequence; // must grab sequence first, which allows condition below to ensure pNext is valid
ThreadMemoryBarrier(); // need a barrier to prevent reordering of these assignments
head.value.pNode = *pHeadNode;
tailSequence = pTail->value.sequence;
pNext = head.value.pNode->pNext;
if ( pNext && head.value.sequence == *pHeadSequence ) // Checking pNext only to force optimizer to not reorder the assignment to pNext and the compare of the sequence
{
if ( bTestOptimizer )
{
if ( pNext == TSQUEUE_BAD_NODE_LINK )
{
Msg( "Bad node link detected\n" );
continue;
}
}
if ( head.value.pNode == *pTailNode )
{
if ( pNext == End() )
{
return NULL;
}
// Another thread is trying to push, help it along
NodeLink_t &oldTail = head; // just reuse local memory for head to build old tail
oldTail.value.sequence = tailSequence; // reuse head pNode
FinishPush( pNext, oldTail );
}
else if ( pNext != End() )
{
elem = pNext->elem; // NOTE: next could be a freed node here, by design
newHead.value.pNode = pNext;
newHead.value.sequence = head.value.sequence + 1;
if ( InterlockedCompareExchangeNodeLink( pHead, newHead, head ) )
{
ThreadMemoryBarrier();
if ( bTestOptimizer )
{
head.value.pNode->pNext = TSQUEUE_BAD_NODE_LINK;
}
break;
}
}
}
}
m_Count--;
head.value.pNode->elem = elem;
return head.value.pNode;
}
void FreeNode( Node_t *pNode )
{
if ( bFreeList )
{
m_FreeNodes.Push( (TSLNodeBase_t *)pNode );
}
else
{
delete pNode;
}
}
void PushItem( const T &init )
{
Node_t *pNode;
if ( bFreeList && ( pNode = (Node_t *)m_FreeNodes.Pop() ) != NULL )
{
pNode->elem = init;
}
else
{
pNode = new Node_t( init );
}
Push( pNode );
}
bool PopItem( T *pResult)
{
Node_t *pNode = Pop();
if ( !pNode )
return false;
*pResult = pNode->elem;
if ( bFreeList )
{
m_FreeNodes.Push( (TSLNodeBase_t *)pNode );
}
else
{
delete pNode;
}
return true;
}
int Count()
{
return m_Count;
}
private:
Node_t *End() { return (Node_t *)this; } // just need a unique signifier
#ifndef _WIN64
Node_t *InterlockedCompareExchangeNode( Node_t * volatile *ppNode, Node_t *value, Node_t *comperand )
{
return (Node_t *)::ThreadInterlockedCompareExchangePointer( (void **)ppNode, value, comperand );
}
bool InterlockedCompareExchangeNodeLink( NodeLink_t volatile *pLink, const NodeLink_t &value, const NodeLink_t &comperand )
{
return ThreadInterlockedAssignIf64( (int64 *)pLink, value.value64, comperand.value64 );
}
#else
Node_t *InterlockedCompareExchangeNode( Node_t * volatile *ppNode, Node_t *value, Node_t *comperand )
{
AUTO_LOCK( m_ExchangeMutex );
Node_t *retVal = *ppNode;
if ( *ppNode == comperand )
*ppNode = value;
return retVal;
}
bool InterlockedCompareExchangeNodeLink( NodeLink_t volatile *pLink, const NodeLink_t &value, const NodeLink_t &comperand )
{
AUTO_LOCK( m_ExchangeMutex );
if ( pLink->value64 == comperand.value64 )
{
pLink->value64 = value.value64;
return true;
}
return false;
}
CThreadFastMutex m_ExchangeMutex;
#endif
NodeLink_t m_Head;
NodeLink_t m_Tail;
CInterlockedInt m_Count;
CTSListBase m_FreeNodes;
} TSLIST_HEAD_ALIGN_POST;
#include "tier0/memdbgoff.h"
#endif // TSLIST_H

73
external/vpc/public/tier0/validator.h vendored Normal file
View File

@@ -0,0 +1,73 @@
//========= Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#include "valobject.h"
#ifndef VALIDATOR_H
#define VALIDATOR_H
#ifdef _WIN32
#pragma once
#endif
#ifdef DBGFLAG_VALIDATE
class CValidator
{
public:
// Constructors & destructors
CValidator( void );
~CValidator( void );
// Call this each time we enter a new Validate function
void Push( tchar *pchType, void *pvObj, tchar *pchName );
// Call this each time we exit a Validate function
void Pop( void );
// Claim ownership of a memory block
void ClaimMemory( void *pvMem );
// Finish performing a check and perform necessary computations
void Finalize( void );
// Render our results to the console
void RenderObjects( int cubThreshold ); // Render all reported objects
void RenderLeaks( void ); // Render all memory leaks
// List manipulation functions:
CValObject *FindObject( void *pvObj ); // Returns CValObject containing pvObj, or NULL.
void DiffAgainst( CValidator *pOtherValidator ); // Removes any entries from this validator that are also present in the other.
// Accessors
bool BMemLeaks( void ) { return m_bMemLeaks; };
CValObject *PValObjectFirst( void ) { return m_pValObjectFirst; };
void Validate( CValidator &validator, tchar *pchName ); // Validate our internal structures
private:
CValObject *m_pValObjectFirst; // Linked list of all ValObjects
CValObject *m_pValObjectLast; // Last ValObject on the linked list
CValObject *m_pValObjectCur; // Object we're current processing
int m_cpvOwned; // Total # of blocks owned
int m_cpubLeaked; // # of leaked memory blocks
int m_cubLeaked; // Amount of leaked memory
bool m_bMemLeaks; // Has any memory leaked?
};
#endif // DBGFLAG_VALIDATE
#endif // VALIDATOR_H

72
external/vpc/public/tier0/valobject.h vendored Normal file
View File

@@ -0,0 +1,72 @@
//========= Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose: CValObject is used for tracking individual objects that report
// in to CValidator. Whenever a new object reports in (via CValidator::Push),
// we create a new CValObject to aggregate stats for it.
//
// $NoKeywords: $
//=============================================================================//
#ifndef VALOBJECT_H
#define VALOBJECT_H
#ifdef _WIN32
#pragma once
#endif
#ifdef DBGFLAG_VALIDATE
class CValObject
{
public:
// Constructors & destructors
CValObject( void ) { };
~CValObject( void );
void Init( tchar *pchType, void *pvObj, tchar *pchName, CValObject *pValObjectParent,
CValObject *pValObjectPrev );
// Our object has claimed ownership of a memory block
void ClaimMemoryBlock( void *pvMem );
// A child of ours has claimed ownership of a memory block
void ClaimChildMemoryBlock( int cubUser );
// Accessors
tchar *PchType( void ) { return m_rgchType; };
void *PvObj( void ) { return m_pvObj; };
tchar *PchName( void ) { return m_rgchName; };
CValObject *PValObjectParent( void ) { return m_pValObjectParent; };
int NLevel( void ) { return m_nLevel; };
CValObject *PValObjectNext( void ) { return m_pValObjectNext; };
int CpubMemSelf( void ) { return m_cpubMemSelf; };
int CubMemSelf( void ) { return m_cubMemSelf; };
int CpubMemTree( void ) { return m_cpubMemTree; };
int CubMemTree( void ) { return m_cubMemTree; };
int NUser( void ) { return m_nUser; };
void SetNUser( int nUser ) { m_nUser = nUser; };
void SetBNewSinceSnapshot( bool bNewSinceSnapshot ) { m_bNewSinceSnapshot = bNewSinceSnapshot; }
bool BNewSinceSnapshot( void ) { return m_bNewSinceSnapshot; }
private:
bool m_bNewSinceSnapshot; // If this block is new since the snapshot.
tchar m_rgchType[64]; // Type of the object we represent
tchar m_rgchName[64]; // Name of this particular object
void *m_pvObj; // Pointer to the object we represent
CValObject *m_pValObjectParent; // Our parent object in the tree.
int m_nLevel; // Our depth in the tree
CValObject *m_pValObjectNext; // Next ValObject in the linked list
int m_cpubMemSelf; // # of memory blocks we own directly
int m_cubMemSelf; // Total size of the memory blocks we own directly
int m_cpubMemTree; // # of memory blocks owned by us and our children
int m_cubMemTree; // Total size of the memory blocks owned by us and our children
int m_nUser; // Field provided for use by our users
};
#endif // DBGFLAG_VALIDATE
#endif // VALOBJECT_H

33
external/vpc/public/tier0/valve_off.h vendored Normal file
View File

@@ -0,0 +1,33 @@
//========= Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose: This turns off all Valve-specific #defines. Because we sometimes
// call external include files from inside .cpp files, we need to
// wrap those includes like this:
// #include "tier0/valve_off.h"
// #include <external.h>
// #include "tier0/valve_on.h"
//
// $NoKeywords: $
//=============================================================================//
#ifdef STEAM
//-----------------------------------------------------------------------------
// Unicode-related #defines (see wchartypes.h)
//-----------------------------------------------------------------------------
#undef char
//-----------------------------------------------------------------------------
// Memory-related #defines
//-----------------------------------------------------------------------------
#undef malloc
#undef realloc
#undef _expand
#undef free
#endif // STEAM
// Allow long to be used in 3rd-party headers
#undef long

37
external/vpc/public/tier0/valve_on.h vendored Normal file
View File

@@ -0,0 +1,37 @@
//========= Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose: This turns on all Valve-specific #defines. Because we sometimes
// call external include files from inside .cpp files, we need to
// wrap those includes like this:
// #include "tier0/valve_off.h"
// #include <external.h>
// #include "tier0/valve_on.h"
//
// $NoKeywords: $
//=============================================================================//
#ifdef STEAM
//-----------------------------------------------------------------------------
// Unicode-related #defines (see wchartypes.h)
//-----------------------------------------------------------------------------
#ifdef ENFORCE_WCHAR
#define char DontUseChar_SeeWcharOn.h
#endif
//-----------------------------------------------------------------------------
// Memory-related #defines
//-----------------------------------------------------------------------------
#define malloc( cub ) HEY_DONT_USE_MALLOC_USE_PVALLOC
#define realloc( pvOld, cub ) HEY_DONT_USE_REALLOC_USE_PVREALLOC
#define _expand( pvOld, cub ) HEY_DONT_USE_EXPAND_USE_PVEXPAND
#define free( pv ) HEY_DONT_USE_FREE_USE_FREEPV
#endif
// Long is evil because it's treated differently by different compilers
#ifdef DISALLOW_USE_OF_LONG
#define long long_is_the_devil_stop_using_it_use_int32_or_int64
#endif

1510
external/vpc/public/tier0/vprof.h vendored Normal file

File diff suppressed because it is too large Load Diff

31
external/vpc/public/tier0/vprof_sn.h vendored Normal file
View File

@@ -0,0 +1,31 @@
//========= Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ============//
#ifndef TIER_V0PROF_SN_HDR
#define TIER_V0PROF_SN_HDR
// enable this to get detailed SN Tuner markers. PS3 specific
#if defined( SN_TARGET_PS3 ) && !defined(_CERT)
#define VPROF_SN_LEVEL 0
extern "C" void(*g_pfnPushMarker)( const char * pName );
extern "C" void(*g_pfnPopMarker)();
class CVProfSnMarkerScope
{
public:
CVProfSnMarkerScope( const char * pszName )
{
g_pfnPushMarker( pszName );
}
~CVProfSnMarkerScope()
{
g_pfnPopMarker( );
}
};
#else
class CVProfSnMarkerScope { public: CVProfSnMarkerScope( const char * ) {} };
#endif
#endif

101
external/vpc/public/tier0/wchartypes.h vendored Normal file
View File

@@ -0,0 +1,101 @@
//========= Copyright (c) 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose: All of our code is completely Unicode. Instead of char, you should
// use wchar, uint8, or char8, as explained below.
//
// $NoKeywords: $
//=============================================================================//
#ifndef WCHARTYPES_H
#define WCHARTYPES_H
#ifdef _WIN32
#pragma once
#endif
#include "stddef.h"
#ifdef _INC_TCHAR
#error ("Must include tier0 type headers before tchar.h")
#endif
// Temporarily turn off Valve defines
#include "tier0/valve_off.h"
#if !defined(_WCHAR_T_DEFINED) && !defined( __WCHAR_TYPE__ ) && !defined(GNUC)
typedef unsigned short wchar_t;
#define _WCHAR_T_DEFINED
#endif
// char8
// char8 is equivalent to char, and should be used when you really need a char
// (for example, when calling an external function that's declared to take
// chars).
typedef char char8;
// uint8
// uint8 is equivalent to byte (but is preferred over byte for clarity). Use this
// whenever you mean a byte (for example, one byte of a network packet).
// uint8 itself is defined in platform.h
typedef unsigned char BYTE;
typedef unsigned char byte;
// wchar
// wchar is a single character of text (currently 16 bits, as all of our text is
// Unicode). Use this whenever you mean a piece of text (for example, in a string).
typedef wchar_t wchar;
//typedef char wchar;
// __WFILE__
// This is a Unicode version of __FILE__
#define WIDEN2(x) L ## x
#define WIDEN(x) WIDEN2(x)
#define __WFILE__ WIDEN(__FILE__)
#ifdef STEAM
#ifndef _UNICODE
#define FORCED_UNICODE
#endif
#define _UNICODE
#endif
#if defined( POSIX ) || defined( _PS3 )
#define _tcsstr strstr
#define _tcsicmp stricmp
#define _tcscmp strcmp
#define _tcscpy strcpy
#define _tcsncpy strncpy
#define _tcsrchr strrchr
#define _tcslen strlen
#define _tfopen fopen
#define _stprintf sprintf
#define _ftprintf fprintf
#define _vsntprintf _vsnprintf
#define _tprintf printf
#define _sntprintf _snprintf
#define _T(s) s
#else
#include <tchar.h>
#endif
#if defined(_UNICODE)
typedef wchar tchar;
#define tstring wstring
#define __TFILE__ __WFILE__
#define TCHAR_IS_WCHAR
#else
typedef char tchar;
#define tstring string
#define __TFILE__ __FILE__
#define TCHAR_IS_CHAR
#endif
#ifdef FORCED_UNICODE
#undef _UNICODE
#endif
// Turn valve defines back on
#include "tier0/valve_on.h"
#endif // WCHARTYPES

View File

@@ -0,0 +1,32 @@
//======= Copyright <20> 1996-2006, Valve Corporation, All rights reserved. ======
//
// Purpose: Win32 Console API helpers
//
//=============================================================================
#ifndef WIN32_CONSOLE_IO_H
#define WIN32_CONSOLE_IO_H
#if defined( COMPILER_MSVC )
#pragma once
#endif
// Function to attach a console for I/O to a Win32 GUI application in a reasonably smart fashion.
PLATFORM_INTERFACE bool SetupWin32ConsoleIO();
// Win32 Console Color API Helpers, originally from cmdlib.
struct Win32ConsoleColorContext_t
{
int m_InitialColor;
uint16 m_LastColor;
uint16 m_BadColor;
uint16 m_BackgroundFlags;
};
PLATFORM_INTERFACE void InitWin32ConsoleColorContext( Win32ConsoleColorContext_t *pContext );
PLATFORM_INTERFACE uint16 SetWin32ConsoleColor( Win32ConsoleColorContext_t *pContext, int nRed, int nGreen, int nBlue, int nIntensity );
PLATFORM_INTERFACE void RestoreWin32ConsoleColor( Win32ConsoleColorContext_t *pContext, uint16 prevColor );
#endif

View File

@@ -0,0 +1,16 @@
//========= Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#ifndef XBOX_CODELINE_DEFINES_H
#define XBOX_CODELINE_DEFINES_H
// In the regular src_main codeline, we leave this out.
//#define IN_XBOX_CODELINE
#endif // XBOX_CODELINE_DEFINES_H

268
external/vpc/public/tier1/byteswap.h vendored Normal file
View File

@@ -0,0 +1,268 @@
//========= Copyright <20> 1996-2006, Valve LLC, All rights reserved. ============
//
// Purpose: Low level byte swapping routines.
//
// $NoKeywords: $
//=============================================================================
#ifndef BYTESWAP_H
#define BYTESWAP_H
#if defined(_WIN32)
#pragma once
#endif
#include "tier0/dbg.h"
#include "datamap.h" // needed for typedescription_t. note datamap.h is tier1 as well.
class CByteswap
{
public:
CByteswap()
{
// Default behavior sets the target endian to match the machine native endian (no swap).
SetTargetBigEndian( IsMachineBigEndian() );
}
//-----------------------------------------------------------------------------
// Write a single field.
//-----------------------------------------------------------------------------
void SwapFieldToTargetEndian( void* pOutputBuffer, void *pData, typedescription_t *pField );
//-----------------------------------------------------------------------------
// Write a block of fields. Works a bit like the saverestore code.
//-----------------------------------------------------------------------------
void SwapFieldsToTargetEndian( void *pOutputBuffer, void *pBaseData, datamap_t *pDataMap );
// Swaps fields for the templated type to the output buffer.
template<typename T> inline void SwapFieldsToTargetEndian( T* pOutputBuffer, void *pBaseData, unsigned int objectCount = 1 )
{
for ( unsigned int i = 0; i < objectCount; ++i, ++pOutputBuffer )
{
SwapFieldsToTargetEndian( (void*)pOutputBuffer, pBaseData, &T::m_DataMap );
pBaseData = (byte*)pBaseData + sizeof(T);
}
}
// Swaps fields for the templated type in place.
template<typename T> inline void SwapFieldsToTargetEndian( T* pOutputBuffer, unsigned int objectCount = 1 )
{
SwapFieldsToTargetEndian<T>( pOutputBuffer, (void*)pOutputBuffer, objectCount );
}
//-----------------------------------------------------------------------------
// True if the current machine is detected as big endian.
// (Endienness is effectively detected at compile time when optimizations are
// enabled)
//-----------------------------------------------------------------------------
static bool IsMachineBigEndian()
{
short nIsBigEndian = 1;
// if we are big endian, the first byte will be a 0, if little endian, it will be a one.
return (bool)(0 == *(char *)&nIsBigEndian );
}
//-----------------------------------------------------------------------------
// Sets the target byte ordering we are swapping to or from.
//
// Braindead Endian Reference:
// x86 is LITTLE Endian
// PowerPC is BIG Endian
//-----------------------------------------------------------------------------
inline void SetTargetBigEndian( bool bigEndian )
{
m_bBigEndian = bigEndian;
m_bSwapBytes = IsMachineBigEndian() != bigEndian;
}
// Changes target endian
inline void FlipTargetEndian( void )
{
m_bSwapBytes = !m_bSwapBytes;
m_bBigEndian = !m_bBigEndian;
}
// Forces byte swapping state, regardless of endianess
inline void ActivateByteSwapping( bool bActivate )
{
SetTargetBigEndian( IsMachineBigEndian() != bActivate );
}
//-----------------------------------------------------------------------------
// Returns true if the target machine is the same as this one in endianness.
//
// Used to determine when a byteswap needs to take place.
//-----------------------------------------------------------------------------
inline bool IsSwappingBytes( void ) // Are bytes being swapped?
{
return m_bSwapBytes;
}
inline bool IsTargetBigEndian( void ) // What is the current target endian?
{
return m_bBigEndian;
}
//-----------------------------------------------------------------------------
// IsByteSwapped()
//
// When supplied with a chunk of input data and a constant or magic number
// (in native format) determines the endienness of the current machine in
// relation to the given input data.
//
// Returns:
// 1 if input is the same as nativeConstant.
// 0 if input is byteswapped relative to nativeConstant.
// -1 if input is not the same as nativeConstant and not byteswapped either.
//
// ( This is useful for detecting byteswapping in magic numbers in structure
// headers for example. )
//-----------------------------------------------------------------------------
template<typename T> inline int SourceIsNativeEndian( T input, T nativeConstant )
{
// If it's the same, it isn't byteswapped:
if( input == nativeConstant )
return 1;
int output;
LowLevelByteSwap<T>( &output, &input );
if( output == nativeConstant )
return 0;
Assert( 0 ); // if we get here, input is neither a swapped nor unswapped version of nativeConstant.
return -1;
}
//-----------------------------------------------------------------------------
// Swaps an input buffer full of type T into the given output buffer.
//
// Swaps [count] items from the inputBuffer to the outputBuffer.
// If inputBuffer is omitted or NULL, then it is assumed to be the same as
// outputBuffer - effectively swapping the contents of the buffer in place.
//-----------------------------------------------------------------------------
template<typename T> inline void SwapBuffer( T* outputBuffer, T* inputBuffer = NULL, int count = 1 )
{
Assert( count >= 0 );
Assert( outputBuffer );
// Fail gracefully in release:
if( count <=0 || !outputBuffer )
return;
// Optimization for the case when we are swapping in place.
if( inputBuffer == NULL )
{
inputBuffer = outputBuffer;
}
// Swap everything in the buffer:
for( int i = 0; i < count; i++ )
{
LowLevelByteSwap<T>( &outputBuffer[i], &inputBuffer[i] );
}
}
//-----------------------------------------------------------------------------
// Swaps an input buffer full of type T into the given output buffer.
//
// Swaps [count] items from the inputBuffer to the outputBuffer.
// If inputBuffer is omitted or NULL, then it is assumed to be the same as
// outputBuffer - effectively swapping the contents of the buffer in place.
//-----------------------------------------------------------------------------
template<typename T> inline void SwapBufferToTargetEndian( T* outputBuffer, T* inputBuffer = NULL, int count = 1 )
{
Assert( count >= 0 );
Assert( outputBuffer );
// Fail gracefully in release:
if( count <=0 || !outputBuffer )
return;
// Optimization for the case when we are swapping in place.
if( inputBuffer == NULL )
{
inputBuffer = outputBuffer;
}
// Are we already the correct endienness? ( or are we swapping 1 byte items? )
if( !m_bSwapBytes || ( sizeof(T) == 1 ) )
{
// If we were just going to swap in place then return.
if( !inputBuffer )
return;
// Otherwise copy the inputBuffer to the outputBuffer:
if ( outputBuffer != inputBuffer )
memcpy( outputBuffer, inputBuffer, count * sizeof( T ) );
return;
}
// Swap everything in the buffer:
for( int i = 0; i < count; i++ )
{
LowLevelByteSwap<T>( &outputBuffer[i], &inputBuffer[i] );
}
}
private:
//-----------------------------------------------------------------------------
// The lowest level byte swapping workhorse of doom. output always contains the
// swapped version of input. ( Doesn't compare machine to target endianness )
//-----------------------------------------------------------------------------
template<typename T> static void LowLevelByteSwap( T *output, T *input )
{
T temp = *output;
#if defined( _X360 )
// Intrinsics need the source type to be fixed-point
DWORD* word = (DWORD*)input;
switch( sizeof(T) )
{
case 8:
{
__storewordbytereverse( *(word+1), 0, &temp );
__storewordbytereverse( *(word+0), 4, &temp );
}
break;
case 4:
__storewordbytereverse( *word, 0, &temp );
break;
case 2:
__storeshortbytereverse( *input, 0, &temp );
break;
case 1:
V_memcpy( &temp, input, 1 );
break;
default:
Assert( "Invalid size in CByteswap::LowLevelByteSwap" && 0 );
}
#else
for( unsigned int i = 0; i < sizeof(T); i++ )
{
((unsigned char* )&temp)[i] = ((unsigned char*)input)[sizeof(T)-(i+1)];
}
#endif
V_memcpy( output, &temp, sizeof(T) );
}
#if defined( _X360 )
// specialized for void * to get 360 XDK compile working despite changelist 281331
//-----------------------------------------------------------------------------
// The lowest level byte swapping workhorse of doom. output always contains the
// swapped version of input. ( Doesn't compare machine to target endianness )
//-----------------------------------------------------------------------------
template<> static void LowLevelByteSwap( void **output, void **input )
{
AssertMsgOnce( sizeof(void *) == sizeof(unsigned int) , "void *'s on this platform are not four bytes!" );
__storewordbytereverse( *reinterpret_cast<unsigned int *>(input), 0, output );
}
#endif
unsigned int m_bSwapBytes : 1;
unsigned int m_bBigEndian : 1;
};
#endif /* !BYTESWAP_H */

View File

@@ -0,0 +1,43 @@
//===== Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ======//
//
// Purpose: Shared code for parsing / searching for characters in a string
// using lookup tables
//
// $Workfile: $
// $Date: $
// $NoKeywords: $
//===========================================================================//
#ifndef CHARACTERSET_H
#define CHARACTERSET_H
#ifdef _WIN32
#pragma once
#endif
struct characterset_t
{
char set[256];
};
// This is essentially a strpbrk() using a precalculated lookup table
//-----------------------------------------------------------------------------
// Purpose: builds a simple lookup table of a group of important characters
// Input : *pSetBuffer - pointer to the buffer for the group
// *pSetString - list of characters to flag
//-----------------------------------------------------------------------------
extern void CharacterSetBuild( characterset_t *pSetBuffer, const char *pSetString );
//-----------------------------------------------------------------------------
// Purpose:
// Input : *pSetBuffer - pre-build group buffer
// character - character to lookup
// Output : int - 1 if the character was in the set
//-----------------------------------------------------------------------------
#define IN_CHARACTERSET( SetBuffer, character ) ((SetBuffer).set[(unsigned char)(character)])
#endif // CHARACTERSET_H

View File

@@ -0,0 +1,31 @@
//========= Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose: Generic CRC functions
//
// $NoKeywords: $
//=============================================================================//
#ifndef CHECKSUM_CRC_H
#define CHECKSUM_CRC_H
#ifdef _WIN32
#pragma once
#endif
typedef uint32 CRC32_t;
void CRC32_Init( CRC32_t *pulCRC );
void CRC32_ProcessBuffer( CRC32_t *pulCRC, const void *p, int len );
void CRC32_Final( CRC32_t *pulCRC );
CRC32_t CRC32_GetTableEntry( unsigned int slot );
inline CRC32_t CRC32_ProcessSingleBuffer( const void *p, int len )
{
CRC32_t crc;
CRC32_Init( &crc );
CRC32_ProcessBuffer( &crc, p, len );
CRC32_Final( &crc );
return crc;
}
#endif // CHECKSUM_CRC_H

View File

@@ -0,0 +1,33 @@
//========= Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose: Generic MD5 hashing algo
//
//=============================================================================//
#ifndef CHECKSUM_MD5_H
#define CHECKSUM_MD5_H
#ifdef _WIN32
#pragma once
#endif
// 16 bytes == 128 bit digest
#define MD5_DIGEST_LENGTH 16
// MD5 Hash
typedef struct
{
unsigned int buf[4];
unsigned int bits[2];
unsigned char in[64];
} MD5Context_t;
void MD5Init( MD5Context_t *context );
void MD5Update( MD5Context_t *context, unsigned char const *buf, unsigned int len );
void MD5Final( unsigned char digest[ MD5_DIGEST_LENGTH ], MD5Context_t *context );
char *MD5_Print(unsigned char *digest, int hashlen );
unsigned int MD5_PseudoRandom(unsigned int nSeed);
#endif // CHECKSUM_MD5_H

975
external/vpc/public/tier1/convar.h vendored Normal file
View File

@@ -0,0 +1,975 @@
//===== Copyright 1996-2005, Valve Corporation, All rights reserved. ======//
//
// Purpose:
//
// $Workfile: $
// $Date: $
//
//-----------------------------------------------------------------------------
// $NoKeywords: $
//===========================================================================//
#ifndef CONVAR_H
#define CONVAR_H
#if _WIN32
#pragma once
#endif
#include "tier0/dbg.h"
#include "tier1/iconvar.h"
#include "tier1/utlvector.h"
#include "tier1/utlstring.h"
#include "color.h"
#include "icvar.h"
#ifdef _WIN32
#define FORCEINLINE_CVAR FORCEINLINE
#elif POSIX
#define FORCEINLINE_CVAR inline
#elif defined(_PS3)
#define FORCEINLINE_CVAR __attribute__((always_inline)) FORCEINLINE
#else
#error "implement me"
#endif
//-----------------------------------------------------------------------------
// Uncomment me to test for threading issues for material system convars
// NOTE: You want to disable all threading when you do this
// +host_thread_mode 0 +r_threaded_particles 0 +sv_parallel_packentities 0 +sv_disable_querycache 0
//-----------------------------------------------------------------------------
//#define CONVAR_TEST_MATERIAL_THREAD_CONVARS 1
//-----------------------------------------------------------------------------
// Forward declarations
//-----------------------------------------------------------------------------
class ConVar;
class CCommand;
class ConCommand;
class ConCommandBase;
struct characterset_t;
//-----------------------------------------------------------------------------
// Any executable that wants to use ConVars need to implement one of
// these to hook up access to console variables.
//-----------------------------------------------------------------------------
class IConCommandBaseAccessor
{
public:
// Flags is a combination of FCVAR flags in cvar.h.
// hOut is filled in with a handle to the variable.
virtual bool RegisterConCommandBase( ConCommandBase *pVar ) = 0;
};
//-----------------------------------------------------------------------------
// Helper method for console development
//-----------------------------------------------------------------------------
#if defined( USE_VXCONSOLE )
void ConVar_PublishToVXConsole();
#else
inline void ConVar_PublishToVXConsole() {}
#endif
//-----------------------------------------------------------------------------
// Called when a ConCommand needs to execute
//-----------------------------------------------------------------------------
typedef void ( *FnCommandCallbackV1_t )( void );
typedef void ( *FnCommandCallback_t )( const CCommand &command );
#define COMMAND_COMPLETION_MAXITEMS 64
#define COMMAND_COMPLETION_ITEM_LENGTH 64
//-----------------------------------------------------------------------------
// Returns 0 to COMMAND_COMPLETION_MAXITEMS worth of completion strings
//-----------------------------------------------------------------------------
typedef int ( *FnCommandCompletionCallback )( const char *partial, char commands[ COMMAND_COMPLETION_MAXITEMS ][ COMMAND_COMPLETION_ITEM_LENGTH ] );
//-----------------------------------------------------------------------------
// Interface version
//-----------------------------------------------------------------------------
class ICommandCallback
{
public:
virtual void CommandCallback( const CCommand &command ) = 0;
};
class ICommandCompletionCallback
{
public:
virtual int CommandCompletionCallback( const char *pPartial, CUtlVector< CUtlString > &commands ) = 0;
};
//-----------------------------------------------------------------------------
// Purpose: The base console invoked command/cvar interface
//-----------------------------------------------------------------------------
class ConCommandBase
{
friend class CCvar;
friend class ConVar;
friend class ConCommand;
friend void ConVar_Register( int nCVarFlag, IConCommandBaseAccessor *pAccessor );
friend void ConVar_PublishToVXConsole();
// FIXME: Remove when ConVar changes are done
friend class CDefaultCvar;
public:
ConCommandBase( void );
ConCommandBase( const char *pName, const char *pHelpString = 0,
int flags = 0 );
virtual ~ConCommandBase( void );
virtual bool IsCommand( void ) const;
// Check flag
virtual bool IsFlagSet( int flag ) const;
// Set flag
virtual void AddFlags( int flags );
// Clear flag
virtual void RemoveFlags( int flags );
virtual int GetFlags() const;
// Return name of cvar
virtual const char *GetName( void ) const;
// Return help text for cvar
virtual const char *GetHelpText( void ) const;
// Deal with next pointer
const ConCommandBase *GetNext( void ) const;
ConCommandBase *GetNext( void );
virtual bool IsRegistered( void ) const;
// Returns the DLL identifier
virtual CVarDLLIdentifier_t GetDLLIdentifier() const;
protected:
virtual void Create( const char *pName, const char *pHelpString = 0,
int flags = 0 );
// Used internally by OneTimeInit to initialize/shutdown
virtual void Init();
void Shutdown();
// Internal copy routine ( uses new operator from correct module )
char *CopyString( const char *from );
private:
// Next ConVar in chain
// Prior to register, it points to the next convar in the DLL.
// Once registered, though, m_pNext is reset to point to the next
// convar in the global list
ConCommandBase *m_pNext;
// Has the cvar been added to the global list?
bool m_bRegistered;
// Static data
const char *m_pszName;
const char *m_pszHelpString;
// ConVar flags
int m_nFlags;
protected:
// ConVars add themselves to this list for the executable.
// Then ConVar_Register runs through all the console variables
// and registers them into a global list stored in vstdlib.dll
static ConCommandBase *s_pConCommandBases;
// ConVars in this executable use this 'global' to access values.
static IConCommandBaseAccessor *s_pAccessor;
};
//-----------------------------------------------------------------------------
// Command tokenizer
//-----------------------------------------------------------------------------
class CCommand
{
public:
CCommand();
CCommand( int nArgC, const char **ppArgV );
bool Tokenize( const char *pCommand, characterset_t *pBreakSet = NULL );
void Reset();
int ArgC() const;
const char **ArgV() const;
const char *ArgS() const; // All args that occur after the 0th arg, in string form
const char *GetCommandString() const; // The entire command in string form, including the 0th arg
const char *operator[]( int nIndex ) const; // Gets at arguments
const char *Arg( int nIndex ) const; // Gets at arguments
// Helper functions to parse arguments to commands.
const char* FindArg( const char *pName ) const;
int FindArgInt( const char *pName, int nDefaultVal ) const;
static int MaxCommandLength();
static characterset_t* DefaultBreakSet();
private:
enum
{
COMMAND_MAX_ARGC = 64,
COMMAND_MAX_LENGTH = 512,
};
int m_nArgc;
int m_nArgv0Size;
char m_pArgSBuffer[ COMMAND_MAX_LENGTH ];
char m_pArgvBuffer[ COMMAND_MAX_LENGTH ];
const char* m_ppArgv[ COMMAND_MAX_ARGC ];
};
inline int CCommand::MaxCommandLength()
{
return COMMAND_MAX_LENGTH - 1;
}
inline int CCommand::ArgC() const
{
return m_nArgc;
}
inline const char **CCommand::ArgV() const
{
return m_nArgc ? (const char**)m_ppArgv : NULL;
}
inline const char *CCommand::ArgS() const
{
return m_nArgv0Size ? &m_pArgSBuffer[m_nArgv0Size] : "";
}
inline const char *CCommand::GetCommandString() const
{
return m_nArgc ? m_pArgSBuffer : "";
}
inline const char *CCommand::Arg( int nIndex ) const
{
// FIXME: Many command handlers appear to not be particularly careful
// about checking for valid argc range. For now, we're going to
// do the extra check and return an empty string if it's out of range
if ( nIndex < 0 || nIndex >= m_nArgc )
return "";
return m_ppArgv[nIndex];
}
inline const char *CCommand::operator[]( int nIndex ) const
{
return Arg( nIndex );
}
//-----------------------------------------------------------------------------
// Purpose: The console invoked command
//-----------------------------------------------------------------------------
class ConCommand : public ConCommandBase
{
friend class CCvar;
public:
typedef ConCommandBase BaseClass;
ConCommand( const char *pName, FnCommandCallbackV1_t callback,
const char *pHelpString = 0, int flags = 0, FnCommandCompletionCallback completionFunc = 0 );
ConCommand( const char *pName, FnCommandCallback_t callback,
const char *pHelpString = 0, int flags = 0, FnCommandCompletionCallback completionFunc = 0 );
ConCommand( const char *pName, ICommandCallback *pCallback,
const char *pHelpString = 0, int flags = 0, ICommandCompletionCallback *pCommandCompletionCallback = 0 );
virtual ~ConCommand( void );
virtual bool IsCommand( void ) const;
virtual int AutoCompleteSuggest( const char *partial, CUtlVector< CUtlString > &commands );
virtual bool CanAutoComplete( void );
// Invoke the function
virtual void Dispatch( const CCommand &command );
private:
// NOTE: To maintain backward compat, we have to be very careful:
// All public virtual methods must appear in the same order always
// since engine code will be calling into this code, which *does not match*
// in the mod code; it's using slightly different, but compatible versions
// of this class. Also: Be very careful about adding new fields to this class.
// Those fields will not exist in the version of this class that is instanced
// in mod code.
// Call this function when executing the command
union
{
FnCommandCallbackV1_t m_fnCommandCallbackV1;
FnCommandCallback_t m_fnCommandCallback;
ICommandCallback *m_pCommandCallback;
};
union
{
FnCommandCompletionCallback m_fnCompletionCallback;
ICommandCompletionCallback *m_pCommandCompletionCallback;
};
bool m_bHasCompletionCallback : 1;
bool m_bUsingNewCommandCallback : 1;
bool m_bUsingCommandCallbackInterface : 1;
};
//-----------------------------------------------------------------------------
// Purpose: A console variable
//-----------------------------------------------------------------------------
class ConVar : public ConCommandBase, public IConVar
{
friend class CCvar;
friend class ConVarRef;
friend class SplitScreenConVarRef;
public:
typedef ConCommandBase BaseClass;
ConVar( const char *pName, const char *pDefaultValue, int flags = 0);
ConVar( const char *pName, const char *pDefaultValue, int flags,
const char *pHelpString );
ConVar( const char *pName, const char *pDefaultValue, int flags,
const char *pHelpString, bool bMin, float fMin, bool bMax, float fMax );
ConVar( const char *pName, const char *pDefaultValue, int flags,
const char *pHelpString, FnChangeCallback_t callback );
ConVar( const char *pName, const char *pDefaultValue, int flags,
const char *pHelpString, bool bMin, float fMin, bool bMax, float fMax,
FnChangeCallback_t callback );
virtual ~ConVar( void );
virtual bool IsFlagSet( int flag ) const;
virtual const char* GetHelpText( void ) const;
virtual bool IsRegistered( void ) const;
virtual const char *GetName( void ) const;
// Return name of command (usually == GetName(), except in case of FCVAR_SS_ADDED vars
virtual const char *GetBaseName( void ) const;
virtual int GetSplitScreenPlayerSlot() const;
virtual void AddFlags( int flags );
virtual int GetFlags() const;
virtual bool IsCommand( void ) const;
// Install a change callback (there shouldn't already be one....)
void InstallChangeCallback( FnChangeCallback_t callback, bool bInvoke = true );
void RemoveChangeCallback( FnChangeCallback_t callbackToRemove );
int GetChangeCallbackCount() const { return m_pParent->m_fnChangeCallbacks.Count(); }
FnChangeCallback_t GetChangeCallback( int slot ) const { return m_pParent->m_fnChangeCallbacks[ slot ]; }
// Retrieve value
FORCEINLINE_CVAR float GetFloat( void ) const;
FORCEINLINE_CVAR int GetInt( void ) const;
FORCEINLINE_CVAR Color GetColor( void ) const;
FORCEINLINE_CVAR bool GetBool() const { return !!GetInt(); }
FORCEINLINE_CVAR char const *GetString( void ) const;
// Compiler driven selection for template use
template <typename T> T Get( void ) const;
template <typename T> T Get( T * ) const;
// Any function that allocates/frees memory needs to be virtual or else you'll have crashes
// from alloc/free across dll/exe boundaries.
// These just call into the IConCommandBaseAccessor to check flags and set the var (which ends up calling InternalSetValue).
virtual void SetValue( const char *value );
virtual void SetValue( float value );
virtual void SetValue( int value );
virtual void SetValue( Color value );
// Reset to default value
void Revert( void );
// True if it has a min/max setting
bool HasMin() const;
bool HasMax() const;
bool GetMin( float& minVal ) const;
bool GetMax( float& maxVal ) const;
float GetMinValue() const;
float GetMaxValue() const;
const char *GetDefault( void ) const;
void SetDefault( const char *pszDefault );
// Value
struct CVValue_t
{
char *m_pszString;
int m_StringLength;
// Values
float m_fValue;
int m_nValue;
};
FORCEINLINE_CVAR CVValue_t &GetRawValue()
{
return m_Value;
}
FORCEINLINE_CVAR const CVValue_t &GetRawValue() const
{
return m_Value;
}
private:
bool InternalSetColorFromString( const char *value );
// Called by CCvar when the value of a var is changing.
virtual void InternalSetValue(const char *value);
// For CVARs marked FCVAR_NEVER_AS_STRING
virtual void InternalSetFloatValue( float fNewValue );
virtual void InternalSetIntValue( int nValue );
virtual void InternalSetColorValue( Color value );
virtual bool ClampValue( float& value );
virtual void ChangeStringValue( const char *tempVal, float flOldValue );
virtual void Create( const char *pName, const char *pDefaultValue, int flags = 0,
const char *pHelpString = 0, bool bMin = false, float fMin = 0.0,
bool bMax = false, float fMax = false, FnChangeCallback_t callback = 0 );
// Used internally by OneTimeInit to initialize.
virtual void Init();
protected:
// This either points to "this" or it points to the original declaration of a ConVar.
// This allows ConVars to exist in separate modules, and they all use the first one to be declared.
// m_pParent->m_pParent must equal m_pParent (ie: m_pParent must be the root, or original, ConVar).
ConVar *m_pParent;
// Static data
const char *m_pszDefaultValue;
CVValue_t m_Value;
// Min/Max values
bool m_bHasMin;
float m_fMinVal;
bool m_bHasMax;
float m_fMaxVal;
// Call this function when ConVar changes
CUtlVector< FnChangeCallback_t > m_fnChangeCallbacks;
};
//-----------------------------------------------------------------------------
// Purpose: Return ConVar value as a float
// Output : float
//-----------------------------------------------------------------------------
FORCEINLINE_CVAR float ConVar::GetFloat( void ) const
{
#ifdef CONVAR_TEST_MATERIAL_THREAD_CONVARS
Assert( ThreadInMainThread() || IsFlagSet( FCVAR_MATERIAL_THREAD_MASK | FCVAR_ACCESSIBLE_FROM_THREADS ) );
#endif
return m_pParent->m_Value.m_fValue;
}
//-----------------------------------------------------------------------------
// Purpose: Return ConVar value as an int
// Output : int
//-----------------------------------------------------------------------------
FORCEINLINE_CVAR int ConVar::GetInt( void ) const
{
#ifdef CONVAR_TEST_MATERIAL_THREAD_CONVARS
Assert( ThreadInMainThread() || IsFlagSet( FCVAR_MATERIAL_THREAD_MASK | FCVAR_ACCESSIBLE_FROM_THREADS ) );
#endif
return m_pParent->m_Value.m_nValue;
}
//-----------------------------------------------------------------------------
// Purpose: Return ConVar value as a color
// Output : Color
//-----------------------------------------------------------------------------
FORCEINLINE_CVAR Color ConVar::GetColor( void ) const
{
#ifdef CONVAR_TEST_MATERIAL_THREAD_CONVARS
Assert( ThreadInMainThread() || IsFlagSet( FCVAR_MATERIAL_THREAD_MASK | FCVAR_ACCESSIBLE_FROM_THREADS ) );
#endif
unsigned char *pColorElement = ((unsigned char *)&m_pParent->m_Value.m_nValue);
return Color( pColorElement[0], pColorElement[1], pColorElement[2], pColorElement[3] );
}
//-----------------------------------------------------------------------------
template <> FORCEINLINE_CVAR float ConVar::Get<float>( void ) const { return GetFloat(); }
template <> FORCEINLINE_CVAR int ConVar::Get<int>( void ) const { return GetInt(); }
template <> FORCEINLINE_CVAR bool ConVar::Get<bool>( void ) const { return GetBool(); }
template <> FORCEINLINE_CVAR const char * ConVar::Get<const char *>( void ) const { return GetString(); }
template <> FORCEINLINE_CVAR float ConVar::Get<float>( float *p ) const { return ( *p = GetFloat() ); }
template <> FORCEINLINE_CVAR int ConVar::Get<int>( int *p ) const { return ( *p = GetInt() ); }
template <> FORCEINLINE_CVAR bool ConVar::Get<bool>( bool *p ) const { return ( *p = GetBool() ); }
template <> FORCEINLINE_CVAR const char * ConVar::Get<const char *>( char const **p ) const { return ( *p = GetString() ); }
//-----------------------------------------------------------------------------
// Purpose: Return ConVar value as a string, return "" for bogus string pointer, etc.
// Output : const char *
//-----------------------------------------------------------------------------
FORCEINLINE_CVAR const char *ConVar::GetString( void ) const
{
#ifdef CONVAR_TEST_MATERIAL_THREAD_CONVARS
Assert( ThreadInMainThread() || IsFlagSet( FCVAR_MATERIAL_THREAD_MASK | FCVAR_ACCESSIBLE_FROM_THREADS ) );
#endif
if ( m_nFlags & FCVAR_NEVER_AS_STRING )
return "FCVAR_NEVER_AS_STRING";
char const *str = m_pParent->m_Value.m_pszString;
return str ? str : "";
}
class CSplitScreenAddedConVar : public ConVar
{
typedef ConVar BaseClass;
public:
CSplitScreenAddedConVar( int nSplitScreenSlot, const char *pName, const ConVar *pBaseVar ) :
BaseClass
(
pName,
pBaseVar->GetDefault(),
// Keep basevar flags, except remove _SS and add _SS_ADDED instead
( pBaseVar->GetFlags() & ~FCVAR_SS ) | FCVAR_SS_ADDED,
pBaseVar->GetHelpText(),
pBaseVar->HasMin(),
pBaseVar->GetMinValue(),
pBaseVar->HasMax(),
pBaseVar->GetMaxValue()
),
m_pBaseVar( pBaseVar ),
m_nSplitScreenSlot( nSplitScreenSlot )
{
for ( int i = 0; i < pBaseVar->GetChangeCallbackCount(); ++i )
{
InstallChangeCallback( pBaseVar->GetChangeCallback( i ), false );
}
Assert( nSplitScreenSlot >= 1 );
Assert( nSplitScreenSlot < MAX_SPLITSCREEN_CLIENTS );
Assert( m_pBaseVar );
Assert( IsFlagSet( FCVAR_SS_ADDED ) );
Assert( !IsFlagSet( FCVAR_SS ) );
}
const ConVar *GetBaseVar() const;
virtual const char *GetBaseName() const;
void SetSplitScreenPlayerSlot( int nSlot );
virtual int GetSplitScreenPlayerSlot() const;
protected:
const ConVar *m_pBaseVar;
int m_nSplitScreenSlot;
};
FORCEINLINE_CVAR const ConVar *CSplitScreenAddedConVar::GetBaseVar() const
{
Assert( m_pBaseVar );
return m_pBaseVar;
}
FORCEINLINE_CVAR const char *CSplitScreenAddedConVar::GetBaseName() const
{
Assert( m_pBaseVar );
return m_pBaseVar->GetName();
}
FORCEINLINE_CVAR void CSplitScreenAddedConVar::SetSplitScreenPlayerSlot( int nSlot )
{
m_nSplitScreenSlot = nSlot;
}
FORCEINLINE_CVAR int CSplitScreenAddedConVar::GetSplitScreenPlayerSlot() const
{
return m_nSplitScreenSlot;
}
//-----------------------------------------------------------------------------
// Used to read/write convars that already exist (replaces the FindVar method)
//-----------------------------------------------------------------------------
class ConVarRef
{
public:
ConVarRef( const char *pName );
ConVarRef( const char *pName, bool bIgnoreMissing );
ConVarRef( IConVar *pConVar );
void Init( const char *pName, bool bIgnoreMissing );
bool IsValid() const;
bool IsFlagSet( int nFlags ) const;
IConVar *GetLinkedConVar();
// Get/Set value
float GetFloat( void ) const;
int GetInt( void ) const;
Color GetColor( void ) const;
bool GetBool() const { return !!GetInt(); }
const char *GetString( void ) const;
void SetValue( const char *pValue );
void SetValue( float flValue );
void SetValue( int nValue );
void SetValue( Color value );
void SetValue( bool bValue );
const char *GetName() const;
const char *GetDefault() const;
const char *GetBaseName() const;
int GetSplitScreenPlayerSlot() const;
private:
// High-speed method to read convar data
IConVar *m_pConVar;
ConVar *m_pConVarState;
};
//-----------------------------------------------------------------------------
// Did we find an existing convar of that name?
//-----------------------------------------------------------------------------
FORCEINLINE_CVAR bool ConVarRef::IsFlagSet( int nFlags ) const
{
return ( m_pConVar->IsFlagSet( nFlags ) != 0 );
}
FORCEINLINE_CVAR IConVar *ConVarRef::GetLinkedConVar()
{
return m_pConVar;
}
FORCEINLINE_CVAR const char *ConVarRef::GetName() const
{
return m_pConVar->GetName();
}
FORCEINLINE_CVAR const char *ConVarRef::GetBaseName() const
{
return m_pConVar->GetBaseName();
}
FORCEINLINE_CVAR int ConVarRef::GetSplitScreenPlayerSlot() const
{
return m_pConVar->GetSplitScreenPlayerSlot();
}
//-----------------------------------------------------------------------------
// Purpose: Return ConVar value as a float
//-----------------------------------------------------------------------------
FORCEINLINE_CVAR float ConVarRef::GetFloat( void ) const
{
return m_pConVarState->m_Value.m_fValue;
}
//-----------------------------------------------------------------------------
// Purpose: Return ConVar value as an int
//-----------------------------------------------------------------------------
FORCEINLINE_CVAR int ConVarRef::GetInt( void ) const
{
return m_pConVarState->m_Value.m_nValue;
}
//-----------------------------------------------------------------------------
// Purpose: Return ConVar value as a color
//-----------------------------------------------------------------------------
FORCEINLINE_CVAR Color ConVarRef::GetColor( void ) const
{
return m_pConVarState->GetColor();
}
//-----------------------------------------------------------------------------
// Purpose: Return ConVar value as a string, return "" for bogus string pointer, etc.
//-----------------------------------------------------------------------------
FORCEINLINE_CVAR const char *ConVarRef::GetString( void ) const
{
Assert( !IsFlagSet( FCVAR_NEVER_AS_STRING ) );
return m_pConVarState->m_Value.m_pszString;
}
FORCEINLINE_CVAR void ConVarRef::SetValue( const char *pValue )
{
m_pConVar->SetValue( pValue );
}
FORCEINLINE_CVAR void ConVarRef::SetValue( float flValue )
{
m_pConVar->SetValue( flValue );
}
FORCEINLINE_CVAR void ConVarRef::SetValue( int nValue )
{
m_pConVar->SetValue( nValue );
}
FORCEINLINE_CVAR void ConVarRef::SetValue( Color value )
{
m_pConVar->SetValue( value );
}
FORCEINLINE_CVAR void ConVarRef::SetValue( bool bValue )
{
m_pConVar->SetValue( bValue ? 1 : 0 );
}
FORCEINLINE_CVAR const char *ConVarRef::GetDefault() const
{
return m_pConVarState->m_pszDefaultValue;
}
//-----------------------------------------------------------------------------
// Helper for referencing splitscreen convars (i.e., "name" and "name2")
//-----------------------------------------------------------------------------
class SplitScreenConVarRef
{
public:
SplitScreenConVarRef( const char *pName );
SplitScreenConVarRef( const char *pName, bool bIgnoreMissing );
SplitScreenConVarRef( IConVar *pConVar );
void Init( const char *pName, bool bIgnoreMissing );
bool IsValid() const;
bool IsFlagSet( int nFlags ) const;
// Get/Set value
float GetFloat( int nSlot ) const;
int GetInt( int nSlot ) const;
Color GetColor( int nSlot ) const;
bool GetBool( int nSlot ) const { return !!GetInt( nSlot ); }
const char *GetString( int nSlot ) const;
void SetValue( int nSlot, const char *pValue );
void SetValue( int nSlot, float flValue );
void SetValue( int nSlot, int nValue );
void SetValue( int nSlot, Color value );
void SetValue( int nSlot, bool bValue );
const char *GetName( int nSlot ) const;
const char *GetDefault() const;
const char *GetBaseName() const;
private:
struct cv_t
{
IConVar *m_pConVar;
ConVar *m_pConVarState;
};
cv_t m_Info[ MAX_SPLITSCREEN_CLIENTS ];
};
//-----------------------------------------------------------------------------
// Did we find an existing convar of that name?
//-----------------------------------------------------------------------------
FORCEINLINE_CVAR bool SplitScreenConVarRef::IsFlagSet( int nFlags ) const
{
return ( m_Info[ 0 ].m_pConVar->IsFlagSet( nFlags ) != 0 );
}
FORCEINLINE_CVAR const char *SplitScreenConVarRef::GetName( int nSlot ) const
{
return m_Info[ nSlot ].m_pConVar->GetName();
}
FORCEINLINE_CVAR const char *SplitScreenConVarRef::GetBaseName() const
{
return m_Info[ 0 ].m_pConVar->GetBaseName();
}
//-----------------------------------------------------------------------------
// Purpose: Return ConVar value as a float
//-----------------------------------------------------------------------------
FORCEINLINE_CVAR float SplitScreenConVarRef::GetFloat( int nSlot ) const
{
return m_Info[ nSlot ].m_pConVarState->m_Value.m_fValue;
}
//-----------------------------------------------------------------------------
// Purpose: Return ConVar value as an int
//-----------------------------------------------------------------------------
FORCEINLINE_CVAR int SplitScreenConVarRef::GetInt( int nSlot ) const
{
return m_Info[ nSlot ].m_pConVarState->m_Value.m_nValue;
}
//-----------------------------------------------------------------------------
// Purpose: Return ConVar value as an int
//-----------------------------------------------------------------------------
FORCEINLINE_CVAR Color SplitScreenConVarRef::GetColor( int nSlot ) const
{
return m_Info[ nSlot ].m_pConVarState->GetColor();
}
//-----------------------------------------------------------------------------
// Purpose: Return ConVar value as a string, return "" for bogus string pointer, etc.
//-----------------------------------------------------------------------------
FORCEINLINE_CVAR const char *SplitScreenConVarRef::GetString( int nSlot ) const
{
Assert( !IsFlagSet( FCVAR_NEVER_AS_STRING ) );
return m_Info[ nSlot ].m_pConVarState->m_Value.m_pszString;
}
FORCEINLINE_CVAR void SplitScreenConVarRef::SetValue( int nSlot, const char *pValue )
{
m_Info[ nSlot ].m_pConVar->SetValue( pValue );
}
FORCEINLINE_CVAR void SplitScreenConVarRef::SetValue( int nSlot, float flValue )
{
m_Info[ nSlot ].m_pConVar->SetValue( flValue );
}
FORCEINLINE_CVAR void SplitScreenConVarRef::SetValue( int nSlot, int nValue )
{
m_Info[ nSlot ].m_pConVar->SetValue( nValue );
}
FORCEINLINE_CVAR void SplitScreenConVarRef::SetValue( int nSlot, Color value )
{
m_Info[ nSlot ].m_pConVar->SetValue( value );
}
FORCEINLINE_CVAR void SplitScreenConVarRef::SetValue( int nSlot, bool bValue )
{
m_Info[ nSlot ].m_pConVar->SetValue( bValue ? 1 : 0 );
}
FORCEINLINE_CVAR const char *SplitScreenConVarRef::GetDefault() const
{
return m_Info[ 0 ].m_pConVarState->m_pszDefaultValue;
}
//-----------------------------------------------------------------------------
// Called by the framework to register ConCommands with the ICVar
//-----------------------------------------------------------------------------
void ConVar_Register( int nCVarFlag = 0, IConCommandBaseAccessor *pAccessor = NULL );
void ConVar_Unregister( );
//-----------------------------------------------------------------------------
// Utility methods
//-----------------------------------------------------------------------------
void ConVar_PrintDescription( const ConCommandBase *pVar );
//-----------------------------------------------------------------------------
// Purpose: Utility class to quickly allow ConCommands to call member methods
//-----------------------------------------------------------------------------
#pragma warning (disable : 4355 )
template< class T >
class CConCommandMemberAccessor : public ConCommand, public ICommandCallback, public ICommandCompletionCallback
{
typedef ConCommand BaseClass;
typedef void ( T::*FnMemberCommandCallback_t )( const CCommand &command );
typedef int ( T::*FnMemberCommandCompletionCallback_t )( const char *pPartial, CUtlVector< CUtlString > &commands );
public:
CConCommandMemberAccessor( T* pOwner, const char *pName, FnMemberCommandCallback_t callback, const char *pHelpString = 0,
int flags = 0, FnMemberCommandCompletionCallback_t completionFunc = 0 ) :
BaseClass( pName, this, pHelpString, flags, ( completionFunc != 0 ) ? this : NULL )
{
m_pOwner = pOwner;
m_Func = callback;
m_CompletionFunc = completionFunc;
}
~CConCommandMemberAccessor()
{
Shutdown();
}
void SetOwner( T* pOwner )
{
m_pOwner = pOwner;
}
virtual void CommandCallback( const CCommand &command )
{
Assert( m_pOwner && m_Func );
(m_pOwner->*m_Func)( command );
}
virtual int CommandCompletionCallback( const char *pPartial, CUtlVector< CUtlString > &commands )
{
Assert( m_pOwner && m_CompletionFunc );
return (m_pOwner->*m_CompletionFunc)( pPartial, commands );
}
private:
T* m_pOwner;
FnMemberCommandCallback_t m_Func;
FnMemberCommandCompletionCallback_t m_CompletionFunc;
};
#pragma warning ( default : 4355 )
//-----------------------------------------------------------------------------
// Purpose: Utility macros to quicky generate a simple console command
//-----------------------------------------------------------------------------
#define CON_COMMAND( name, description ) \
static void name( const CCommand &args ); \
static ConCommand name##_command( #name, name, description ); \
static void name( const CCommand &args )
#define CON_COMMAND_F( name, description, flags ) \
static void name( const CCommand &args ); \
static ConCommand name##_command( #name, name, description, flags ); \
static void name( const CCommand &args )
#define CON_COMMAND_F_COMPLETION( name, description, flags, completion ) \
static void name( const CCommand &args ); \
static ConCommand name##_command( #name, name, description, flags, completion ); \
static void name( const CCommand &args )
#define CON_COMMAND_EXTERN( name, _funcname, description ) \
void _funcname( const CCommand &args ); \
static ConCommand name##_command( #name, _funcname, description ); \
void _funcname( const CCommand &args )
#define CON_COMMAND_EXTERN_F( name, _funcname, description, flags ) \
void _funcname( const CCommand &args ); \
static ConCommand name##_command( #name, _funcname, description, flags ); \
void _funcname( const CCommand &args )
#define CON_COMMAND_MEMBER_F( _thisclass, name, _funcname, description, flags ) \
void _funcname( const CCommand &args ); \
friend class CCommandMemberInitializer_##_funcname; \
class CCommandMemberInitializer_##_funcname \
{ \
public: \
CCommandMemberInitializer_##_funcname() : m_ConCommandAccessor( NULL, name, &_thisclass::_funcname, description, flags ) \
{ \
m_ConCommandAccessor.SetOwner( GET_OUTER( _thisclass, m_##_funcname##_register ) ); \
} \
private: \
CConCommandMemberAccessor< _thisclass > m_ConCommandAccessor; \
}; \
\
CCommandMemberInitializer_##_funcname m_##_funcname##_register; \
#endif // CONVAR_H

View File

@@ -0,0 +1,53 @@
//========= Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose: Helper class for cvars that have restrictions on their value.
//
//=============================================================================//
#ifndef CONVAR_SERVERBOUNDED_H
#define CONVAR_SERVERBOUNDED_H
#ifdef _WIN32
#pragma once
#endif
// This class is used to virtualize a ConVar's value, so the client can restrict its
// value while connected to a server. When using this across modules, it's important
// to dynamic_cast it to a ConVar_ServerBounded or you won't get the restricted value.
//
// NOTE: FCVAR_USERINFO vars are not virtualized before they are sent to the server
// (we have no way to detect if the virtualized value would change), so
// if you want to use a bounded cvar's value on the server, you must rebound it
// the same way the client does.
class ConVar_ServerBounded : public ConVar
{
public:
ConVar_ServerBounded( char const *pName, char const *pDefaultValue, int flags, char const *pHelpString )
: ConVar( pName, pDefaultValue, flags, pHelpString )
{
}
ConVar_ServerBounded( char const *pName, char const *pDefaultValue, int flags, char const *pHelpString, FnChangeCallback_t callback )
: ConVar( pName, pDefaultValue, flags, pHelpString, callback )
{
}
ConVar_ServerBounded( char const *pName, char const *pDefaultValue, int flags, char const *pHelpString, bool bMin, float fMin, bool bMax, float fMax )
: ConVar( pName, pDefaultValue, flags, pHelpString, bMin, fMin, bMax, fMax ) {}
// You must implement GetFloat.
virtual float GetFloat() const = 0;
// You can optionally implement these.
virtual int GetInt() const { return (int)GetFloat(); }
virtual bool GetBool() const { return ( GetInt() != 0 ); }
// Use this to get the underlying cvar's value.
float GetBaseFloatValue() const
{
return ConVar::GetFloat();
}
};
#endif // CONVAR_SERVERBOUNDED_H

View File

@@ -0,0 +1,74 @@
//===== Copyright <20> 1996-2006, Valve Corporation, All rights reserved. ======//
//
// Purpose: ExprSimplifier builds a binary tree from an infix expression (in the
// form of a character array).
//
//===========================================================================//
#ifndef EXPREVALUATOR_H
#define EXPREVALUATOR_H
#if defined( _WIN32 )
#pragma once
#endif
static const char OR_OP = '|';
static const char AND_OP = '&';
static const char NOT_OP = '!';
#define MAX_IDENTIFIER_LEN 128
enum Kind {CONDITIONAL, NOT, LITERAL};
struct ExprNode
{
ExprNode *left; // left sub-expression
ExprNode *right; // right sub-expression
Kind kind; // kind of node this is
union
{
char cond; // the conditional
bool value; // the value
} data;
};
typedef ExprNode *ExprTree;
// callback to evaluate a $<symbol> during evaluation, return true or false
typedef bool (*GetSymbolProc_t)( const char *pKey );
typedef void (*SyntaxErrorProc_t)( const char *pReason );
class CExpressionEvaluator
{
public:
CExpressionEvaluator();
~CExpressionEvaluator();
bool Evaluate( bool &result, const char *pInfixExpression, GetSymbolProc_t pGetSymbolProc = 0, SyntaxErrorProc_t pSyntaxErrorProc = 0 );
private:
CExpressionEvaluator( CExpressionEvaluator& ); // prevent copy constructor being used
char GetNextToken( void );
void FreeNode( ExprNode *pNode );
ExprNode *AllocateNode( void );
void FreeTree( ExprTree &node );
bool IsConditional( bool &bCondition, const char token );
bool IsNotOp( const char token );
bool IsIdentifierOrConstant( const char token );
bool MakeExprNode( ExprTree &tree, char token, Kind kind, ExprTree left, ExprTree right );
bool MakeFactor( ExprTree &tree );
bool MakeTerm( ExprTree &tree );
bool MakeExpression( ExprTree &tree );
bool BuildExpression( void );
bool SimplifyNode( ExprTree &node );
ExprTree m_ExprTree; // Tree representation of the expression
char m_CurToken; // Current token read from the input expression
const char *m_pExpression; // Array of the expression characters
int m_CurPosition; // Current position in the input expression
char m_Identifier[MAX_IDENTIFIER_LEN]; // Stores the identifier string
GetSymbolProc_t m_pGetSymbolProc;
SyntaxErrorProc_t m_pSyntaxErrorProc;
bool m_bSetup;
};
#endif

366
external/vpc/public/tier1/fmtstr.h vendored Normal file
View File

@@ -0,0 +1,366 @@
//========= Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose: A simple class for performing safe and in-expression sprintf-style
// string formatting
//
// $NoKeywords: $
//=============================================================================//
#ifndef FMTSTR_H
#define FMTSTR_H
#include <stdarg.h>
#include <stdio.h>
#include "tier0/platform.h"
#include "tier0/dbg.h"
#include "tier1/strtools.h"
#if defined( _WIN32 )
#pragma once
#endif
#if defined(POSIX)
#pragma GCC visibility push(hidden)
#endif
//=============================================================================
// using macro to be compatable with GCC
#define FmtStrVSNPrintf( szBuf, nBufSize, bQuietTruncation, ppszFormat, nPrevLen, lastArg ) \
do \
{ \
int result; \
va_list arg_ptr; \
bool bTruncated = false; \
static int scAsserted = 0; \
\
va_start(arg_ptr, lastArg); \
result = V_vsnprintfRet( (szBuf), (nBufSize)-1, (*(ppszFormat)), arg_ptr, &bTruncated ); \
va_end(arg_ptr); \
\
(szBuf)[(nBufSize)-1] = 0; \
if ( bTruncated && !(bQuietTruncation) && scAsserted < 5 ) \
{ \
Warning( "FmtStrVSNPrintf truncated to %d without QUIET_TRUNCATION specified!\n", ( int )( nBufSize ) ); \
AssertMsg( 0, "FmtStrVSNPrintf truncated without QUIET_TRUNCATION specified!\n" ); \
scAsserted++; \
} \
m_nLength = nPrevLen + result; \
} \
while (0)
// using macro to be compatible with GCC
#define FmtStrVSNPrintfNoLengthFixup( szBuf, nBufSize, bQuietTruncation, ppszFormat, nPrevLen, lastArg ) \
do \
{ \
int result; \
va_list arg_ptr; \
bool bTruncated = false; \
static int scAsserted = 0; \
\
va_start(arg_ptr, lastArg); \
result = V_vsnprintfRet( (szBuf), (nBufSize)-1, (*(ppszFormat)), arg_ptr, &bTruncated ); \
va_end(arg_ptr); \
\
(szBuf)[(nBufSize)-1] = 0; \
if ( bTruncated && !(bQuietTruncation) && scAsserted < 5 ) \
{ \
Warning( "FmtStrVSNPrintf truncated to %d without QUIET_TRUNCATION specified!\n", ( int )( nBufSize ) ); \
AssertMsg( 0, "FmtStrVSNPrintf truncated without QUIET_TRUNCATION specified!\n" ); \
scAsserted++; \
} \
} \
while (0)
//-----------------------------------------------------------------------------
//
// Purpose: String formatter with specified size
//
template <int SIZE_BUF, bool QUIET_TRUNCATION = false >
class CFmtStrN
{
public:
CFmtStrN()
{
InitQuietTruncation();
m_szBuf[0] = 0;
m_nLength = 0;
}
// Standard C formatting
CFmtStrN(PRINTF_FORMAT_STRING const char *pszFormat, ...) FMTFUNCTION( 2, 3 )
{
InitQuietTruncation();
FmtStrVSNPrintf( m_szBuf, SIZE_BUF, m_bQuietTruncation, &pszFormat, 0, pszFormat );
}
// Use this for pass-through formatting
CFmtStrN(const char ** ppszFormat, ...)
{
InitQuietTruncation();
FmtStrVSNPrintf( m_szBuf, SIZE_BUF, m_bQuietTruncation, ppszFormat, 0, ppszFormat );
}
// Explicit reformat
const char *sprintf(PRINTF_FORMAT_STRING const char *pszFormat, ...) FMTFUNCTION( 2, 3 )
{
InitQuietTruncation();
FmtStrVSNPrintf(m_szBuf, SIZE_BUF, m_bQuietTruncation, &pszFormat, 0, pszFormat );
return m_szBuf;
}
// Use this for va_list formatting
const char *sprintf_argv(const char *pszFormat, va_list arg_ptr)
{
int result;
bool bTruncated = false;
static int s_nWarned = 0;
InitQuietTruncation();
result = V_vsnprintfRet( m_szBuf, SIZE_BUF - 1, pszFormat, arg_ptr, &bTruncated );
m_szBuf[SIZE_BUF - 1] = 0;
if ( bTruncated && !m_bQuietTruncation && ( s_nWarned < 5 ) )
{
Warning( "CFmtStr truncated to %d without QUIET_TRUNCATION specified!\n", SIZE_BUF );
AssertMsg( 0, "CFmtStr truncated without QUIET_TRUNCATION specified!\n" );
s_nWarned++;
}
m_nLength = V_strlen( m_szBuf );
return m_szBuf;
}
// Use this for pass-through formatting
void VSprintf(const char **ppszFormat, ...)
{
InitQuietTruncation();
FmtStrVSNPrintf( m_szBuf, SIZE_BUF, m_bQuietTruncation, ppszFormat, 0, ppszFormat );
}
// Compatible API with CUtlString for converting to const char*
const char *Get( ) const { return m_szBuf; }
const char *String( ) const { return m_szBuf; }
// Use for access
operator const char *() const { return m_szBuf; }
char *Access() { return m_szBuf; }
// Access template argument
static inline int GetMaxLength() { return SIZE_BUF-1; }
CFmtStrN<SIZE_BUF,QUIET_TRUNCATION> & operator=( const char *pchValue )
{
V_strncpy( m_szBuf, pchValue, SIZE_BUF );
m_nLength = V_strlen( m_szBuf );
return *this;
}
CFmtStrN<SIZE_BUF,QUIET_TRUNCATION> & operator+=( const char *pchValue )
{
Append( pchValue );
return *this;
}
int Length() const { return m_nLength; }
void SetLength( int nLength )
{
m_nLength = Min( nLength, SIZE_BUF - 1 );
m_szBuf[m_nLength] = '\0';
}
void Clear()
{
m_szBuf[0] = 0;
m_nLength = 0;
}
void AppendFormat( PRINTF_FORMAT_STRING const char *pchFormat, ... ) FMTFUNCTION( 2, 3 )
{
char *pchEnd = m_szBuf + m_nLength;
FmtStrVSNPrintf( pchEnd, SIZE_BUF - m_nLength, m_bQuietTruncation, &pchFormat, m_nLength, pchFormat );
}
void AppendFormatV( const char *pchFormat, va_list args );
void Append( const char *pchValue )
{
// This function is close to the metal to cut down on the CPU cost
// of the previous incantation of Append which was implemented as
// AppendFormat( "%s", pchValue ). This implementation, though not
// as easy to read, instead does a strcpy from the existing end
// point of the CFmtStrN. This brings something like a 10-20x speedup
// in my rudimentary tests. It isn't using V_strncpy because that
// function doesn't return the number of characters copied, which
// we need to adjust m_nLength. Doing the V_strncpy with a V_strlen
// afterwards took twice as long as this implementations in tests,
// so V_strncpy's implementation was used to write this method.
char *pDest = m_szBuf + m_nLength;
const int maxLen = SIZE_BUF - m_nLength;
char *pLast = pDest + maxLen - 1;
while ( (pDest < pLast) && (*pchValue != 0) )
{
*pDest = *pchValue;
++pDest; ++pchValue;
}
*pDest = 0;
m_nLength = pDest - m_szBuf;
}
//optimized version of append for just adding a single character
void Append( char ch )
{
if( m_nLength < SIZE_BUF - 1 )
{
m_szBuf[ m_nLength ] = ch;
m_nLength++;
m_szBuf[ m_nLength ] = '\0';
}
}
void AppendIndent( uint32 unCount, char chIndent = '\t' );
void SetQuietTruncation( bool bQuiet ) { m_bQuietTruncation = bQuiet; }
protected:
virtual void InitQuietTruncation()
{
m_bQuietTruncation = QUIET_TRUNCATION;
}
bool m_bQuietTruncation;
private:
char m_szBuf[SIZE_BUF];
int m_nLength;
};
// Version which will not assert if strings are truncated
template < int SIZE_BUF >
class CFmtStrQuietTruncationN : public CFmtStrN<SIZE_BUF, true >
{
};
template< int SIZE_BUF, bool QUIET_TRUNCATION >
void CFmtStrN< SIZE_BUF, QUIET_TRUNCATION >::AppendIndent( uint32 unCount, char chIndent )
{
Assert( Length() + unCount < SIZE_BUF );
if( Length() + unCount >= SIZE_BUF )
unCount = SIZE_BUF - (1+Length());
for ( uint32 x = 0; x < unCount; x++ )
{
m_szBuf[ m_nLength++ ] = chIndent;
}
m_szBuf[ m_nLength ] = '\0';
}
template< int SIZE_BUF, bool QUIET_TRUNCATION >
void CFmtStrN< SIZE_BUF, QUIET_TRUNCATION >::AppendFormatV( const char *pchFormat, va_list args )
{
int cubPrinted = V_vsnprintf( m_szBuf+Length(), SIZE_BUF - Length(), pchFormat, args );
m_nLength += cubPrinted;
}
#if defined(POSIX)
#pragma GCC visibility pop
#endif
//-----------------------------------------------------------------------------
//
// Purpose: Default-sized string formatter
//
#define FMTSTR_STD_LEN 512
typedef CFmtStrN<FMTSTR_STD_LEN> CFmtStr;
typedef CFmtStrQuietTruncationN<FMTSTR_STD_LEN> CFmtStrQuietTruncation;
typedef CFmtStrN<1024> CFmtStr1024;
typedef CFmtStrN<8192> CFmtStrMax;
//-----------------------------------------------------------------------------
// Purpose: Fast-path number-to-string helper (with optional quoting)
// Derived off of the Steam CNumStr but with a few tweaks, such as
// trimming off the in-our-cases-unnecessary strlen calls (by not
// storing the length in the class).
//-----------------------------------------------------------------------------
class CNumStr
{
public:
CNumStr() { m_szBuf[0] = 0; }
explicit CNumStr( bool b ) { SetBool( b ); }
explicit CNumStr( int8 n8 ) { SetInt8( n8 ); }
explicit CNumStr( uint8 un8 ) { SetUint8( un8 ); }
explicit CNumStr( int16 n16 ) { SetInt16( n16 ); }
explicit CNumStr( uint16 un16 ) { SetUint16( un16 ); }
explicit CNumStr( int32 n32 ) { SetInt32( n32 ); }
explicit CNumStr( uint32 un32 ) { SetUint32( un32 ); }
explicit CNumStr( int64 n64 ) { SetInt64( n64 ); }
explicit CNumStr( uint64 un64 ) { SetUint64( un64 ); }
#if defined(COMPILER_GCC) && defined(PLATFORM_64BITS)
explicit CNumStr( lint64 n64 ) { SetInt64( (int64)n64 ); }
explicit CNumStr( ulint64 un64 ) { SetUint64( (uint64)un64 ); }
#endif
explicit CNumStr( double f ) { SetDouble( f ); }
explicit CNumStr( float f ) { SetFloat( f ); }
inline void SetBool( bool b ) { V_memcpy( m_szBuf, b ? "1" : "0", 2 ); }
#ifdef _WIN32
inline void SetInt8( int8 n8 ) { _itoa( (int32)n8, m_szBuf, 10 ); }
inline void SetUint8( uint8 un8 ) { _itoa( (int32)un8, m_szBuf, 10 ); }
inline void SetInt16( int16 n16 ) { _itoa( (int32)n16, m_szBuf, 10 ); }
inline void SetUint16( uint16 un16 ) { _itoa( (int32)un16, m_szBuf, 10 ); }
inline void SetInt32( int32 n32 ) { _itoa( n32, m_szBuf, 10 ); }
inline void SetUint32( uint32 un32 ) { _i64toa( (int64)un32, m_szBuf, 10 ); }
inline void SetInt64( int64 n64 ) { _i64toa( n64, m_szBuf, 10 ); }
inline void SetUint64( uint64 un64 ) { _ui64toa( un64, m_szBuf, 10 ); }
#else
inline void SetInt8( int8 n8 ) { Q_snprintf( m_szBuf, sizeof(m_szBuf), "%d", (int32)n8 ); }
inline void SetUint8( uint8 un8 ) { Q_snprintf( m_szBuf, sizeof(m_szBuf), "%d", (int32)un8 ); }
inline void SetInt16( int16 n16 ) { Q_snprintf( m_szBuf, sizeof(m_szBuf), "%d", (int32)n16 ); }
inline void SetUint16( uint16 un16 ) { Q_snprintf( m_szBuf, sizeof(m_szBuf), "%d", (int32)un16 ); }
inline void SetInt32( int32 n32 ) { Q_snprintf( m_szBuf, sizeof(m_szBuf), "%d", n32 ); }
inline void SetUint32( uint32 un32 ) { Q_snprintf( m_szBuf, sizeof(m_szBuf), "%u", un32 ); }
inline void SetInt64( int64 n64 ) { Q_snprintf( m_szBuf, sizeof(m_szBuf), "%lld", n64 ); }
inline void SetUint64( uint64 un64 ) { Q_snprintf( m_szBuf, sizeof(m_szBuf), "%llu", un64 ); }
#endif
inline void SetDouble( double f ) { V_snprintf( m_szBuf, sizeof(m_szBuf), "%.18g", f ); }
inline void SetFloat( float f ) { V_snprintf( m_szBuf, sizeof(m_szBuf), "%.18g", f ); }
inline void SetHexUint64( uint64 un64 ) { V_binarytohex( (byte *)&un64, sizeof( un64 ), m_szBuf, sizeof( m_szBuf ) ); }
operator const char *() const { return m_szBuf; }
const char* String() const { return m_szBuf; }
void AddQuotes()
{
Assert( m_szBuf[0] != '"' );
const int nLength = V_strlen( m_szBuf );
V_memmove( m_szBuf + 1, m_szBuf, nLength );
m_szBuf[0] = '"';
m_szBuf[nLength + 1] = '"';
m_szBuf[nLength + 2] = 0;
}
protected:
char m_szBuf[28]; // long enough to hold 18 digits of precision, a decimal, a - sign, e+### suffix, and quotes
};
//=============================================================================
bool BGetLocalFormattedDateAndTime( time_t timeVal, char *pchDate, int cubDate, char *pchTime, int cubTime );
bool BGetLocalFormattedDate( time_t timeVal, char *pchDate, int cubDate );
bool BGetLocalFormattedTime( time_t timeVal, char *pchTime, int cubTime );
#endif // FMTSTR_H

922
external/vpc/public/tier1/functors.h vendored Normal file
View File

@@ -0,0 +1,922 @@
//========== Copyright © 2006, Valve Corporation, All rights reserved. ========
//
// Purpose: Implements a generic infrastucture for functors combining
// a number of techniques to provide transparent parameter type
// deduction and packaging. Supports both member and non-member functions.
//
// See also: http://en.wikipedia.org/wiki/Function_object
//
// Note that getting into the guts of this file is not for the
// feint of heart. The core concept here is that the compiler can
// figure out all the parameter types.
//
// E.g.:
//
// struct CMyClass
// {
// void foo( int i) {}
// };
//
// int bar(int i) { return i; }
//
// CMyClass myInstance;
//
// CFunctor *pFunctor = CreateFunctor( &myInstance, CMyClass::foo, 8675 );
// CFunctor *pFunctor2 = CreateFunctor( &bar, 309 );
//
// void CallEm()
// {
// (*pFunctor)();
// (*pFunctor2)();
// }
//
//=============================================================================
#ifndef FUNCTORS_H
#define FUNCTORS_H
#if defined( _WIN32 )
#pragma once
#endif
#include "tier0/platform.h"
#include "tier1/refcount.h"
#include "tier1/utlenvelope.h"
#include <typeinfo>
//-----------------------------------------------------------------------------
//
// Macros used as basis for template generation. Just ignore the man behind the
// curtain
//
//-----------------------------------------------------------------------------
#define FUNC_SOLO_TEMPLATE_ARG_PARAMS_0
#define FUNC_TEMPLATE_ARG_PARAMS_0
#define FUNC_BASE_TEMPLATE_ARG_PARAMS_0
#define FUNC_SOLO_BASE_TEMPLATE_ARG_PARAMS_0
#define FUNC_ARG_MEMBERS_0
#define FUNC_ARG_FORMAL_PARAMS_0
#define FUNC_PROXY_ARG_FORMAL_PARAMS_0
#define FUNC_CALL_ARGS_INIT_0
#define FUNC_SOLO_CALL_ARGS_INIT_0
#define FUNC_CALL_MEMBER_ARGS_0
#define FUNC_CALL_ARGS_0
#define FUNC_CALL_DATA_ARGS_0( _var )
#define FUNC_FUNCTOR_CALL_ARGS_0
#define FUNC_TEMPLATE_FUNC_PARAMS_0
#define FUNC_BASE_TEMPLATE_FUNC_PARAMS_0
#define FUNC_VALIDATION_STRING_0 V_snprintf( pString, nBufLen, "method( void )" );
#define FUNC_SEPARATOR_0
#define FUNC_SOLO_TEMPLATE_ARG_PARAMS_1 typename ARG_TYPE_1
#define FUNC_TEMPLATE_ARG_PARAMS_1 , typename ARG_TYPE_1
#define FUNC_BASE_TEMPLATE_ARG_PARAMS_1 , ARG_TYPE_1
#define FUNC_SOLO_BASE_TEMPLATE_ARG_PARAMS_1 ARG_TYPE_1
#define FUNC_ARG_MEMBERS_1 ARG_TYPE_1 m_arg1
#define FUNC_ARG_FORMAL_PARAMS_1 , const ARG_TYPE_1 &arg1
#define FUNC_PROXY_ARG_FORMAL_PARAMS_1 const ARG_TYPE_1 &arg1
#define FUNC_CALL_ARGS_INIT_1 , m_arg1( arg1 )
#define FUNC_SOLO_CALL_ARGS_INIT_1 : m_arg1( arg1 )
#define FUNC_CALL_MEMBER_ARGS_1 m_arg1
#define FUNC_CALL_ARGS_1 arg1
#define FUNC_CALL_DATA_ARGS_1( _var ) _var->m_arg1
#define FUNC_FUNCTOR_CALL_ARGS_1 , arg1
#define FUNC_TEMPLATE_FUNC_PARAMS_1 , typename FUNC_ARG_TYPE_1
#define FUNC_BASE_TEMPLATE_FUNC_PARAMS_1 FUNC_ARG_TYPE_1
#define FUNC_VALIDATION_STRING_1 V_snprintf( pString, nBufLen, "method( %s )", typeid( ARG_TYPE_1 ).name() );
#define FUNC_SEPARATOR_1 ,
#define FUNC_SOLO_TEMPLATE_ARG_PARAMS_2 typename ARG_TYPE_1, typename ARG_TYPE_2
#define FUNC_TEMPLATE_ARG_PARAMS_2 , typename ARG_TYPE_1, typename ARG_TYPE_2
#define FUNC_BASE_TEMPLATE_ARG_PARAMS_2 , ARG_TYPE_1, ARG_TYPE_2
#define FUNC_SOLO_BASE_TEMPLATE_ARG_PARAMS_2 ARG_TYPE_1, ARG_TYPE_2
#define FUNC_ARG_MEMBERS_2 ARG_TYPE_1 m_arg1; ARG_TYPE_2 m_arg2
#define FUNC_ARG_FORMAL_PARAMS_2 , const ARG_TYPE_1 &arg1, const ARG_TYPE_2 &arg2
#define FUNC_PROXY_ARG_FORMAL_PARAMS_2 const ARG_TYPE_1 &arg1, const ARG_TYPE_2 &arg2
#define FUNC_CALL_ARGS_INIT_2 , m_arg1( arg1 ), m_arg2( arg2 )
#define FUNC_SOLO_CALL_ARGS_INIT_2 : m_arg1( arg1 ), m_arg2( arg2 )
#define FUNC_CALL_MEMBER_ARGS_2 m_arg1, m_arg2
#define FUNC_CALL_ARGS_2 arg1, arg2
#define FUNC_CALL_DATA_ARGS_2( _var ) _var->m_arg1, _var->m_arg2
#define FUNC_FUNCTOR_CALL_ARGS_2 , arg1, arg2
#define FUNC_TEMPLATE_FUNC_PARAMS_2 , typename FUNC_ARG_TYPE_1, typename FUNC_ARG_TYPE_2
#define FUNC_BASE_TEMPLATE_FUNC_PARAMS_2 FUNC_ARG_TYPE_1, FUNC_ARG_TYPE_2
#define FUNC_VALIDATION_STRING_2 V_snprintf( pString, nBufLen, "method( %s, %s )", typeid( ARG_TYPE_1 ).name(), typeid( ARG_TYPE_2 ).name() );
#define FUNC_SEPARATOR_2 ,
#define FUNC_SOLO_TEMPLATE_ARG_PARAMS_3 typename ARG_TYPE_1, typename ARG_TYPE_2, typename ARG_TYPE_3
#define FUNC_TEMPLATE_ARG_PARAMS_3 , typename ARG_TYPE_1, typename ARG_TYPE_2, typename ARG_TYPE_3
#define FUNC_BASE_TEMPLATE_ARG_PARAMS_3 , ARG_TYPE_1, ARG_TYPE_2, ARG_TYPE_3
#define FUNC_SOLO_BASE_TEMPLATE_ARG_PARAMS_3 ARG_TYPE_1, ARG_TYPE_2, ARG_TYPE_3
#define FUNC_ARG_MEMBERS_3 ARG_TYPE_1 m_arg1; ARG_TYPE_2 m_arg2; ARG_TYPE_3 m_arg3
#define FUNC_ARG_FORMAL_PARAMS_3 , const ARG_TYPE_1 &arg1, const ARG_TYPE_2 &arg2, const ARG_TYPE_3 &arg3
#define FUNC_PROXY_ARG_FORMAL_PARAMS_3 const ARG_TYPE_1 &arg1, const ARG_TYPE_2 &arg2, const ARG_TYPE_3 &arg3
#define FUNC_CALL_ARGS_INIT_3 , m_arg1( arg1 ), m_arg2( arg2 ), m_arg3( arg3 )
#define FUNC_SOLO_CALL_ARGS_INIT_3 : m_arg1( arg1 ), m_arg2( arg2 ), m_arg3( arg3 )
#define FUNC_CALL_MEMBER_ARGS_3 m_arg1, m_arg2, m_arg3
#define FUNC_CALL_ARGS_3 arg1, arg2, arg3
#define FUNC_CALL_DATA_ARGS_3( _var ) _var->m_arg1, _var->m_arg2, _var->m_arg3
#define FUNC_FUNCTOR_CALL_ARGS_3 , arg1, arg2, arg3
#define FUNC_TEMPLATE_FUNC_PARAMS_3 , typename FUNC_ARG_TYPE_1, typename FUNC_ARG_TYPE_2, typename FUNC_ARG_TYPE_3
#define FUNC_BASE_TEMPLATE_FUNC_PARAMS_3 FUNC_ARG_TYPE_1, FUNC_ARG_TYPE_2, FUNC_ARG_TYPE_3
#define FUNC_VALIDATION_STRING_3 V_snprintf( pString, nBufLen, "method( %s, %s, %s )", typeid( ARG_TYPE_1 ).name(), typeid( ARG_TYPE_2 ).name(), typeid( ARG_TYPE_3 ).name() );
#define FUNC_SEPARATOR_3 ,
#define FUNC_SOLO_TEMPLATE_ARG_PARAMS_4 typename ARG_TYPE_1, typename ARG_TYPE_2, typename ARG_TYPE_3, typename ARG_TYPE_4
#define FUNC_TEMPLATE_ARG_PARAMS_4 , typename ARG_TYPE_1, typename ARG_TYPE_2, typename ARG_TYPE_3, typename ARG_TYPE_4
#define FUNC_BASE_TEMPLATE_ARG_PARAMS_4 , ARG_TYPE_1, ARG_TYPE_2, ARG_TYPE_3, ARG_TYPE_4
#define FUNC_SOLO_BASE_TEMPLATE_ARG_PARAMS_4 ARG_TYPE_1, ARG_TYPE_2, ARG_TYPE_3, ARG_TYPE_4
#define FUNC_ARG_MEMBERS_4 ARG_TYPE_1 m_arg1; ARG_TYPE_2 m_arg2; ARG_TYPE_3 m_arg3; ARG_TYPE_4 m_arg4
#define FUNC_ARG_FORMAL_PARAMS_4 , const ARG_TYPE_1 &arg1, const ARG_TYPE_2 &arg2, const ARG_TYPE_3 &arg3, const ARG_TYPE_4 &arg4
#define FUNC_PROXY_ARG_FORMAL_PARAMS_4 const ARG_TYPE_1 &arg1, const ARG_TYPE_2 &arg2, const ARG_TYPE_3 &arg3, const ARG_TYPE_4 &arg4
#define FUNC_CALL_ARGS_INIT_4 , m_arg1( arg1 ), m_arg2( arg2 ), m_arg3( arg3 ), m_arg4( arg4 )
#define FUNC_SOLO_CALL_ARGS_INIT_4 : m_arg1( arg1 ), m_arg2( arg2 ), m_arg3( arg3 ), m_arg4( arg4 )
#define FUNC_CALL_MEMBER_ARGS_4 m_arg1, m_arg2, m_arg3, m_arg4
#define FUNC_CALL_ARGS_4 arg1, arg2, arg3, arg4
#define FUNC_CALL_DATA_ARGS_4( _var ) _var->m_arg1, _var->m_arg2, _var->m_arg3, _var->m_arg4
#define FUNC_FUNCTOR_CALL_ARGS_4 , arg1, arg2, arg3, arg4
#define FUNC_TEMPLATE_FUNC_PARAMS_4 , typename FUNC_ARG_TYPE_1, typename FUNC_ARG_TYPE_2, typename FUNC_ARG_TYPE_3, typename FUNC_ARG_TYPE_4
#define FUNC_BASE_TEMPLATE_FUNC_PARAMS_4 FUNC_ARG_TYPE_1, FUNC_ARG_TYPE_2, FUNC_ARG_TYPE_3, FUNC_ARG_TYPE_4
#define FUNC_VALIDATION_STRING_4 V_snprintf( pString, nBufLen, "method( %s, %s, %s, %s )", typeid( ARG_TYPE_1 ).name(), typeid( ARG_TYPE_2 ).name(), typeid( ARG_TYPE_3 ).name(), typeid( ARG_TYPE_4 ).name() );
#define FUNC_SEPARATOR_4 ,
#define FUNC_SOLO_TEMPLATE_ARG_PARAMS_5 typename ARG_TYPE_1, typename ARG_TYPE_2, typename ARG_TYPE_3, typename ARG_TYPE_4, typename ARG_TYPE_5
#define FUNC_TEMPLATE_ARG_PARAMS_5 , typename ARG_TYPE_1, typename ARG_TYPE_2, typename ARG_TYPE_3, typename ARG_TYPE_4, typename ARG_TYPE_5
#define FUNC_BASE_TEMPLATE_ARG_PARAMS_5 , ARG_TYPE_1, ARG_TYPE_2, ARG_TYPE_3, ARG_TYPE_4, ARG_TYPE_5
#define FUNC_SOLO_BASE_TEMPLATE_ARG_PARAMS_5 ARG_TYPE_1, ARG_TYPE_2, ARG_TYPE_3, ARG_TYPE_4, ARG_TYPE_5
#define FUNC_ARG_MEMBERS_5 ARG_TYPE_1 m_arg1; ARG_TYPE_2 m_arg2; ARG_TYPE_3 m_arg3; ARG_TYPE_4 m_arg4; ARG_TYPE_5 m_arg5
#define FUNC_ARG_FORMAL_PARAMS_5 , const ARG_TYPE_1 &arg1, const ARG_TYPE_2 &arg2, const ARG_TYPE_3 &arg3, const ARG_TYPE_4 &arg4, const ARG_TYPE_5 &arg5
#define FUNC_PROXY_ARG_FORMAL_PARAMS_5 const ARG_TYPE_1 &arg1, const ARG_TYPE_2 &arg2, const ARG_TYPE_3 &arg3, const ARG_TYPE_4 &arg4, const ARG_TYPE_5 &arg5
#define FUNC_CALL_ARGS_INIT_5 , m_arg1( arg1 ), m_arg2( arg2 ), m_arg3( arg3 ), m_arg4( arg4 ), m_arg5( arg5 )
#define FUNC_SOLO_CALL_ARGS_INIT_5 : m_arg1( arg1 ), m_arg2( arg2 ), m_arg3( arg3 ), m_arg4( arg4 ), m_arg5( arg5 )
#define FUNC_CALL_MEMBER_ARGS_5 m_arg1, m_arg2, m_arg3, m_arg4, m_arg5
#define FUNC_CALL_ARGS_5 arg1, arg2, arg3, arg4, arg5
#define FUNC_CALL_DATA_ARGS_5( _var ) _var->m_arg1, _var->m_arg2, _var->m_arg3, _var->m_arg4, _var->m_arg5
#define FUNC_FUNCTOR_CALL_ARGS_5 , arg1, arg2, arg3, arg4, arg5
#define FUNC_TEMPLATE_FUNC_PARAMS_5 , typename FUNC_ARG_TYPE_1, typename FUNC_ARG_TYPE_2, typename FUNC_ARG_TYPE_3, typename FUNC_ARG_TYPE_4, typename FUNC_ARG_TYPE_5
#define FUNC_BASE_TEMPLATE_FUNC_PARAMS_5 FUNC_ARG_TYPE_1, FUNC_ARG_TYPE_2, FUNC_ARG_TYPE_3, FUNC_ARG_TYPE_4, FUNC_ARG_TYPE_5
#define FUNC_VALIDATION_STRING_5 V_snprintf( pString, nBufLen, "method( %s, %s, %s, %s, %s )", typeid( ARG_TYPE_1 ).name(), typeid( ARG_TYPE_2 ).name(), typeid( ARG_TYPE_3 ).name(), typeid( ARG_TYPE_4 ).name(), typeid( ARG_TYPE_5 ).name() );
#define FUNC_SEPARATOR_5 ,
#define FUNC_SOLO_TEMPLATE_ARG_PARAMS_6 typename ARG_TYPE_1, typename ARG_TYPE_2, typename ARG_TYPE_3, typename ARG_TYPE_4, typename ARG_TYPE_5, typename ARG_TYPE_6
#define FUNC_TEMPLATE_ARG_PARAMS_6 , typename ARG_TYPE_1, typename ARG_TYPE_2, typename ARG_TYPE_3, typename ARG_TYPE_4, typename ARG_TYPE_5, typename ARG_TYPE_6
#define FUNC_BASE_TEMPLATE_ARG_PARAMS_6 , ARG_TYPE_1, ARG_TYPE_2, ARG_TYPE_3, ARG_TYPE_4, ARG_TYPE_5, ARG_TYPE_6
#define FUNC_SOLO_BASE_TEMPLATE_ARG_PARAMS_6 ARG_TYPE_1, ARG_TYPE_2, ARG_TYPE_3, ARG_TYPE_4, ARG_TYPE_5, ARG_TYPE_6
#define FUNC_ARG_MEMBERS_6 ARG_TYPE_1 m_arg1; ARG_TYPE_2 m_arg2; ARG_TYPE_3 m_arg3; ARG_TYPE_4 m_arg4; ARG_TYPE_5 m_arg5; ARG_TYPE_6 m_arg6
#define FUNC_ARG_FORMAL_PARAMS_6 , const ARG_TYPE_1 &arg1, const ARG_TYPE_2 &arg2, const ARG_TYPE_3 &arg3, const ARG_TYPE_4 &arg4, const ARG_TYPE_5 &arg5, const ARG_TYPE_6 &arg6
#define FUNC_PROXY_ARG_FORMAL_PARAMS_6 const ARG_TYPE_1 &arg1, const ARG_TYPE_2 &arg2, const ARG_TYPE_3 &arg3, const ARG_TYPE_4 &arg4, const ARG_TYPE_5 &arg5, const ARG_TYPE_6 &arg6
#define FUNC_CALL_ARGS_INIT_6 , m_arg1( arg1 ), m_arg2( arg2 ), m_arg3( arg3 ), m_arg4( arg4 ), m_arg5( arg5 ), m_arg6( arg6 )
#define FUNC_SOLO_CALL_ARGS_INIT_6 : m_arg1( arg1 ), m_arg2( arg2 ), m_arg3( arg3 ), m_arg4( arg4 ), m_arg5( arg5 ), m_arg6( arg6 )
#define FUNC_CALL_MEMBER_ARGS_6 m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6
#define FUNC_CALL_ARGS_6 arg1, arg2, arg3, arg4, arg5, arg6
#define FUNC_CALL_DATA_ARGS_6( _var ) _var->m_arg1, _var->m_arg2, _var->m_arg3, _var->m_arg4, _var->m_arg5, _var->m_arg6
#define FUNC_FUNCTOR_CALL_ARGS_6 , arg1, arg2, arg3, arg4, arg5, arg6
#define FUNC_TEMPLATE_FUNC_PARAMS_6 , typename FUNC_ARG_TYPE_1, typename FUNC_ARG_TYPE_2, typename FUNC_ARG_TYPE_3, typename FUNC_ARG_TYPE_4, typename FUNC_ARG_TYPE_5, typename FUNC_ARG_TYPE_6
#define FUNC_BASE_TEMPLATE_FUNC_PARAMS_6 FUNC_ARG_TYPE_1, FUNC_ARG_TYPE_2, FUNC_ARG_TYPE_3, FUNC_ARG_TYPE_4, FUNC_ARG_TYPE_5, FUNC_ARG_TYPE_6
#define FUNC_VALIDATION_STRING_6 V_snprintf( pString, nBufLen, "method( %s, %s, %s, %s, %s, %s )", typeid( ARG_TYPE_1 ).name(), typeid( ARG_TYPE_2 ).name(), typeid( ARG_TYPE_3 ).name(), typeid( ARG_TYPE_4 ).name(), typeid( ARG_TYPE_5 ).name(), typeid( ARG_TYPE_6 ).name() );
#define FUNC_SEPARATOR_6 ,
#define FUNC_SOLO_TEMPLATE_ARG_PARAMS_7 typename ARG_TYPE_1, typename ARG_TYPE_2, typename ARG_TYPE_3, typename ARG_TYPE_4, typename ARG_TYPE_5, typename ARG_TYPE_6, typename ARG_TYPE_7
#define FUNC_TEMPLATE_ARG_PARAMS_7 , typename ARG_TYPE_1, typename ARG_TYPE_2, typename ARG_TYPE_3, typename ARG_TYPE_4, typename ARG_TYPE_5, typename ARG_TYPE_6, typename ARG_TYPE_7
#define FUNC_BASE_TEMPLATE_ARG_PARAMS_7 , ARG_TYPE_1, ARG_TYPE_2, ARG_TYPE_3, ARG_TYPE_4, ARG_TYPE_5, ARG_TYPE_6, ARG_TYPE_7
#define FUNC_SOLO_BASE_TEMPLATE_ARG_PARAMS_7 ARG_TYPE_1, ARG_TYPE_2, ARG_TYPE_3, ARG_TYPE_4, ARG_TYPE_5, ARG_TYPE_6, ARG_TYPE_7
#define FUNC_ARG_MEMBERS_7 ARG_TYPE_1 m_arg1; ARG_TYPE_2 m_arg2; ARG_TYPE_3 m_arg3; ARG_TYPE_4 m_arg4; ARG_TYPE_5 m_arg5; ARG_TYPE_6 m_arg6; ARG_TYPE_7 m_arg7;
#define FUNC_ARG_FORMAL_PARAMS_7 , const ARG_TYPE_1 &arg1, const ARG_TYPE_2 &arg2, const ARG_TYPE_3 &arg3, const ARG_TYPE_4 &arg4, const ARG_TYPE_5 &arg5, const ARG_TYPE_6 &arg6, const ARG_TYPE_7 &arg7
#define FUNC_PROXY_ARG_FORMAL_PARAMS_7 const ARG_TYPE_1 &arg1, const ARG_TYPE_2 &arg2, const ARG_TYPE_3 &arg3, const ARG_TYPE_4 &arg4, const ARG_TYPE_5 &arg5, const ARG_TYPE_6 &arg6, const ARG_TYPE_7 &arg7
#define FUNC_CALL_ARGS_INIT_7 , m_arg1( arg1 ), m_arg2( arg2 ), m_arg3( arg3 ), m_arg4( arg4 ), m_arg5( arg5 ), m_arg6( arg6 ), m_arg7( arg7 )
#define FUNC_SOLO_CALL_ARGS_INIT_7 : m_arg1( arg1 ), m_arg2( arg2 ), m_arg3( arg3 ), m_arg4( arg4 ), m_arg5( arg5 ), m_arg6( arg6 ), m_arg7( arg7 )
#define FUNC_CALL_MEMBER_ARGS_7 m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7
#define FUNC_CALL_ARGS_7 arg1, arg2, arg3, arg4, arg5, arg6, arg7
#define FUNC_CALL_DATA_ARGS_7( _var ) _var->m_arg1, _var->m_arg2, _var->m_arg3, _var->m_arg4, _var->m_arg5, _var->m_arg6, _var->m_arg7
#define FUNC_FUNCTOR_CALL_ARGS_7 , arg1, arg2, arg3, arg4, arg5, arg6, arg7
#define FUNC_TEMPLATE_FUNC_PARAMS_7 , typename FUNC_ARG_TYPE_1, typename FUNC_ARG_TYPE_2, typename FUNC_ARG_TYPE_3, typename FUNC_ARG_TYPE_4, typename FUNC_ARG_TYPE_5, typename FUNC_ARG_TYPE_6, typename FUNC_ARG_TYPE_7
#define FUNC_BASE_TEMPLATE_FUNC_PARAMS_7 FUNC_ARG_TYPE_1, FUNC_ARG_TYPE_2, FUNC_ARG_TYPE_3, FUNC_ARG_TYPE_4, FUNC_ARG_TYPE_5, FUNC_ARG_TYPE_6, FUNC_ARG_TYPE_7
#define FUNC_VALIDATION_STRING_7 V_snprintf( pString, nBufLen, "method( %s, %s, %s, %s, %s, %s, %s )", typeid( ARG_TYPE_1 ).name(), typeid( ARG_TYPE_2 ).name(), typeid( ARG_TYPE_3 ).name(), typeid( ARG_TYPE_4 ).name(), typeid( ARG_TYPE_5 ).name(), typeid( ARG_TYPE_6 ).name(), typeid( ARG_TYPE_7 ).name() );
#define FUNC_SEPARATOR_7 ,
#define FUNC_SOLO_TEMPLATE_ARG_PARAMS_8 typename ARG_TYPE_1, typename ARG_TYPE_2, typename ARG_TYPE_3, typename ARG_TYPE_4, typename ARG_TYPE_5, typename ARG_TYPE_6, typename ARG_TYPE_7, typename ARG_TYPE_8
#define FUNC_TEMPLATE_ARG_PARAMS_8 , typename ARG_TYPE_1, typename ARG_TYPE_2, typename ARG_TYPE_3, typename ARG_TYPE_4, typename ARG_TYPE_5, typename ARG_TYPE_6, typename ARG_TYPE_7, typename ARG_TYPE_8
#define FUNC_BASE_TEMPLATE_ARG_PARAMS_8 , ARG_TYPE_1, ARG_TYPE_2, ARG_TYPE_3, ARG_TYPE_4, ARG_TYPE_5, ARG_TYPE_6, ARG_TYPE_7, ARG_TYPE_8
#define FUNC_SOLO_BASE_TEMPLATE_ARG_PARAMS_8 ARG_TYPE_1, ARG_TYPE_2, ARG_TYPE_3, ARG_TYPE_4, ARG_TYPE_5, ARG_TYPE_6, ARG_TYPE_7, ARG_TYPE_8
#define FUNC_ARG_MEMBERS_8 ARG_TYPE_1 m_arg1; ARG_TYPE_2 m_arg2; ARG_TYPE_3 m_arg3; ARG_TYPE_4 m_arg4; ARG_TYPE_5 m_arg5; ARG_TYPE_6 m_arg6; ARG_TYPE_7 m_arg7; ARG_TYPE_8 m_arg8;
#define FUNC_ARG_FORMAL_PARAMS_8 , const ARG_TYPE_1 &arg1, const ARG_TYPE_2 &arg2, const ARG_TYPE_3 &arg3, const ARG_TYPE_4 &arg4, const ARG_TYPE_5 &arg5, const ARG_TYPE_6 &arg6, const ARG_TYPE_7 &arg7, const ARG_TYPE_8 &arg8
#define FUNC_PROXY_ARG_FORMAL_PARAMS_8 const ARG_TYPE_1 &arg1, const ARG_TYPE_2 &arg2, const ARG_TYPE_3 &arg3, const ARG_TYPE_4 &arg4, const ARG_TYPE_5 &arg5, const ARG_TYPE_6 &arg6, const ARG_TYPE_7 &arg7, const ARG_TYPE_8 &arg8
#define FUNC_CALL_ARGS_INIT_8 , m_arg1( arg1 ), m_arg2( arg2 ), m_arg3( arg3 ), m_arg4( arg4 ), m_arg5( arg5 ), m_arg6( arg6 ), m_arg7( arg7 ), m_arg8( arg8 )
#define FUNC_SOLO_CALL_ARGS_INIT_8 : m_arg1( arg1 ), m_arg2( arg2 ), m_arg3( arg3 ), m_arg4( arg4 ), m_arg5( arg5 ), m_arg6( arg6 ), m_arg7( arg7 ), m_arg8( arg8 )
#define FUNC_CALL_MEMBER_ARGS_8 m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7, m_arg8
#define FUNC_CALL_ARGS_8 arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8
#define FUNC_CALL_DATA_ARGS_8( _var ) _var->m_arg1, _var->m_arg2, _var->m_arg3, _var->m_arg4, _var->m_arg5, _var->m_arg6, _var->m_arg7, _var->m_arg8
#define FUNC_FUNCTOR_CALL_ARGS_8 , arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8
#define FUNC_TEMPLATE_FUNC_PARAMS_8 , typename FUNC_ARG_TYPE_1, typename FUNC_ARG_TYPE_2, typename FUNC_ARG_TYPE_3, typename FUNC_ARG_TYPE_4, typename FUNC_ARG_TYPE_5, typename FUNC_ARG_TYPE_6, typename FUNC_ARG_TYPE_7, typename FUNC_ARG_TYPE_8
#define FUNC_BASE_TEMPLATE_FUNC_PARAMS_8 FUNC_ARG_TYPE_1, FUNC_ARG_TYPE_2, FUNC_ARG_TYPE_3, FUNC_ARG_TYPE_4, FUNC_ARG_TYPE_5, FUNC_ARG_TYPE_6, FUNC_ARG_TYPE_7, FUNC_ARG_TYPE_8
#define FUNC_VALIDATION_STRING_8 V_snprintf( pString, nBufLen, "method( %s, %s, %s, %s, %s, %s, %s, %s )", typeid( ARG_TYPE_1 ).name(), typeid( ARG_TYPE_2 ).name(), typeid( ARG_TYPE_3 ).name(), typeid( ARG_TYPE_4 ).name(), typeid( ARG_TYPE_5 ).name(), typeid( ARG_TYPE_6 ).name(), typeid( ARG_TYPE_7 ).name(), typeid( ARG_TYPE_8 ).name() );
#define FUNC_SEPARATOR_8 ,
#define FUNC_SOLO_TEMPLATE_ARG_PARAMS_9 typename ARG_TYPE_1, typename ARG_TYPE_2, typename ARG_TYPE_3, typename ARG_TYPE_4, typename ARG_TYPE_5, typename ARG_TYPE_6, typename ARG_TYPE_7, typename ARG_TYPE_8, typename ARG_TYPE_9
#define FUNC_TEMPLATE_ARG_PARAMS_9 , typename ARG_TYPE_1, typename ARG_TYPE_2, typename ARG_TYPE_3, typename ARG_TYPE_4, typename ARG_TYPE_5, typename ARG_TYPE_6, typename ARG_TYPE_7, typename ARG_TYPE_8, typename ARG_TYPE_9
#define FUNC_BASE_TEMPLATE_ARG_PARAMS_9 , ARG_TYPE_1, ARG_TYPE_2, ARG_TYPE_3, ARG_TYPE_4, ARG_TYPE_5, ARG_TYPE_6, ARG_TYPE_7, ARG_TYPE_8, ARG_TYPE_9
#define FUNC_SOLO_BASE_TEMPLATE_ARG_PARAMS_9 ARG_TYPE_1, ARG_TYPE_2, ARG_TYPE_3, ARG_TYPE_4, ARG_TYPE_5, ARG_TYPE_6, ARG_TYPE_7, ARG_TYPE_8, ARG_TYPE_9
#define FUNC_ARG_MEMBERS_9 ARG_TYPE_1 m_arg1; ARG_TYPE_2 m_arg2; ARG_TYPE_3 m_arg3; ARG_TYPE_4 m_arg4; ARG_TYPE_5 m_arg5; ARG_TYPE_6 m_arg6; ARG_TYPE_7 m_arg7; ARG_TYPE_8 m_arg8; ARG_TYPE_9 m_arg9;
#define FUNC_ARG_FORMAL_PARAMS_9 , const ARG_TYPE_1 &arg1, const ARG_TYPE_2 &arg2, const ARG_TYPE_3 &arg3, const ARG_TYPE_4 &arg4, const ARG_TYPE_5 &arg5, const ARG_TYPE_6 &arg6, const ARG_TYPE_7 &arg7, const ARG_TYPE_8 &arg8, const ARG_TYPE_9 &arg9
#define FUNC_PROXY_ARG_FORMAL_PARAMS_9 const ARG_TYPE_1 &arg1, const ARG_TYPE_2 &arg2, const ARG_TYPE_3 &arg3, const ARG_TYPE_4 &arg4, const ARG_TYPE_5 &arg5, const ARG_TYPE_6 &arg6, const ARG_TYPE_7 &arg7, const ARG_TYPE_8 &arg8, const ARG_TYPE_9 &arg9
#define FUNC_CALL_ARGS_INIT_9 , m_arg1( arg1 ), m_arg2( arg2 ), m_arg3( arg3 ), m_arg4( arg4 ), m_arg5( arg5 ), m_arg6( arg6 ), m_arg7( arg7 ), m_arg8( arg8 ), m_arg9( arg9 )
#define FUNC_SOLO_CALL_ARGS_INIT_9 : m_arg1( arg1 ), m_arg2( arg2 ), m_arg3( arg3 ), m_arg4( arg4 ), m_arg5( arg5 ), m_arg6( arg6 ), m_arg7( arg7 ), m_arg8( arg8 ), m_arg9( arg9 )
#define FUNC_CALL_MEMBER_ARGS_9 m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7, m_arg8, m_arg9
#define FUNC_CALL_ARGS_9 arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9
#define FUNC_CALL_DATA_ARGS_9( _var ) _var->m_arg1, _var->m_arg2, _var->m_arg3, _var->m_arg4, _var->m_arg5, _var->m_arg6, _var->m_arg7, _var->m_arg8, _var->m_arg9
#define FUNC_FUNCTOR_CALL_ARGS_9 , arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9
#define FUNC_TEMPLATE_FUNC_PARAMS_9 , typename FUNC_ARG_TYPE_1, typename FUNC_ARG_TYPE_2, typename FUNC_ARG_TYPE_3, typename FUNC_ARG_TYPE_4, typename FUNC_ARG_TYPE_5, typename FUNC_ARG_TYPE_6, typename FUNC_ARG_TYPE_7, typename FUNC_ARG_TYPE_8, typename FUNC_ARG_TYPE_9
#define FUNC_BASE_TEMPLATE_FUNC_PARAMS_9 FUNC_ARG_TYPE_1, FUNC_ARG_TYPE_2, FUNC_ARG_TYPE_3, FUNC_ARG_TYPE_4, FUNC_ARG_TYPE_5, FUNC_ARG_TYPE_6, FUNC_ARG_TYPE_7, FUNC_ARG_TYPE_8, FUNC_ARG_TYPE_9
#define FUNC_VALIDATION_STRING_9 V_snprintf( pString, nBufLen, "method( %s, %s, %s, %s, %s, %s, %s, %s, %s )", typeid( ARG_TYPE_1 ).name(), typeid( ARG_TYPE_2 ).name(), typeid( ARG_TYPE_3 ).name(), typeid( ARG_TYPE_4 ).name(), typeid( ARG_TYPE_5 ).name(), typeid( ARG_TYPE_6 ).name(), typeid( ARG_TYPE_7 ).name(), typeid( ARG_TYPE_8 ).name(), typeid( ARG_TYPE_9 ).name() );
#define FUNC_SEPARATOR_9 ,
#define FUNC_SOLO_TEMPLATE_ARG_PARAMS_10 typename ARG_TYPE_1, typename ARG_TYPE_2, typename ARG_TYPE_3, typename ARG_TYPE_4, typename ARG_TYPE_5, typename ARG_TYPE_6, typename ARG_TYPE_7, typename ARG_TYPE_8, typename ARG_TYPE_9, typename ARG_TYPE_10
#define FUNC_TEMPLATE_ARG_PARAMS_10 , typename ARG_TYPE_1, typename ARG_TYPE_2, typename ARG_TYPE_3, typename ARG_TYPE_4, typename ARG_TYPE_5, typename ARG_TYPE_6, typename ARG_TYPE_7, typename ARG_TYPE_8, typename ARG_TYPE_9, typename ARG_TYPE_10
#define FUNC_BASE_TEMPLATE_ARG_PARAMS_10 , ARG_TYPE_1, ARG_TYPE_2, ARG_TYPE_3, ARG_TYPE_4, ARG_TYPE_5, ARG_TYPE_6, ARG_TYPE_7, ARG_TYPE_8, ARG_TYPE_9, ARG_TYPE_10
#define FUNC_SOLO_BASE_TEMPLATE_ARG_PARAMS_10 ARG_TYPE_1, ARG_TYPE_2, ARG_TYPE_3, ARG_TYPE_4, ARG_TYPE_5, ARG_TYPE_6, ARG_TYPE_7, ARG_TYPE_8, ARG_TYPE_9, ARG_TYPE_10
#define FUNC_ARG_MEMBERS_10 ARG_TYPE_1 m_arg1; ARG_TYPE_2 m_arg2; ARG_TYPE_3 m_arg3; ARG_TYPE_4 m_arg4; ARG_TYPE_5 m_arg5; ARG_TYPE_6 m_arg6; ARG_TYPE_7 m_arg7; ARG_TYPE_8 m_arg8; ARG_TYPE_9 m_arg9; ARG_TYPE_10 m_arg10;
#define FUNC_ARG_FORMAL_PARAMS_10 , const ARG_TYPE_1 &arg1, const ARG_TYPE_2 &arg2, const ARG_TYPE_3 &arg3, const ARG_TYPE_4 &arg4, const ARG_TYPE_5 &arg5, const ARG_TYPE_6 &arg6, const ARG_TYPE_7 &arg7, const ARG_TYPE_8 &arg8, const ARG_TYPE_9 &arg9, const ARG_TYPE_10 &arg10
#define FUNC_PROXY_ARG_FORMAL_PARAMS_10 const ARG_TYPE_1 &arg1, const ARG_TYPE_2 &arg2, const ARG_TYPE_3 &arg3, const ARG_TYPE_4 &arg4, const ARG_TYPE_5 &arg5, const ARG_TYPE_6 &arg6, const ARG_TYPE_7 &arg7, const ARG_TYPE_8 &arg8, const ARG_TYPE_9 &arg9, const ARG_TYPE_10 &arg10
#define FUNC_CALL_ARGS_INIT_10 , m_arg1( arg1 ), m_arg2( arg2 ), m_arg3( arg3 ), m_arg4( arg4 ), m_arg5( arg5 ), m_arg6( arg6 ), m_arg7( arg7 ), m_arg8( arg8 ), m_arg9( arg9 ), m_arg10( arg10 )
#define FUNC_SOLO_CALL_ARGS_INIT_10 : m_arg1( arg1 ), m_arg2( arg2 ), m_arg3( arg3 ), m_arg4( arg4 ), m_arg5( arg5 ), m_arg6( arg6 ), m_arg7( arg7 ), m_arg8( arg8 ), m_arg9( arg9 ), m_arg10( arg10 )
#define FUNC_CALL_MEMBER_ARGS_10 m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7, m_arg8, m_arg9, m_arg10
#define FUNC_CALL_ARGS_10 arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10
#define FUNC_CALL_DATA_ARGS_10( _var ) _var->m_arg1, _var->m_arg2, _var->m_arg3, _var->m_arg4, _var->m_arg5, _var->m_arg6, _var->m_arg7, _var->m_arg8, _var->m_arg9, _var->m_arg10
#define FUNC_FUNCTOR_CALL_ARGS_10 , arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10
#define FUNC_TEMPLATE_FUNC_PARAMS_10 , typename FUNC_ARG_TYPE_1, typename FUNC_ARG_TYPE_2, typename FUNC_ARG_TYPE_3, typename FUNC_ARG_TYPE_4, typename FUNC_ARG_TYPE_5, typename FUNC_ARG_TYPE_6, typename FUNC_ARG_TYPE_7, typename FUNC_ARG_TYPE_8, typename FUNC_ARG_TYPE_9, typename FUNC_ARG_TYPE_10
#define FUNC_BASE_TEMPLATE_FUNC_PARAMS_10 FUNC_ARG_TYPE_1, FUNC_ARG_TYPE_2, FUNC_ARG_TYPE_3, FUNC_ARG_TYPE_4, FUNC_ARG_TYPE_5, FUNC_ARG_TYPE_6, FUNC_ARG_TYPE_7, FUNC_ARG_TYPE_8, FUNC_ARG_TYPE_9, FUNC_ARG_TYPE_10
#define FUNC_VALIDATION_STRING_10 V_snprintf( pString, nBufLen, "method( %s, %s, %s, %s, %s, %s, %s, %s, %s, %s )", typeid( ARG_TYPE_1 ).name(), typeid( ARG_TYPE_2 ).name(), typeid( ARG_TYPE_3 ).name(), typeid( ARG_TYPE_4 ).name(), typeid( ARG_TYPE_5 ).name(), typeid( ARG_TYPE_6 ).name(), typeid( ARG_TYPE_7 ).name(), typeid( ARG_TYPE_8 ).name(), typeid( ARG_TYPE_9 ).name(), typeid( ARG_TYPE_10 ).name() );
#define FUNC_SEPARATOR_10 ,
#define FUNC_SOLO_TEMPLATE_ARG_PARAMS_11 typename ARG_TYPE_1, typename ARG_TYPE_2, typename ARG_TYPE_3, typename ARG_TYPE_4, typename ARG_TYPE_5, typename ARG_TYPE_6, typename ARG_TYPE_7, typename ARG_TYPE_8, typename ARG_TYPE_9, typename ARG_TYPE_10, typename ARG_TYPE_11
#define FUNC_TEMPLATE_ARG_PARAMS_11 , typename ARG_TYPE_1, typename ARG_TYPE_2, typename ARG_TYPE_3, typename ARG_TYPE_4, typename ARG_TYPE_5, typename ARG_TYPE_6, typename ARG_TYPE_7, typename ARG_TYPE_8, typename ARG_TYPE_9, typename ARG_TYPE_10, typename ARG_TYPE_11
#define FUNC_BASE_TEMPLATE_ARG_PARAMS_11 , ARG_TYPE_1, ARG_TYPE_2, ARG_TYPE_3, ARG_TYPE_4, ARG_TYPE_5, ARG_TYPE_6, ARG_TYPE_7, ARG_TYPE_8, ARG_TYPE_9, ARG_TYPE_10, ARG_TYPE_11
#define FUNC_SOLO_BASE_TEMPLATE_ARG_PARAMS_11 ARG_TYPE_1, ARG_TYPE_2, ARG_TYPE_3, ARG_TYPE_4, ARG_TYPE_5, ARG_TYPE_6, ARG_TYPE_7, ARG_TYPE_8, ARG_TYPE_9, ARG_TYPE_10, ARG_TYPE_11
#define FUNC_ARG_MEMBERS_11 ARG_TYPE_1 m_arg1; ARG_TYPE_2 m_arg2; ARG_TYPE_3 m_arg3; ARG_TYPE_4 m_arg4; ARG_TYPE_5 m_arg5; ARG_TYPE_6 m_arg6; ARG_TYPE_7 m_arg7; ARG_TYPE_8 m_arg8; ARG_TYPE_9 m_arg9; ARG_TYPE_10 m_arg10; ARG_TYPE_11 m_arg11
#define FUNC_ARG_FORMAL_PARAMS_11 , const ARG_TYPE_1 &arg1, const ARG_TYPE_2 &arg2, const ARG_TYPE_3 &arg3, const ARG_TYPE_4 &arg4, const ARG_TYPE_5 &arg5, const ARG_TYPE_6 &arg6, const ARG_TYPE_7 &arg7, const ARG_TYPE_8 &arg8, const ARG_TYPE_9 &arg9, const ARG_TYPE_10 &arg10, const ARG_TYPE_11 &arg11
#define FUNC_PROXY_ARG_FORMAL_PARAMS_11 const ARG_TYPE_1 &arg1, const ARG_TYPE_2 &arg2, const ARG_TYPE_3 &arg3, const ARG_TYPE_4 &arg4, const ARG_TYPE_5 &arg5, const ARG_TYPE_6 &arg6, const ARG_TYPE_7 &arg7, const ARG_TYPE_8 &arg8, const ARG_TYPE_9 &arg9, const ARG_TYPE_10 &arg10, const ARG_TYPE_11 &arg11
#define FUNC_CALL_ARGS_INIT_11 , m_arg1( arg1 ), m_arg2( arg2 ), m_arg3( arg3 ), m_arg4( arg4 ), m_arg5( arg5 ), m_arg6( arg6 ), m_arg7( arg7 ), m_arg8( arg8 ), m_arg9( arg9 ), m_arg10( arg10 ), m_arg11( arg11 )
#define FUNC_SOLO_CALL_ARGS_INIT_11 : m_arg1( arg1 ), m_arg2( arg2 ), m_arg3( arg3 ), m_arg4( arg4 ), m_arg5( arg5 ), m_arg6( arg6 ), m_arg7( arg7 ), m_arg8( arg8 ), m_arg9( arg9 ), m_arg10( arg10 ), m_arg11( arg11 )
#define FUNC_CALL_MEMBER_ARGS_11 m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7, m_arg8, m_arg9, m_arg10, m_arg11
#define FUNC_CALL_ARGS_11 arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11
#define FUNC_CALL_DATA_ARGS_11( _var ) _var->m_arg1, _var->m_arg2, _var->m_arg3, _var->m_arg4, _var->m_arg5, _var->m_arg6, _var->m_arg7, _var->m_arg8, _var->m_arg9, _var->m_arg10, _var->m_arg11
#define FUNC_FUNCTOR_CALL_ARGS_11 , arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11
#define FUNC_TEMPLATE_FUNC_PARAMS_11 , typename FUNC_ARG_TYPE_1, typename FUNC_ARG_TYPE_2, typename FUNC_ARG_TYPE_3, typename FUNC_ARG_TYPE_4, typename FUNC_ARG_TYPE_5, typename FUNC_ARG_TYPE_6, typename FUNC_ARG_TYPE_7, typename FUNC_ARG_TYPE_8, typename FUNC_ARG_TYPE_9, typename FUNC_ARG_TYPE_10, typename FUNC_ARG_TYPE_11
#define FUNC_BASE_TEMPLATE_FUNC_PARAMS_11 FUNC_ARG_TYPE_1, FUNC_ARG_TYPE_2, FUNC_ARG_TYPE_3, FUNC_ARG_TYPE_4, FUNC_ARG_TYPE_5, FUNC_ARG_TYPE_6, FUNC_ARG_TYPE_7, FUNC_ARG_TYPE_8, FUNC_ARG_TYPE_9, FUNC_ARG_TYPE_10, FUNC_ARG_TYPE_11
#define FUNC_VALIDATION_STRING_11 V_snprintf( pString, nBufLen, "method( %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s )", typeid( ARG_TYPE_1 ).name(), typeid( ARG_TYPE_2 ).name(), typeid( ARG_TYPE_3 ).name(), typeid( ARG_TYPE_4 ).name(), typeid( ARG_TYPE_5 ).name(), typeid( ARG_TYPE_6 ).name(), typeid( ARG_TYPE_7 ).name(), typeid( ARG_TYPE_8 ).name(), typeid( ARG_TYPE_9 ).name(), typeid( ARG_TYPE_10 ).name(), typeid( ARG_TYPE_11 ).name() );
#define FUNC_SEPARATOR_11 ,
#define FUNC_SOLO_TEMPLATE_ARG_PARAMS_12 typename ARG_TYPE_1, typename ARG_TYPE_2, typename ARG_TYPE_3, typename ARG_TYPE_4, typename ARG_TYPE_5, typename ARG_TYPE_6, typename ARG_TYPE_7, typename ARG_TYPE_8, typename ARG_TYPE_9, typename ARG_TYPE_10, typename ARG_TYPE_11, typename ARG_TYPE_12
#define FUNC_TEMPLATE_ARG_PARAMS_12 , typename ARG_TYPE_1, typename ARG_TYPE_2, typename ARG_TYPE_3, typename ARG_TYPE_4, typename ARG_TYPE_5, typename ARG_TYPE_6, typename ARG_TYPE_7, typename ARG_TYPE_8, typename ARG_TYPE_9, typename ARG_TYPE_10, typename ARG_TYPE_11, typename ARG_TYPE_12
#define FUNC_BASE_TEMPLATE_ARG_PARAMS_12 , ARG_TYPE_1, ARG_TYPE_2, ARG_TYPE_3, ARG_TYPE_4, ARG_TYPE_5, ARG_TYPE_6, ARG_TYPE_7, ARG_TYPE_8, ARG_TYPE_9, ARG_TYPE_10, ARG_TYPE_11, ARG_TYPE_12
#define FUNC_SOLO_BASE_TEMPLATE_ARG_PARAMS_12 ARG_TYPE_1, ARG_TYPE_2, ARG_TYPE_3, ARG_TYPE_4, ARG_TYPE_5, ARG_TYPE_6, ARG_TYPE_7, ARG_TYPE_8, ARG_TYPE_9, ARG_TYPE_10, ARG_TYPE_11, ARG_TYPE_12
#define FUNC_ARG_MEMBERS_12 ARG_TYPE_1 m_arg1; ARG_TYPE_2 m_arg2; ARG_TYPE_3 m_arg3; ARG_TYPE_4 m_arg4; ARG_TYPE_5 m_arg5; ARG_TYPE_6 m_arg6; ARG_TYPE_7 m_arg7; ARG_TYPE_8 m_arg8; ARG_TYPE_9 m_arg9; ARG_TYPE_10 m_arg10; ARG_TYPE_11 m_arg11; ARG_TYPE_12 m_arg12
#define FUNC_ARG_FORMAL_PARAMS_12 , const ARG_TYPE_1 &arg1, const ARG_TYPE_2 &arg2, const ARG_TYPE_3 &arg3, const ARG_TYPE_4 &arg4, const ARG_TYPE_5 &arg5, const ARG_TYPE_6 &arg6, const ARG_TYPE_7 &arg7, const ARG_TYPE_8 &arg8, const ARG_TYPE_9 &arg9, const ARG_TYPE_10 &arg10, const ARG_TYPE_11 &arg11, const ARG_TYPE_12 &arg12
#define FUNC_PROXY_ARG_FORMAL_PARAMS_12 const ARG_TYPE_1 &arg1, const ARG_TYPE_2 &arg2, const ARG_TYPE_3 &arg3, const ARG_TYPE_4 &arg4, const ARG_TYPE_5 &arg5, const ARG_TYPE_6 &arg6, const ARG_TYPE_7 &arg7, const ARG_TYPE_8 &arg8, const ARG_TYPE_9 &arg9, const ARG_TYPE_10 &arg10, const ARG_TYPE_11 &arg11, const ARG_TYPE_12 &arg12
#define FUNC_CALL_ARGS_INIT_12 , m_arg1( arg1 ), m_arg2( arg2 ), m_arg3( arg3 ), m_arg4( arg4 ), m_arg5( arg5 ), m_arg6( arg6 ), m_arg7( arg7 ), m_arg8( arg8 ), m_arg9( arg9 ), m_arg10( arg10 ), m_arg11( arg11 ), m_arg12( arg12 )
#define FUNC_SOLO_CALL_ARGS_INIT_12 : m_arg1( arg1 ), m_arg2( arg2 ), m_arg3( arg3 ), m_arg4( arg4 ), m_arg5( arg5 ), m_arg6( arg6 ), m_arg7( arg7 ), m_arg8( arg8 ), m_arg9( arg9 ), m_arg10( arg10 ), m_arg11( arg11 ), m_arg12( arg12 )
#define FUNC_CALL_MEMBER_ARGS_12 m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7, m_arg8, m_arg9, m_arg10, m_arg11, m_arg12
#define FUNC_CALL_ARGS_12 arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12
#define FUNC_CALL_DATA_ARGS_12( _var ) _var->m_arg1, _var->m_arg2, _var->m_arg3, _var->m_arg4, _var->m_arg5, _var->m_arg6, _var->m_arg7, _var->m_arg8, _var->m_arg9, _var->m_arg10, _var->m_arg11, _var->m_arg12
#define FUNC_FUNCTOR_CALL_ARGS_12 , arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12
#define FUNC_TEMPLATE_FUNC_PARAMS_12 , typename FUNC_ARG_TYPE_1, typename FUNC_ARG_TYPE_2, typename FUNC_ARG_TYPE_3, typename FUNC_ARG_TYPE_4, typename FUNC_ARG_TYPE_5, typename FUNC_ARG_TYPE_6, typename FUNC_ARG_TYPE_7, typename FUNC_ARG_TYPE_8, typename FUNC_ARG_TYPE_9, typename FUNC_ARG_TYPE_10, typename FUNC_ARG_TYPE_11, typename FUNC_ARG_TYPE_12
#define FUNC_BASE_TEMPLATE_FUNC_PARAMS_12 FUNC_ARG_TYPE_1, FUNC_ARG_TYPE_2, FUNC_ARG_TYPE_3, FUNC_ARG_TYPE_4, FUNC_ARG_TYPE_5, FUNC_ARG_TYPE_6, FUNC_ARG_TYPE_7, FUNC_ARG_TYPE_8, FUNC_ARG_TYPE_9, FUNC_ARG_TYPE_10, FUNC_ARG_TYPE_11, FUNC_ARG_TYPE_12
#define FUNC_VALIDATION_STRING_12 V_snprintf( pString, nBufLen, "method( %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s )", typeid( ARG_TYPE_1 ).name(), typeid( ARG_TYPE_2 ).name(), typeid( ARG_TYPE_3 ).name(), typeid( ARG_TYPE_4 ).name(), typeid( ARG_TYPE_5 ).name(), typeid( ARG_TYPE_6 ).name(), typeid( ARG_TYPE_7 ).name(), typeid( ARG_TYPE_8 ).name(), typeid( ARG_TYPE_9 ).name(), typeid( ARG_TYPE_10 ).name(), typeid( ARG_TYPE_11 ).name(), typeid( ARG_TYPE_12 ).name() );
#define FUNC_SEPARATOR_12 ,
#define FUNC_SOLO_TEMPLATE_ARG_PARAMS_13 typename ARG_TYPE_1, typename ARG_TYPE_2, typename ARG_TYPE_3, typename ARG_TYPE_4, typename ARG_TYPE_5, typename ARG_TYPE_6, typename ARG_TYPE_7, typename ARG_TYPE_8, typename ARG_TYPE_9, typename ARG_TYPE_10, typename ARG_TYPE_11, typename ARG_TYPE_12, typename ARG_TYPE_13
#define FUNC_TEMPLATE_ARG_PARAMS_13 , typename ARG_TYPE_1, typename ARG_TYPE_2, typename ARG_TYPE_3, typename ARG_TYPE_4, typename ARG_TYPE_5, typename ARG_TYPE_6, typename ARG_TYPE_7, typename ARG_TYPE_8, typename ARG_TYPE_9, typename ARG_TYPE_10, typename ARG_TYPE_11, typename ARG_TYPE_12, typename ARG_TYPE_13
#define FUNC_BASE_TEMPLATE_ARG_PARAMS_13 , ARG_TYPE_1, ARG_TYPE_2, ARG_TYPE_3, ARG_TYPE_4, ARG_TYPE_5, ARG_TYPE_6, ARG_TYPE_7, ARG_TYPE_8, ARG_TYPE_9, ARG_TYPE_10, ARG_TYPE_11, ARG_TYPE_12, ARG_TYPE_13
#define FUNC_SOLO_BASE_TEMPLATE_ARG_PARAMS_13 ARG_TYPE_1, ARG_TYPE_2, ARG_TYPE_3, ARG_TYPE_4, ARG_TYPE_5, ARG_TYPE_6, ARG_TYPE_7, ARG_TYPE_8, ARG_TYPE_9, ARG_TYPE_10, ARG_TYPE_11, ARG_TYPE_12, ARG_TYPE_13
#define FUNC_ARG_MEMBERS_13 ARG_TYPE_1 m_arg1; ARG_TYPE_2 m_arg2; ARG_TYPE_3 m_arg3; ARG_TYPE_4 m_arg4; ARG_TYPE_5 m_arg5; ARG_TYPE_6 m_arg6; ARG_TYPE_7 m_arg7; ARG_TYPE_8 m_arg8; ARG_TYPE_9 m_arg9; ARG_TYPE_10 m_arg10; ARG_TYPE_11 m_arg11; ARG_TYPE_12 m_arg12; ARG_TYPE_13 m_arg13
#define FUNC_ARG_FORMAL_PARAMS_13 , const ARG_TYPE_1 &arg1, const ARG_TYPE_2 &arg2, const ARG_TYPE_3 &arg3, const ARG_TYPE_4 &arg4, const ARG_TYPE_5 &arg5, const ARG_TYPE_6 &arg6, const ARG_TYPE_7 &arg7, const ARG_TYPE_8 &arg8, const ARG_TYPE_9 &arg9, const ARG_TYPE_10 &arg10, const ARG_TYPE_11 &arg11, const ARG_TYPE_12 &arg12, const ARG_TYPE_13 &arg13
#define FUNC_PROXY_ARG_FORMAL_PARAMS_13 const ARG_TYPE_1 &arg1, const ARG_TYPE_2 &arg2, const ARG_TYPE_3 &arg3, const ARG_TYPE_4 &arg4, const ARG_TYPE_5 &arg5, const ARG_TYPE_6 &arg6, const ARG_TYPE_7 &arg7, const ARG_TYPE_8 &arg8, const ARG_TYPE_9 &arg9, const ARG_TYPE_10 &arg10, const ARG_TYPE_11 &arg11, const ARG_TYPE_12 &arg12, const ARG_TYPE_13 &arg13
#define FUNC_CALL_ARGS_INIT_13 , m_arg1( arg1 ), m_arg2( arg2 ), m_arg3( arg3 ), m_arg4( arg4 ), m_arg5( arg5 ), m_arg6( arg6 ), m_arg7( arg7 ), m_arg8( arg8 ), m_arg9( arg9 ), m_arg10( arg10 ), m_arg11( arg11 ), m_arg12( arg12 ), m_arg13( arg13 )
#define FUNC_SOLO_CALL_ARGS_INIT_13 : m_arg1( arg1 ), m_arg2( arg2 ), m_arg3( arg3 ), m_arg4( arg4 ), m_arg5( arg5 ), m_arg6( arg6 ), m_arg7( arg7 ), m_arg8( arg8 ), m_arg9( arg9 ), m_arg10( arg10 ), m_arg11( arg11 ), m_arg12( arg12 ), m_arg13( arg13 )
#define FUNC_CALL_MEMBER_ARGS_13 m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7, m_arg8, m_arg9, m_arg10, m_arg11, m_arg12, m_arg13
#define FUNC_CALL_ARGS_13 arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13
#define FUNC_CALL_DATA_ARGS_13( _var ) _var->m_arg1, _var->m_arg2, _var->m_arg3, _var->m_arg4, _var->m_arg5, _var->m_arg6, _var->m_arg7, _var->m_arg8, _var->m_arg9, _var->m_arg10, _var->m_arg11, _var->m_arg12, _var->m_arg13
#define FUNC_FUNCTOR_CALL_ARGS_13 , arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13
#define FUNC_TEMPLATE_FUNC_PARAMS_13 , typename FUNC_ARG_TYPE_1, typename FUNC_ARG_TYPE_2, typename FUNC_ARG_TYPE_3, typename FUNC_ARG_TYPE_4, typename FUNC_ARG_TYPE_5, typename FUNC_ARG_TYPE_6, typename FUNC_ARG_TYPE_7, typename FUNC_ARG_TYPE_8, typename FUNC_ARG_TYPE_9, typename FUNC_ARG_TYPE_10, typename FUNC_ARG_TYPE_11, typename FUNC_ARG_TYPE_12, typename FUNC_ARG_TYPE_13
#define FUNC_BASE_TEMPLATE_FUNC_PARAMS_13 FUNC_ARG_TYPE_1, FUNC_ARG_TYPE_2, FUNC_ARG_TYPE_3, FUNC_ARG_TYPE_4, FUNC_ARG_TYPE_5, FUNC_ARG_TYPE_6, FUNC_ARG_TYPE_7, FUNC_ARG_TYPE_8, FUNC_ARG_TYPE_9, FUNC_ARG_TYPE_10, FUNC_ARG_TYPE_11, FUNC_ARG_TYPE_12, FUNC_ARG_TYPE_13
#define FUNC_VALIDATION_STRING_13 V_snprintf( pString, nBufLen, "method( %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s )", typeid( ARG_TYPE_1 ).name(), typeid( ARG_TYPE_2 ).name(), typeid( ARG_TYPE_3 ).name(), typeid( ARG_TYPE_4 ).name(), typeid( ARG_TYPE_5 ).name(), typeid( ARG_TYPE_6 ).name(), typeid( ARG_TYPE_7 ).name(), typeid( ARG_TYPE_8 ).name(), typeid( ARG_TYPE_9 ).name(), typeid( ARG_TYPE_10 ).name(), typeid( ARG_TYPE_11 ).name(), typeid( ARG_TYPE_12 ).name(), typeid( ARG_TYPE_13 ).name() );
#define FUNC_SEPARATOR_13 ,
#define FUNC_SOLO_TEMPLATE_ARG_PARAMS_14 typename ARG_TYPE_1, typename ARG_TYPE_2, typename ARG_TYPE_3, typename ARG_TYPE_4, typename ARG_TYPE_5, typename ARG_TYPE_6, typename ARG_TYPE_7, typename ARG_TYPE_8, typename ARG_TYPE_9, typename ARG_TYPE_10, typename ARG_TYPE_11, typename ARG_TYPE_12, typename ARG_TYPE_13, typename ARG_TYPE_14
#define FUNC_TEMPLATE_ARG_PARAMS_14 , typename ARG_TYPE_1, typename ARG_TYPE_2, typename ARG_TYPE_3, typename ARG_TYPE_4, typename ARG_TYPE_5, typename ARG_TYPE_6, typename ARG_TYPE_7, typename ARG_TYPE_8, typename ARG_TYPE_9, typename ARG_TYPE_10, typename ARG_TYPE_11, typename ARG_TYPE_12, typename ARG_TYPE_13, typename ARG_TYPE_14
#define FUNC_BASE_TEMPLATE_ARG_PARAMS_14 , ARG_TYPE_1, ARG_TYPE_2, ARG_TYPE_3, ARG_TYPE_4, ARG_TYPE_5, ARG_TYPE_6, ARG_TYPE_7, ARG_TYPE_8, ARG_TYPE_9, ARG_TYPE_10, ARG_TYPE_11, ARG_TYPE_12, ARG_TYPE_13, ARG_TYPE_14
#define FUNC_SOLO_BASE_TEMPLATE_ARG_PARAMS_14 ARG_TYPE_1, ARG_TYPE_2, ARG_TYPE_3, ARG_TYPE_4, ARG_TYPE_5, ARG_TYPE_6, ARG_TYPE_7, ARG_TYPE_8, ARG_TYPE_9, ARG_TYPE_10, ARG_TYPE_11, ARG_TYPE_12, ARG_TYPE_13, ARG_TYPE_14
#define FUNC_ARG_MEMBERS_14 ARG_TYPE_1 m_arg1; ARG_TYPE_2 m_arg2; ARG_TYPE_3 m_arg3; ARG_TYPE_4 m_arg4; ARG_TYPE_5 m_arg5; ARG_TYPE_6 m_arg6; ARG_TYPE_7 m_arg7; ARG_TYPE_8 m_arg8; ARG_TYPE_9 m_arg9; ARG_TYPE_10 m_arg10; ARG_TYPE_11 m_arg11; ARG_TYPE_12 m_arg12; ARG_TYPE_13 m_arg13; ARG_TYPE_14 m_arg14
#define FUNC_ARG_FORMAL_PARAMS_14 , const ARG_TYPE_1 &arg1, const ARG_TYPE_2 &arg2, const ARG_TYPE_3 &arg3, const ARG_TYPE_4 &arg4, const ARG_TYPE_5 &arg5, const ARG_TYPE_6 &arg6, const ARG_TYPE_7 &arg7, const ARG_TYPE_8 &arg8, const ARG_TYPE_9 &arg9, const ARG_TYPE_10 &arg10, const ARG_TYPE_11 &arg11, const ARG_TYPE_12 &arg12, const ARG_TYPE_13 &arg13, const ARG_TYPE_14 &arg14
#define FUNC_PROXY_ARG_FORMAL_PARAMS_14 const ARG_TYPE_1 &arg1, const ARG_TYPE_2 &arg2, const ARG_TYPE_3 &arg3, const ARG_TYPE_4 &arg4, const ARG_TYPE_5 &arg5, const ARG_TYPE_6 &arg6, const ARG_TYPE_7 &arg7, const ARG_TYPE_8 &arg8, const ARG_TYPE_9 &arg9, const ARG_TYPE_10 &arg10, const ARG_TYPE_11 &arg11, const ARG_TYPE_12 &arg12, const ARG_TYPE_13 &arg13, const ARG_TYPE_14 &arg14
#define FUNC_CALL_ARGS_INIT_14 , m_arg1( arg1 ), m_arg2( arg2 ), m_arg3( arg3 ), m_arg4( arg4 ), m_arg5( arg5 ), m_arg6( arg6 ), m_arg7( arg7 ), m_arg8( arg8 ), m_arg9( arg9 ), m_arg10( arg10 ), m_arg11( arg11 ), m_arg12( arg12 ), m_arg13( arg13 ), m_arg14( arg14 )
#define FUNC_SOLO_CALL_ARGS_INIT_14 : m_arg1( arg1 ), m_arg2( arg2 ), m_arg3( arg3 ), m_arg4( arg4 ), m_arg5( arg5 ), m_arg6( arg6 ), m_arg7( arg7 ), m_arg8( arg8 ), m_arg9( arg9 ), m_arg10( arg10 ), m_arg11( arg11 ), m_arg12( arg12 ), m_arg13( arg13 ), m_arg14( arg14 )
#define FUNC_CALL_MEMBER_ARGS_14 m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7, m_arg8, m_arg9, m_arg10, m_arg11, m_arg12, m_arg13, m_arg14
#define FUNC_CALL_ARGS_14 arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14
#define FUNC_CALL_DATA_ARGS_14( _var ) _var->m_arg1, _var->m_arg2, _var->m_arg3, _var->m_arg4, _var->m_arg5, _var->m_arg6, _var->m_arg7, _var->m_arg8, _var->m_arg9, _var->m_arg10, _var->m_arg11, _var->m_arg12, _var->m_arg13, _var->m_arg14
#define FUNC_FUNCTOR_CALL_ARGS_14 , arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14
#define FUNC_TEMPLATE_FUNC_PARAMS_14 , typename FUNC_ARG_TYPE_1, typename FUNC_ARG_TYPE_2, typename FUNC_ARG_TYPE_3, typename FUNC_ARG_TYPE_4, typename FUNC_ARG_TYPE_5, typename FUNC_ARG_TYPE_6, typename FUNC_ARG_TYPE_7, typename FUNC_ARG_TYPE_8, typename FUNC_ARG_TYPE_9, typename FUNC_ARG_TYPE_10, typename FUNC_ARG_TYPE_11, typename FUNC_ARG_TYPE_12, typename FUNC_ARG_TYPE_13, typename FUNC_ARG_TYPE_14
#define FUNC_BASE_TEMPLATE_FUNC_PARAMS_14 FUNC_ARG_TYPE_1, FUNC_ARG_TYPE_2, FUNC_ARG_TYPE_3, FUNC_ARG_TYPE_4, FUNC_ARG_TYPE_5, FUNC_ARG_TYPE_6, FUNC_ARG_TYPE_7, FUNC_ARG_TYPE_8, FUNC_ARG_TYPE_9, FUNC_ARG_TYPE_10, FUNC_ARG_TYPE_11, FUNC_ARG_TYPE_12, FUNC_ARG_TYPE_13, FUNC_ARG_TYPE_14
#define FUNC_VALIDATION_STRING_14 V_snprintf( pString, nBufLen, "method( %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s )", typeid( ARG_TYPE_1 ).name(), typeid( ARG_TYPE_2 ).name(), typeid( ARG_TYPE_3 ).name(), typeid( ARG_TYPE_4 ).name(), typeid( ARG_TYPE_5 ).name(), typeid( ARG_TYPE_6 ).name(), typeid( ARG_TYPE_7 ).name(), typeid( ARG_TYPE_8 ).name(), typeid( ARG_TYPE_9 ).name(), typeid( ARG_TYPE_10 ).name(), typeid( ARG_TYPE_11 ).name(), typeid( ARG_TYPE_12 ).name(), typeid( ARG_TYPE_13 ).name(), typeid( ARG_TYPE_14 ).name() );
#define FUNC_SEPARATOR_14 ,
#define FUNC_GENERATE_ALL_BUT0( INNERMACRONAME ) \
INNERMACRONAME(1); \
INNERMACRONAME(2); \
INNERMACRONAME(3); \
INNERMACRONAME(4); \
INNERMACRONAME(5); \
INNERMACRONAME(6); \
INNERMACRONAME(7); \
INNERMACRONAME(8); \
INNERMACRONAME(9); \
INNERMACRONAME(10);\
INNERMACRONAME(11);\
INNERMACRONAME(12);\
INNERMACRONAME(13);\
INNERMACRONAME(14)
#define FUNC_GENERATE_ALL( INNERMACRONAME ) \
INNERMACRONAME(0); \
FUNC_GENERATE_ALL_BUT0( INNERMACRONAME )
//-----------------------------------------------------------------------------
//
// Purpose: Base class of all function objects
//
//-----------------------------------------------------------------------------
abstract_class CFunctor : public IRefCounted
{
public:
CFunctor()
{
#ifdef DEBUG
m_nUserID = 0;
#endif
}
virtual ~CFunctor() {}
virtual void operator()() = 0;
#ifdef DEBUG
unsigned m_nUserID; // For debugging
#endif
};
//-----------------------------------------------------------------------------
// NOTE: Functor data + functor callback are tied together
// The basic idea is that someone creates the functor data. At a later point,
// the functor data is passed to a functor callback. Validation strings
// are compared in debug builds to ensure the data matches the callback
//-----------------------------------------------------------------------------
abstract_class CFunctorData : public IRefCounted
{
public:
virtual void ComputeValidationString( char *pString, size_t nBufLen ) const = 0;
};
abstract_class CFunctorCallback : public IRefCounted
{
public:
virtual bool IsEqual( CFunctorCallback *pSrc ) const = 0;
virtual void operator()( CFunctorData *pData ) = 0;
virtual void ComputeValidationString( char *pString, size_t nBufLen ) const = 0;
virtual const char *GetImplClassName() const = 0;
virtual const void *GetTarget() const = 0;
};
//-----------------------------------------------------------------------------
// When calling through a functor, care needs to be taken to not pass objects that might go away.
// Since this code determines the type to store in the functor based on the actual arguments,
// this is achieved by changing the point of call.
//
// See also CUtlEnvelope
//-----------------------------------------------------------------------------
// convert a reference to a passable value
template <typename T>
inline T RefToVal(const T &item)
{
return item;
}
//-----------------------------------------------------------------------------
// This class can be used to pass into a functor a proxy object for a pointer
// to be resolved later. For example, you can execute a "call" on a resource
// whose actual value is not known until a later time
//-----------------------------------------------------------------------------
template <typename T>
class CLateBoundPtr
{
public:
CLateBoundPtr( T **ppObject )
: m_ppObject( ppObject )
{
}
T *operator->() { return *m_ppObject; }
T &operator *() { return **m_ppObject; }
operator T *() const { return (T*)(*m_ppObject); }
operator void *() { return *m_ppObject; }
private:
T **m_ppObject;
};
//-----------------------------------------------------------------------------
//
// Purpose: Classes to define memory management policies when operating
// on pointers to members
//
//-----------------------------------------------------------------------------
class CFuncMemPolicyNone
{
public:
static void OnAcquire(void *pObject) {}
static void OnRelease(void *pObject) {}
};
template <class OBJECT_TYPE_PTR = IRefCounted *>
class CFuncMemPolicyRefCount
{
public:
static void OnAcquire(OBJECT_TYPE_PTR pObject) { pObject->AddRef(); }
static void OnRelease(OBJECT_TYPE_PTR pObject) { pObject->Release(); }
};
//-----------------------------------------------------------------------------
//
// Purpose: Function proxy is a generic facility for holding a function
// pointer. Can be used on own, though primarily for use
// by this file
//
//-----------------------------------------------------------------------------
template <class OBJECT_TYPE_PTR, typename FUNCTION_TYPE, class MEM_POLICY = CFuncMemPolicyNone >
class CMemberFuncProxyBase
{
public:
bool operator==( const CMemberFuncProxyBase &src ) const
{
return m_pfnProxied == src.m_pfnProxied && m_pObject == src.m_pObject;
}
const void *GetTarget() const
{
return m_pObject;
}
protected:
CMemberFuncProxyBase( OBJECT_TYPE_PTR pObject, FUNCTION_TYPE pfnProxied )
: m_pObject( pObject ),
m_pfnProxied( pfnProxied )
{
MEM_POLICY::OnAcquire(m_pObject);
}
~CMemberFuncProxyBase()
{
MEM_POLICY::OnRelease(m_pObject);
}
void Set( OBJECT_TYPE_PTR pObject, FUNCTION_TYPE pfnProxied )
{
m_pfnProxied = pfnProxied;
m_pObject = pObject;
}
void OnCall()
{
Assert( (void *)m_pObject != NULL );
}
FUNCTION_TYPE m_pfnProxied;
OBJECT_TYPE_PTR m_pObject;
};
#define DEFINE_MEMBER_FUNC_PROXY( N ) \
template <class OBJECT_TYPE_PTR, typename FUNCTION_TYPE FUNC_TEMPLATE_ARG_PARAMS_##N, class MEM_POLICY = CFuncMemPolicyNone> \
class CMemberFuncProxy##N : public CMemberFuncProxyBase<OBJECT_TYPE_PTR, FUNCTION_TYPE, MEM_POLICY> \
{ \
public: \
CMemberFuncProxy##N( OBJECT_TYPE_PTR pObject = NULL, FUNCTION_TYPE pfnProxied = NULL ) \
: CMemberFuncProxyBase<OBJECT_TYPE_PTR, FUNCTION_TYPE, MEM_POLICY >( pObject, pfnProxied ) \
{ \
} \
\
void operator()( FUNC_PROXY_ARG_FORMAL_PARAMS_##N ) \
{ \
this->OnCall(); \
((*this->m_pObject).*this->m_pfnProxied)( FUNC_CALL_ARGS_##N ); \
} \
}
FUNC_GENERATE_ALL( DEFINE_MEMBER_FUNC_PROXY );
//-----------------------------------------------------------------------------
//
// The actual functor implementation
//
//-----------------------------------------------------------------------------
#include "tier0/memdbgon.h"
typedef CRefCounted1<CFunctor, CRefCountServiceMT> CFunctorBase;
#define DEFINE_FUNCTOR_TEMPLATE(N) \
template <typename FUNC_TYPE FUNC_TEMPLATE_ARG_PARAMS_##N, class FUNCTOR_BASE = CFunctorBase> \
class CFunctor##N : public CFunctorBase \
{ \
public: \
CFunctor##N( FUNC_TYPE pfnProxied FUNC_ARG_FORMAL_PARAMS_##N ) : m_pfnProxied( pfnProxied ) FUNC_CALL_ARGS_INIT_##N {} \
void operator()() { m_pfnProxied(FUNC_CALL_MEMBER_ARGS_##N); } \
\
private: \
FUNC_TYPE m_pfnProxied; \
FUNC_ARG_MEMBERS_##N; \
}
FUNC_GENERATE_ALL( DEFINE_FUNCTOR_TEMPLATE );
#define DEFINE_MEMBER_FUNCTOR( N ) \
template <class OBJECT_TYPE_PTR, typename FUNCTION_TYPE FUNC_TEMPLATE_ARG_PARAMS_##N, class FUNCTOR_BASE = CFunctorBase, class MEM_POLICY = CFuncMemPolicyNone> \
class CMemberFunctor##N : public FUNCTOR_BASE \
{ \
public: \
CMemberFunctor##N( OBJECT_TYPE_PTR pObject, FUNCTION_TYPE pfnProxied FUNC_ARG_FORMAL_PARAMS_##N ) : m_Proxy( pObject, pfnProxied ) FUNC_CALL_ARGS_INIT_##N {} \
void operator()() { m_Proxy(FUNC_CALL_MEMBER_ARGS_##N); } \
\
private: \
CMemberFuncProxy##N<OBJECT_TYPE_PTR, FUNCTION_TYPE FUNC_BASE_TEMPLATE_ARG_PARAMS_##N, MEM_POLICY> m_Proxy; \
FUNC_ARG_MEMBERS_##N; \
};
FUNC_GENERATE_ALL( DEFINE_MEMBER_FUNCTOR );
typedef CRefCounted1<CFunctorData, CRefCountServiceMT> CFunctorDataBase;
class CFunctorCallbackBase : public CRefCounted1<CFunctorCallback, CRefCountServiceMT>
{
protected:
virtual void ValidateFunctorData( CFunctorData *pData )
{
#ifdef _DEBUG
char pDataString[1024];
char pCallbackString[1024];
ComputeValidationString( pCallbackString, sizeof(pCallbackString) );
pData->ComputeValidationString( pDataString, sizeof(pDataString) );
bool bMatch = !V_stricmp( pDataString, pCallbackString );
if ( !bMatch )
{
Warning( "Functor doesn't match data!\n\tExpected:\t%s\n\tEncountered:\t%s\n",
pCallbackString, pDataString );
Assert( 0 );
}
#endif
}
};
#define DEFINE_FUNCTOR_DATA_TEMPLATE(N) \
template < FUNC_SOLO_TEMPLATE_ARG_PARAMS_##N > \
class CFunctorData##N : public CFunctorDataBase \
{ \
public: \
CFunctorData##N( FUNC_PROXY_ARG_FORMAL_PARAMS_##N ) FUNC_SOLO_CALL_ARGS_INIT_##N {} \
virtual void ComputeValidationString( char *pString, size_t nBufLen ) const { FUNC_VALIDATION_STRING_##N } \
FUNC_ARG_MEMBERS_##N; \
}
class CFunctorData0 : public CFunctorDataBase
{
public:
CFunctorData0( ) {}
virtual void ComputeValidationString( char *pString, size_t nBufLen ) const { FUNC_VALIDATION_STRING_0 }
};
FUNC_GENERATE_ALL_BUT0( DEFINE_FUNCTOR_DATA_TEMPLATE );
#define DEFINE_FUNCTOR_CALLBACK_TEMPLATE(N) \
template < FUNC_SOLO_TEMPLATE_ARG_PARAMS_##N > \
class CFunctorCallback##N : public CFunctorCallbackBase \
{ \
typedef void (*Callback_t)( FUNC_PROXY_ARG_FORMAL_PARAMS_##N ); \
public: \
CFunctorCallback##N( Callback_t pfnProxied ) : m_pfnProxied( pfnProxied ) {} \
void operator()( CFunctorData *pFunctorDataBase ) \
{ \
ValidateFunctorData( pFunctorDataBase ); \
CFunctorData##N< FUNC_SOLO_BASE_TEMPLATE_ARG_PARAMS_##N > *pFunctorData = static_cast< CFunctorData##N< FUNC_SOLO_BASE_TEMPLATE_ARG_PARAMS_##N >* >( pFunctorDataBase ); \
m_pfnProxied( FUNC_CALL_DATA_ARGS_##N(pFunctorData) ); \
} \
virtual bool IsEqual( CFunctorCallback *pSrc ) const { return !V_stricmp( GetImplClassName(), pSrc->GetImplClassName() ) && ( m_pfnProxied == static_cast< CFunctorCallback##N * >( pSrc )->m_pfnProxied ); } \
virtual void ComputeValidationString( char *pString, size_t nBufLen ) const { FUNC_VALIDATION_STRING_##N } \
virtual const char *GetImplClassName() const { return "CFunctorCallback" #N; } \
virtual const void *GetTarget() const { return m_pfnProxied; } \
private: \
Callback_t m_pfnProxied; \
}
class CFunctorCallback0 : public CFunctorCallbackBase
{
typedef void (*Callback_t)( );
public:
CFunctorCallback0( Callback_t pfnProxied ) : m_pfnProxied( pfnProxied ) {}
void operator()( CFunctorData *pFunctorDataBase )
{
ValidateFunctorData( pFunctorDataBase );
m_pfnProxied( );
}
virtual void ComputeValidationString( char *pString, size_t nBufLen ) const { FUNC_VALIDATION_STRING_0 }
virtual bool IsEqual( CFunctorCallback *pSrc ) const
{
if ( V_stricmp( GetImplClassName(), pSrc->GetImplClassName() ) )
return false;
return m_pfnProxied == static_cast< CFunctorCallback0* >( pSrc )->m_pfnProxied;
}
virtual const char *GetImplClassName() const { return "CFunctorCallback0"; }
virtual const void *GetTarget() const { return ( void * )m_pfnProxied; }
private:
Callback_t m_pfnProxied;
};
FUNC_GENERATE_ALL_BUT0( DEFINE_FUNCTOR_CALLBACK_TEMPLATE );
#define DEFINE_MEMBER_FUNCTOR_CALLBACK_TEMPLATE( N ) \
template < class FUNCTION_CLASS FUNC_TEMPLATE_ARG_PARAMS_##N, class MEM_POLICY = CFuncMemPolicyNone > \
class CMemberFunctorCallback##N : public CFunctorCallbackBase \
{ \
typedef void (FUNCTION_CLASS::*MemberCallback_t)( FUNC_PROXY_ARG_FORMAL_PARAMS_##N ); \
public: \
CMemberFunctorCallback##N( FUNCTION_CLASS *pObject, MemberCallback_t pfnProxied ) : m_Proxy( pObject, pfnProxied ) {} \
void operator()( CFunctorData *pFunctorDataBase ) \
{ \
ValidateFunctorData( pFunctorDataBase ); \
CFunctorData##N< FUNC_SOLO_BASE_TEMPLATE_ARG_PARAMS_##N > *pFunctorData = static_cast< CFunctorData##N< FUNC_SOLO_BASE_TEMPLATE_ARG_PARAMS_##N >* >( pFunctorDataBase ); \
m_Proxy( FUNC_CALL_DATA_ARGS_##N( pFunctorData ) ); \
} \
virtual void ComputeValidationString( char *pString, size_t nBufLen ) const { FUNC_VALIDATION_STRING_##N } \
virtual bool IsEqual( CFunctorCallback *pSrc ) const { return !V_stricmp( GetImplClassName(), pSrc->GetImplClassName() ) && ( m_Proxy == static_cast< CMemberFunctorCallback##N* >( pSrc )->m_Proxy ); } \
virtual const char *GetImplClassName() const { return "CMemberFunctorCallback" #N; } \
virtual const void *GetTarget() const { return m_Proxy.GetTarget(); } \
private: \
CMemberFuncProxy##N< FUNCTION_CLASS *, MemberCallback_t FUNC_BASE_TEMPLATE_ARG_PARAMS_##N, MEM_POLICY> m_Proxy; \
}
template < class FUNCTION_CLASS, class MEM_POLICY = CFuncMemPolicyNone >
class CMemberFunctorCallback0 : public CFunctorCallbackBase
{
typedef void (FUNCTION_CLASS::*MemberCallback_t)( );
public:
CMemberFunctorCallback0( FUNCTION_CLASS *pObject, MemberCallback_t pfnProxied ) : m_Proxy( pObject, pfnProxied ) {}
void operator()( CFunctorData *pFunctorDataBase )
{
ValidateFunctorData( pFunctorDataBase );
m_Proxy( );
}
virtual void ComputeValidationString( char *pString, size_t nBufLen ) const { FUNC_VALIDATION_STRING_0 }
virtual bool IsEqual( CFunctorCallback *pSrc ) const
{
if ( V_stricmp( GetImplClassName(), pSrc->GetImplClassName() ) )
return false;
return m_Proxy == static_cast< CMemberFunctorCallback0 * >( pSrc )->m_Proxy;
}
virtual const char *GetImplClassName() const { return "CMemberFunctorCallback0"; }
virtual const void *GetTarget() const { return m_Proxy.GetTarget(); }
private:
CMemberFuncProxy0< FUNCTION_CLASS *, MemberCallback_t, MEM_POLICY > m_Proxy;
};
FUNC_GENERATE_ALL_BUT0( DEFINE_MEMBER_FUNCTOR_CALLBACK_TEMPLATE );
//-----------------------------------------------------------------------------
//
// The real magic, letting the compiler figure out all the right template parameters
//
//-----------------------------------------------------------------------------
#define DEFINE_NONMEMBER_FUNCTOR_FACTORY(N) \
template <typename FUNCTION_RETTYPE FUNC_TEMPLATE_FUNC_PARAMS_##N FUNC_TEMPLATE_ARG_PARAMS_##N> \
inline CFunctor *CreateFunctor(FUNCTION_RETTYPE (*pfnProxied)( FUNC_BASE_TEMPLATE_FUNC_PARAMS_##N ) FUNC_ARG_FORMAL_PARAMS_##N ) \
{ \
typedef FUNCTION_RETTYPE (*Func_t)(FUNC_BASE_TEMPLATE_FUNC_PARAMS_##N); \
return new CFunctor##N<Func_t FUNC_BASE_TEMPLATE_ARG_PARAMS_##N>( pfnProxied FUNC_FUNCTOR_CALL_ARGS_##N ); \
}
FUNC_GENERATE_ALL( DEFINE_NONMEMBER_FUNCTOR_FACTORY );
//-------------------------------------
#define DEFINE_MEMBER_FUNCTOR_FACTORY(N) \
template <typename OBJECT_TYPE_PTR, typename FUNCTION_CLASS, typename FUNCTION_RETTYPE FUNC_TEMPLATE_FUNC_PARAMS_##N FUNC_TEMPLATE_ARG_PARAMS_##N> \
inline CFunctor *CreateFunctor(OBJECT_TYPE_PTR pObject, FUNCTION_RETTYPE ( FUNCTION_CLASS::*pfnProxied )( FUNC_BASE_TEMPLATE_FUNC_PARAMS_##N ) FUNC_ARG_FORMAL_PARAMS_##N ) \
{ \
return new CMemberFunctor##N<OBJECT_TYPE_PTR, FUNCTION_RETTYPE (FUNCTION_CLASS::*)(FUNC_BASE_TEMPLATE_FUNC_PARAMS_##N) FUNC_BASE_TEMPLATE_ARG_PARAMS_##N>(pObject, pfnProxied FUNC_FUNCTOR_CALL_ARGS_##N); \
}
FUNC_GENERATE_ALL( DEFINE_MEMBER_FUNCTOR_FACTORY );
//-------------------------------------
#define DEFINE_CONST_MEMBER_FUNCTOR_FACTORY(N) \
template <typename OBJECT_TYPE_PTR, typename FUNCTION_CLASS, typename FUNCTION_RETTYPE FUNC_TEMPLATE_FUNC_PARAMS_##N FUNC_TEMPLATE_ARG_PARAMS_##N> \
inline CFunctor *CreateFunctor(OBJECT_TYPE_PTR pObject, FUNCTION_RETTYPE ( FUNCTION_CLASS::*pfnProxied )( FUNC_BASE_TEMPLATE_FUNC_PARAMS_##N ) const FUNC_ARG_FORMAL_PARAMS_##N ) \
{ \
return new CMemberFunctor##N<OBJECT_TYPE_PTR, FUNCTION_RETTYPE (FUNCTION_CLASS::*)(FUNC_BASE_TEMPLATE_FUNC_PARAMS_##N) const FUNC_BASE_TEMPLATE_ARG_PARAMS_##N>(pObject, pfnProxied FUNC_FUNCTOR_CALL_ARGS_##N); \
}
FUNC_GENERATE_ALL( DEFINE_CONST_MEMBER_FUNCTOR_FACTORY );
//-------------------------------------
#define DEFINE_REF_COUNTING_MEMBER_FUNCTOR_FACTORY(N) \
template <typename OBJECT_TYPE_PTR, typename FUNCTION_CLASS, typename FUNCTION_RETTYPE FUNC_TEMPLATE_FUNC_PARAMS_##N FUNC_TEMPLATE_ARG_PARAMS_##N> \
inline CFunctor *CreateRefCountingFunctor(OBJECT_TYPE_PTR pObject, FUNCTION_RETTYPE ( FUNCTION_CLASS::*pfnProxied )( FUNC_BASE_TEMPLATE_FUNC_PARAMS_##N ) FUNC_ARG_FORMAL_PARAMS_##N ) \
{ \
return new CMemberFunctor##N<OBJECT_TYPE_PTR, FUNCTION_RETTYPE (FUNCTION_CLASS::*)(FUNC_BASE_TEMPLATE_FUNC_PARAMS_##N) FUNC_BASE_TEMPLATE_ARG_PARAMS_##N, CFuncMemPolicyRefCount<OBJECT_TYPE_PTR> >(pObject, pfnProxied FUNC_FUNCTOR_CALL_ARGS_##N); \
}
FUNC_GENERATE_ALL( DEFINE_REF_COUNTING_MEMBER_FUNCTOR_FACTORY );
//-------------------------------------
#define DEFINE_REF_COUNTING_CONST_MEMBER_FUNCTOR_FACTORY(N) \
template <typename OBJECT_TYPE_PTR, typename FUNCTION_CLASS, typename FUNCTION_RETTYPE FUNC_TEMPLATE_FUNC_PARAMS_##N FUNC_TEMPLATE_ARG_PARAMS_##N> \
inline CFunctor *CreateRefCountingFunctor(OBJECT_TYPE_PTR pObject, FUNCTION_RETTYPE ( FUNCTION_CLASS::*pfnProxied )( FUNC_BASE_TEMPLATE_FUNC_PARAMS_##N ) const FUNC_ARG_FORMAL_PARAMS_##N ) \
{ \
return new CMemberFunctor##N<OBJECT_TYPE_PTR, FUNCTION_RETTYPE (FUNCTION_CLASS::*)(FUNC_BASE_TEMPLATE_FUNC_PARAMS_##N) const FUNC_BASE_TEMPLATE_ARG_PARAMS_##N, CFuncMemPolicyRefCount<OBJECT_TYPE_PTR> >(pObject, pfnProxied FUNC_FUNCTOR_CALL_ARGS_##N); \
}
FUNC_GENERATE_ALL( DEFINE_REF_COUNTING_CONST_MEMBER_FUNCTOR_FACTORY );
#define DEFINE_FUNCTOR_DATA_FACTORY(N) \
template < FUNC_SOLO_TEMPLATE_ARG_PARAMS_##N > \
inline CFunctorData *CreateFunctorData( FUNC_PROXY_ARG_FORMAL_PARAMS_##N ) \
{ \
return new CFunctorData##N< FUNC_SOLO_BASE_TEMPLATE_ARG_PARAMS_##N >( FUNC_CALL_ARGS_##N ); \
}
inline CFunctorData *CreateFunctorData()
{
return new CFunctorData0();
}
FUNC_GENERATE_ALL_BUT0( DEFINE_FUNCTOR_DATA_FACTORY );
#define DEFINE_FUNCTOR_CALLBACK_FACTORY(N) \
template < FUNC_SOLO_TEMPLATE_ARG_PARAMS_##N > \
inline CFunctorCallback *CreateFunctorCallback( void (*pfnProxied)( FUNC_PROXY_ARG_FORMAL_PARAMS_##N ) ) \
{ \
return new CFunctorCallback##N< FUNC_SOLO_BASE_TEMPLATE_ARG_PARAMS_##N >( pfnProxied ); \
}
inline CFunctorCallback *CreateFunctorCallback( void (*pfnProxied)() )
{
return new CFunctorCallback0( pfnProxied );
}
FUNC_GENERATE_ALL_BUT0( DEFINE_FUNCTOR_CALLBACK_FACTORY );
#define DEFINE_MEMBER_FUNCTOR_CALLBACK_FACTORY(N) \
template < typename FUNCTION_CLASS FUNC_TEMPLATE_ARG_PARAMS_##N > \
inline CFunctorCallback *CreateFunctorCallback( FUNCTION_CLASS *pObject, void ( FUNCTION_CLASS::*pfnProxied )( FUNC_PROXY_ARG_FORMAL_PARAMS_##N ) ) \
{ \
return new CMemberFunctorCallback##N< FUNCTION_CLASS FUNC_BASE_TEMPLATE_ARG_PARAMS_##N >( pObject, pfnProxied ); \
}
FUNC_GENERATE_ALL( DEFINE_MEMBER_FUNCTOR_CALLBACK_FACTORY );
//-----------------------------------------------------------------------------
//
// Templates to assist early-out direct call code
//
//-----------------------------------------------------------------------------
#define DEFINE_NONMEMBER_FUNCTOR_DIRECT(N) \
template <typename FUNCTION_RETTYPE FUNC_TEMPLATE_FUNC_PARAMS_##N FUNC_TEMPLATE_ARG_PARAMS_##N> \
inline void FunctorDirectCall(FUNCTION_RETTYPE (*pfnProxied)( FUNC_BASE_TEMPLATE_FUNC_PARAMS_##N ) FUNC_ARG_FORMAL_PARAMS_##N ) \
{ \
(*pfnProxied)( FUNC_CALL_ARGS_##N ); \
}
FUNC_GENERATE_ALL( DEFINE_NONMEMBER_FUNCTOR_DIRECT );
//-------------------------------------
#define DEFINE_MEMBER_FUNCTOR_DIRECT(N) \
template <typename OBJECT_TYPE_PTR, typename FUNCTION_CLASS, typename FUNCTION_RETTYPE FUNC_TEMPLATE_FUNC_PARAMS_##N FUNC_TEMPLATE_ARG_PARAMS_##N> \
inline void FunctorDirectCall(OBJECT_TYPE_PTR pObject, FUNCTION_RETTYPE ( FUNCTION_CLASS::*pfnProxied )( FUNC_BASE_TEMPLATE_FUNC_PARAMS_##N ) FUNC_ARG_FORMAL_PARAMS_##N ) \
{ \
((*pObject).*pfnProxied)(FUNC_CALL_ARGS_##N); \
}
FUNC_GENERATE_ALL( DEFINE_MEMBER_FUNCTOR_DIRECT );
//-------------------------------------
#define DEFINE_CONST_MEMBER_FUNCTOR_DIRECT(N) \
template <typename OBJECT_TYPE_PTR, typename FUNCTION_CLASS, typename FUNCTION_RETTYPE FUNC_TEMPLATE_FUNC_PARAMS_##N FUNC_TEMPLATE_ARG_PARAMS_##N> \
inline void FunctorDirectCall(OBJECT_TYPE_PTR pObject, FUNCTION_RETTYPE ( FUNCTION_CLASS::*pfnProxied )( FUNC_BASE_TEMPLATE_FUNC_PARAMS_##N ) const FUNC_ARG_FORMAL_PARAMS_##N ) \
{ \
((*pObject).*pfnProxied)(FUNC_CALL_ARGS_##N); \
}
FUNC_GENERATE_ALL( DEFINE_CONST_MEMBER_FUNCTOR_DIRECT );
#include "tier0/memdbgoff.h"
//-----------------------------------------------------------------------------
// Factory class useable as templated traits
//-----------------------------------------------------------------------------
class CDefaultFunctorFactory
{
public:
FUNC_GENERATE_ALL( DEFINE_NONMEMBER_FUNCTOR_FACTORY );
FUNC_GENERATE_ALL( DEFINE_MEMBER_FUNCTOR_FACTORY );
FUNC_GENERATE_ALL( DEFINE_CONST_MEMBER_FUNCTOR_FACTORY );
FUNC_GENERATE_ALL( DEFINE_REF_COUNTING_MEMBER_FUNCTOR_FACTORY );
FUNC_GENERATE_ALL( DEFINE_REF_COUNTING_CONST_MEMBER_FUNCTOR_FACTORY );
};
template <class CAllocator, class CCustomFunctorBase = CFunctorBase>
class CCustomizedFunctorFactory
{
public:
void SetAllocator( CAllocator *pAllocator )
{
m_pAllocator = pAllocator;
}
#define DEFINE_NONMEMBER_FUNCTOR_FACTORY_CUSTOM(N) \
template <typename FUNCTION_RETTYPE FUNC_TEMPLATE_FUNC_PARAMS_##N FUNC_TEMPLATE_ARG_PARAMS_##N> \
inline CFunctor *CreateFunctor( FUNCTION_RETTYPE (*pfnProxied)( FUNC_BASE_TEMPLATE_FUNC_PARAMS_##N ) FUNC_ARG_FORMAL_PARAMS_##N ) \
{ \
typedef FUNCTION_RETTYPE (*Func_t)(FUNC_BASE_TEMPLATE_FUNC_PARAMS_##N); \
return new (m_pAllocator->Alloc( sizeof(CFunctor##N<Func_t FUNC_BASE_TEMPLATE_ARG_PARAMS_##N, CCustomFunctorBase>) )) CFunctor##N<Func_t FUNC_BASE_TEMPLATE_ARG_PARAMS_##N, CCustomFunctorBase>( pfnProxied FUNC_FUNCTOR_CALL_ARGS_##N ); \
}
FUNC_GENERATE_ALL( DEFINE_NONMEMBER_FUNCTOR_FACTORY_CUSTOM );
//-------------------------------------
#define DEFINE_MEMBER_FUNCTOR_FACTORY_CUSTOM(N) \
template <typename OBJECT_TYPE_PTR, typename FUNCTION_CLASS, typename FUNCTION_RETTYPE FUNC_TEMPLATE_FUNC_PARAMS_##N FUNC_TEMPLATE_ARG_PARAMS_##N> \
inline CFunctor *CreateFunctor(OBJECT_TYPE_PTR pObject, FUNCTION_RETTYPE ( FUNCTION_CLASS::*pfnProxied )( FUNC_BASE_TEMPLATE_FUNC_PARAMS_##N ) FUNC_ARG_FORMAL_PARAMS_##N ) \
{ \
return new (m_pAllocator->Alloc( sizeof(CMemberFunctor##N<OBJECT_TYPE_PTR, FUNCTION_RETTYPE (FUNCTION_CLASS::*)(FUNC_BASE_TEMPLATE_FUNC_PARAMS_##N) FUNC_BASE_TEMPLATE_ARG_PARAMS_##N, CCustomFunctorBase>) )) CMemberFunctor##N<OBJECT_TYPE_PTR, FUNCTION_RETTYPE (FUNCTION_CLASS::*)(FUNC_BASE_TEMPLATE_FUNC_PARAMS_##N) FUNC_BASE_TEMPLATE_ARG_PARAMS_##N, CCustomFunctorBase>(pObject, pfnProxied FUNC_FUNCTOR_CALL_ARGS_##N); \
}
FUNC_GENERATE_ALL( DEFINE_MEMBER_FUNCTOR_FACTORY_CUSTOM );
//-------------------------------------
#define DEFINE_CONST_MEMBER_FUNCTOR_FACTORY_CUSTOM(N) \
template <typename OBJECT_TYPE_PTR, typename FUNCTION_CLASS, typename FUNCTION_RETTYPE FUNC_TEMPLATE_FUNC_PARAMS_##N FUNC_TEMPLATE_ARG_PARAMS_##N> \
inline CFunctor *CreateFunctor( OBJECT_TYPE_PTR pObject, FUNCTION_RETTYPE ( FUNCTION_CLASS::*pfnProxied )( FUNC_BASE_TEMPLATE_FUNC_PARAMS_##N ) const FUNC_ARG_FORMAL_PARAMS_##N ) \
{ \
return new (m_pAllocator->Alloc( sizeof(CMemberFunctor##N<OBJECT_TYPE_PTR, FUNCTION_RETTYPE (FUNCTION_CLASS::*)(FUNC_BASE_TEMPLATE_FUNC_PARAMS_##N) const FUNC_BASE_TEMPLATE_ARG_PARAMS_##N, CCustomFunctorBase>) )) CMemberFunctor##N<OBJECT_TYPE_PTR, FUNCTION_RETTYPE (FUNCTION_CLASS::*)(FUNC_BASE_TEMPLATE_FUNC_PARAMS_##N) const FUNC_BASE_TEMPLATE_ARG_PARAMS_##N, CCustomFunctorBase>(pObject, pfnProxied FUNC_FUNCTOR_CALL_ARGS_##N); \
}
FUNC_GENERATE_ALL( DEFINE_CONST_MEMBER_FUNCTOR_FACTORY_CUSTOM );
//-------------------------------------
#define DEFINE_REF_COUNTING_MEMBER_FUNCTOR_FACTORY_CUSTOM(N) \
template <typename OBJECT_TYPE_PTR, typename FUNCTION_CLASS, typename FUNCTION_RETTYPE FUNC_TEMPLATE_FUNC_PARAMS_##N FUNC_TEMPLATE_ARG_PARAMS_##N> \
inline CFunctor *CreateRefCountingFunctor( OBJECT_TYPE_PTR pObject, FUNCTION_RETTYPE ( FUNCTION_CLASS::*pfnProxied )( FUNC_BASE_TEMPLATE_FUNC_PARAMS_##N ) FUNC_ARG_FORMAL_PARAMS_##N ) \
{ \
return new (m_pAllocator->Alloc( sizeof(CMemberFunctor##N<OBJECT_TYPE_PTR, FUNCTION_RETTYPE (FUNCTION_CLASS::*)(FUNC_BASE_TEMPLATE_FUNC_PARAMS_##N) FUNC_BASE_TEMPLATE_ARG_PARAMS_##N, CCustomFunctorBase, CFuncMemPolicyRefCount<OBJECT_TYPE_PTR> >) )) CMemberFunctor##N<OBJECT_TYPE_PTR, FUNCTION_RETTYPE (FUNCTION_CLASS::*)(FUNC_BASE_TEMPLATE_FUNC_PARAMS_##N) FUNC_BASE_TEMPLATE_ARG_PARAMS_##N, CCustomFunctorBase, CFuncMemPolicyRefCount<OBJECT_TYPE_PTR> >(pObject, pfnProxied FUNC_FUNCTOR_CALL_ARGS_##N); \
}
FUNC_GENERATE_ALL( DEFINE_REF_COUNTING_MEMBER_FUNCTOR_FACTORY_CUSTOM );
//-------------------------------------
#define DEFINE_REF_COUNTING_CONST_MEMBER_FUNCTOR_FACTORY_CUSTOM(N) \
template <typename OBJECT_TYPE_PTR, typename FUNCTION_CLASS, typename FUNCTION_RETTYPE FUNC_TEMPLATE_FUNC_PARAMS_##N FUNC_TEMPLATE_ARG_PARAMS_##N> \
inline CFunctor *CreateRefCountingFunctor( OBJECT_TYPE_PTR pObject, FUNCTION_RETTYPE ( FUNCTION_CLASS::*pfnProxied )( FUNC_BASE_TEMPLATE_FUNC_PARAMS_##N ) const FUNC_ARG_FORMAL_PARAMS_##N ) \
{ \
return new (m_pAllocator->Alloc( sizeof(CMemberFunctor##N<OBJECT_TYPE_PTR, FUNCTION_RETTYPE (FUNCTION_CLASS::*)(FUNC_BASE_TEMPLATE_FUNC_PARAMS_##N) const FUNC_BASE_TEMPLATE_ARG_PARAMS_##N, CCustomFunctorBase, CFuncMemPolicyRefCount<OBJECT_TYPE_PTR> >) )) CMemberFunctor##N<OBJECT_TYPE_PTR, FUNCTION_RETTYPE (FUNCTION_CLASS::*)(FUNC_BASE_TEMPLATE_FUNC_PARAMS_##N) const FUNC_BASE_TEMPLATE_ARG_PARAMS_##N, CCustomFunctorBase, CFuncMemPolicyRefCount<OBJECT_TYPE_PTR> >(pObject, pfnProxied FUNC_FUNCTOR_CALL_ARGS_##N); \
}
FUNC_GENERATE_ALL( DEFINE_REF_COUNTING_CONST_MEMBER_FUNCTOR_FACTORY_CUSTOM );
private:
CAllocator *m_pAllocator;
};
//-----------------------------------------------------------------------------
#endif // FUNCTORS_H

116
external/vpc/public/tier1/generichash.h vendored Normal file
View File

@@ -0,0 +1,116 @@
//======= Copyright <20> 2005, , Valve Corporation, All rights reserved. =========
//
// Purpose: Variant Pearson Hash general purpose hashing algorithm described
// by Cargill in C++ Report 1994. Generates a 16-bit result.
//
//=============================================================================
#ifndef GENERICHASH_H
#define GENERICHASH_H
#if defined(_WIN32)
#pragma once
#endif
//-----------------------------------------------------------------------------
unsigned FASTCALL HashString( const char *pszKey );
unsigned FASTCALL HashStringCaseless( const char *pszKey );
unsigned FASTCALL HashStringCaselessConventional( const char *pszKey );
unsigned FASTCALL Hash4( const void *pKey );
unsigned FASTCALL Hash8( const void *pKey );
unsigned FASTCALL Hash12( const void *pKey );
unsigned FASTCALL Hash16( const void *pKey );
unsigned FASTCALL HashBlock( const void *pKey, unsigned size );
unsigned FASTCALL HashInt( const int key );
// hash a uint32 into a uint32
FORCEINLINE uint32 HashIntAlternate( uint32 n)
{
n = ( n + 0x7ed55d16 ) + ( n << 12 );
n = ( n ^ 0xc761c23c ) ^ ( n >> 19 );
n = ( n + 0x165667b1 ) + ( n << 5 );
n = ( n + 0xd3a2646c ) ^ ( n << 9 );
n = ( n + 0xfd7046c5 ) + ( n << 3 );
n = ( n ^ 0xb55a4f09 ) ^ ( n >> 16 );
return n;
}
inline unsigned HashIntConventional( const int n ) // faster but less effective
{
// first byte
unsigned hash = 0xAAAAAAAA + (n & 0xFF);
// second byte
hash = ( hash << 5 ) + hash + ( (n >> 8) & 0xFF );
// third byte
hash = ( hash << 5 ) + hash + ( (n >> 16) & 0xFF );
// fourth byte
hash = ( hash << 5 ) + hash + ( (n >> 24) & 0xFF );
return hash;
/* this is the old version, which would cause a load-hit-store on every
line on a PowerPC, and therefore took hundreds of clocks to execute!
byte *p = (byte *)&n;
unsigned hash = 0xAAAAAAAA + *p++;
hash = ( ( hash << 5 ) + hash ) + *p++;
hash = ( ( hash << 5 ) + hash ) + *p++;
return ( ( hash << 5 ) + hash ) + *p;
*/
}
//-----------------------------------------------------------------------------
template <typename T>
inline unsigned HashItem( const T &item )
{
// TODO: Confirm comiler optimizes out unused paths
if ( sizeof(item) == 4 )
return Hash4( &item );
else if ( sizeof(item) == 8 )
return Hash8( &item );
else if ( sizeof(item) == 12 )
return Hash12( &item );
else if ( sizeof(item) == 16 )
return Hash16( &item );
else
return HashBlock( &item, sizeof(item) );
}
template <> inline unsigned HashItem<int>(const int &key )
{
return HashInt( key );
}
template <> inline unsigned HashItem<unsigned>(const unsigned &key )
{
return HashInt( (int)key );
}
template<> inline unsigned HashItem<const char *>(const char * const &pszKey )
{
return HashString( pszKey );
}
template<> inline unsigned HashItem<char *>(char * const &pszKey )
{
return HashString( pszKey );
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// Murmur hash
//-----------------------------------------------------------------------------
uint32 MurmurHash2( const void * key, int len, uint32 seed );
// return murmurhash2 of a downcased string
uint32 MurmurHash2LowerCase( char const *pString, uint32 nSeed );
uint64 MurmurHash64( const void * key, int len, uint32 seed );
#endif /* !GENERICHASH_H */

121
external/vpc/public/tier1/iconvar.h vendored Normal file
View File

@@ -0,0 +1,121 @@
//===== Copyright (c) 1996-2005, Valve Corporation, All rights reserved. ======//
//
// Purpose:
//
// $Workfile: $
// $Date: $
//
//-----------------------------------------------------------------------------
// $NoKeywords: $
//===========================================================================//
#ifndef ICONVAR_H
#define ICONVAR_H
#if _WIN32
#pragma once
#endif
#include "tier0/dbg.h"
#include "tier0/platform.h"
#include "tier1/strtools.h"
#include "color.h"
//-----------------------------------------------------------------------------
// Forward declarations
//-----------------------------------------------------------------------------
class IConVar;
class CCommand;
//-----------------------------------------------------------------------------
// ConVar flags
//-----------------------------------------------------------------------------
// The default, no flags at all
#define FCVAR_NONE 0
// Command to ConVars and ConCommands
// ConVar Systems
#define FCVAR_UNREGISTERED (1<<0) // If this is set, don't add to linked list, etc.
#define FCVAR_DEVELOPMENTONLY (1<<1) // Hidden in released products. Flag is removed automatically if ALLOW_DEVELOPMENT_CVARS is defined.
#define FCVAR_GAMEDLL (1<<2) // defined by the game DLL
#define FCVAR_CLIENTDLL (1<<3) // defined by the client DLL
#define FCVAR_HIDDEN (1<<4) // Hidden. Doesn't appear in find or auto complete. Like DEVELOPMENTONLY, but can't be compiled out.
// ConVar only
#define FCVAR_PROTECTED (1<<5) // It's a server cvar, but we don't send the data since it's a password, etc. Sends 1 if it's not bland/zero, 0 otherwise as value
#define FCVAR_SPONLY (1<<6) // This cvar cannot be changed by clients connected to a multiplayer server.
#define FCVAR_ARCHIVE (1<<7) // set to cause it to be saved to vars.rc
#define FCVAR_NOTIFY (1<<8) // notifies players when changed
#define FCVAR_USERINFO (1<<9) // changes the client's info string
#define FCVAR_PRINTABLEONLY (1<<10) // This cvar's string cannot contain unprintable characters ( e.g., used for player name etc ).
#define FCVAR_UNLOGGED (1<<11) // If this is a FCVAR_SERVER, don't log changes to the log file / console if we are creating a log
#define FCVAR_NEVER_AS_STRING (1<<12) // never try to print that cvar
// It's a ConVar that's shared between the client and the server.
// At signon, the values of all such ConVars are sent from the server to the client (skipped for local
// client, of course )
// If a change is requested it must come from the console (i.e., no remote client changes)
// If a value is changed while a server is active, it's replicated to all connected clients
#define FCVAR_REPLICATED (1<<13) // server setting enforced on clients, TODO rename to FCAR_SERVER at some time
#define FCVAR_CHEAT (1<<14) // Only useable in singleplayer / debug / multiplayer & sv_cheats
#define FCVAR_SS (1<<15) // causes varnameN where N == 2 through max splitscreen slots for mod to be autogenerated
#define FCVAR_DEMO (1<<16) // record this cvar when starting a demo file
#define FCVAR_DONTRECORD (1<<17) // don't record these command in demofiles
#define FCVAR_SS_ADDED (1<<18) // This is one of the "added" FCVAR_SS variables for the splitscreen players
#define FCVAR_RELEASE (1<<19) // Cvars tagged with this are the only cvars avaliable to customers
#define FCVAR_RELOAD_MATERIALS (1<<20) // If this cvar changes, it forces a material reload
#define FCVAR_RELOAD_TEXTURES (1<<21) // If this cvar changes, if forces a texture reload
#define FCVAR_NOT_CONNECTED (1<<22) // cvar cannot be changed by a client that is connected to a server
#define FCVAR_MATERIAL_SYSTEM_THREAD (1<<23) // Indicates this cvar is read from the material system thread
#define FCVAR_ARCHIVE_GAMECONSOLE (1<<24) // cvar written to config.cfg on the Xbox
#define FCVAR_SERVER_CAN_EXECUTE (1<<28)// the server is allowed to execute this command on clients via ClientCommand/NET_StringCmd/CBaseClientState::ProcessStringCmd.
#define FCVAR_SERVER_CANNOT_QUERY (1<<29)// If this is set, then the server is not allowed to query this cvar's value (via IServerPluginHelpers::StartQueryCvarValue).
#define FCVAR_CLIENTCMD_CAN_EXECUTE (1<<30) // IVEngineClient::ClientCmd is allowed to execute this command.
// Note: IVEngineClient::ClientCmd_Unrestricted can run any client command.
#define FCVAR_ACCESSIBLE_FROM_THREADS (1<<25) // used as a debugging tool necessary to check material system thread convars
// #define FCVAR_AVAILABLE (1<<26)
// #define FCVAR_AVAILABLE (1<<27)
// #define FCVAR_AVAILABLE (1<<31)
#define FCVAR_MATERIAL_THREAD_MASK ( FCVAR_RELOAD_MATERIALS | FCVAR_RELOAD_TEXTURES | FCVAR_MATERIAL_SYSTEM_THREAD )
//-----------------------------------------------------------------------------
// Called when a ConVar changes value
// NOTE: For FCVAR_NEVER_AS_STRING ConVars, pOldValue == NULL
//-----------------------------------------------------------------------------
typedef void ( *FnChangeCallback_t )( IConVar *var, const char *pOldValue, float flOldValue );
//-----------------------------------------------------------------------------
// Abstract interface for ConVars
//-----------------------------------------------------------------------------
abstract_class IConVar
{
public:
// Value set
virtual void SetValue( const char *pValue ) = 0;
virtual void SetValue( float flValue ) = 0;
virtual void SetValue( int nValue ) = 0;
virtual void SetValue( Color value ) = 0;
// Return name of command
virtual const char *GetName( void ) const = 0;
// Return name of command (usually == GetName(), except in case of FCVAR_SS_ADDED vars
virtual const char *GetBaseName( void ) const = 0;
// Accessors.. not as efficient as using GetState()/GetInfo()
// if you call these methods multiple times on the same IConVar
virtual bool IsFlagSet( int nFlag ) const = 0;
virtual int GetSplitScreenPlayerSlot() const = 0;
};
#endif // ICONVAR_H

226
external/vpc/public/tier1/interface.h vendored Normal file
View File

@@ -0,0 +1,226 @@
//========= Copyright (c) 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//
//=============================================================================//
// This header defines the interface convention used in the valve engine.
// To make an interface and expose it:
// 1. The interface must be ALL pure virtuals, and have no data members.
// 2. Define a name for it.
// 3. In its implementation file, use EXPOSE_INTERFACE or EXPOSE_SINGLE_INTERFACE.
// Versioning
// There are two versioning cases that are handled by this:
// 1. You add functions to the end of an interface, so it is binary compatible with the previous interface. In this case,
// you need two EXPOSE_INTERFACEs: one to expose your class as the old interface and one to expose it as the new interface.
// 2. You update an interface so it's not compatible anymore (but you still want to be able to expose the old interface
// for legacy code). In this case, you need to make a new version name for your new interface, and make a wrapper interface and
// expose it for the old interface.
// Static Linking:
// Must mimic unique separate class 'InterfaceReg' constructors per subsystem.
// Each subsystem can then import and export interfaces as expected.
// This is achieved through unique namespacing 'InterfaceReg' via symbol _SUBSYSTEM.
// Static Linking also needs to generate unique symbols per interface so as to
// provide a 'stitching' method whereby these interface symbols can be referenced
// via the lib's primary module (usually the lib's interface exposure)
// therby stitching all of that lib's code/data together for eventual final exe link inclusion.
#ifndef INTERFACE_H
#define INTERFACE_H
#ifdef _WIN32
#pragma once
#endif
// TODO: move interface.cpp into tier0 library.
// Need to include platform.h in case _PS3 and other tokens are not yet defined
#include "tier0/platform.h"
#if defined( POSIX ) && !defined( _PS3 )
#include <dlfcn.h> // dlopen,dlclose, et al
#include <unistd.h>
#define GetProcAddress dlsym
#ifdef _snprintf
#undef _snprintf
#endif
#define _snprintf snprintf
#endif // POSIX && !_PS3
// All interfaces derive from this.
class IBaseInterface
{
public:
virtual ~IBaseInterface() {}
};
#if !defined( _X360 )
#define CREATEINTERFACE_PROCNAME "CreateInterface"
#else
// x360 only allows ordinal exports, .def files export "CreateInterface" at 1
#define CREATEINTERFACE_PROCNAME ((const char*)1)
#endif
typedef void* (*CreateInterfaceFn)(const char *pName, int *pReturnCode);
typedef void* (*InstantiateInterfaceFn)();
// Used internally to register classes.
class InterfaceReg
{
public:
InterfaceReg(InstantiateInterfaceFn fn, const char *pName);
public:
InstantiateInterfaceFn m_CreateFn;
const char *m_pName;
InterfaceReg *m_pNext; // For the global list.
};
// Use this to expose an interface that can have multiple instances.
// e.g.:
// EXPOSE_INTERFACE( CInterfaceImp, IInterface, "MyInterface001" )
// This will expose a class called CInterfaceImp that implements IInterface (a pure class)
// clients can receive a pointer to this class by calling CreateInterface( "MyInterface001" )
//
// In practice, the shared header file defines the interface (IInterface) and version name ("MyInterface001")
// so that each component can use these names/vtables to communicate
//
// A single class can support multiple interfaces through multiple inheritance
//
// Use this if you want to write the factory function.
#if !defined(_STATIC_LINKED) || !defined(_SUBSYSTEM)
#define EXPOSE_INTERFACE_FN(functionName, interfaceName, versionName) \
static InterfaceReg __g_Create##interfaceName##_reg(functionName, versionName);
#else
#define EXPOSE_INTERFACE_FN(functionName, interfaceName, versionName) \
namespace _SUBSYSTEM \
{ \
static InterfaceReg __g_Create##interfaceName##_reg(functionName, versionName); \
}
#endif
#if !defined(_STATIC_LINKED) || !defined(_SUBSYSTEM)
#define EXPOSE_INTERFACE(className, interfaceName, versionName) \
static void* __Create##className##_interface() {return static_cast<interfaceName *>( new className );} \
static InterfaceReg __g_Create##className##_reg(__Create##className##_interface, versionName );
#else
#define EXPOSE_INTERFACE(className, interfaceName, versionName) \
namespace _SUBSYSTEM \
{ \
static void* __Create##className##_interface() {return static_cast<interfaceName *>( new className );} \
static InterfaceReg __g_Create##className##_reg(__Create##className##_interface, versionName ); \
}
#endif
// Use this to expose a singleton interface with a global variable you've created.
#if !defined(_STATIC_LINKED) || !defined(_SUBSYSTEM)
#define EXPOSE_SINGLE_INTERFACE_GLOBALVAR(className, interfaceName, versionName, globalVarName) \
static void* __Create##className##interfaceName##_interface() {return static_cast<interfaceName *>( &globalVarName );} \
static InterfaceReg __g_Create##className##interfaceName##_reg(__Create##className##interfaceName##_interface, versionName);
#else
#define EXPOSE_SINGLE_INTERFACE_GLOBALVAR(className, interfaceName, versionName, globalVarName) \
namespace _SUBSYSTEM \
{ \
static void* __Create##className##interfaceName##_interface() {return static_cast<interfaceName *>( &globalVarName );} \
static InterfaceReg __g_Create##className##interfaceName##_reg(__Create##className##interfaceName##_interface, versionName); \
}
#endif
// Use this to expose a singleton interface. This creates the global variable for you automatically.
#if !defined(_STATIC_LINKED) || !defined(_SUBSYSTEM)
#define EXPOSE_SINGLE_INTERFACE(className, interfaceName, versionName) \
static className __g_##className##_singleton; \
EXPOSE_SINGLE_INTERFACE_GLOBALVAR(className, interfaceName, versionName, __g_##className##_singleton)
#else
#define EXPOSE_SINGLE_INTERFACE(className, interfaceName, versionName) \
namespace _SUBSYSTEM \
{ \
static className __g_##className##_singleton; \
} \
EXPOSE_SINGLE_INTERFACE_GLOBALVAR(className, interfaceName, versionName, __g_##className##_singleton)
#endif
// load/unload components
class CSysModule;
// interface return status
enum
{
IFACE_OK = 0,
IFACE_FAILED
};
//-----------------------------------------------------------------------------
// This function is automatically exported and allows you to access any interfaces exposed with the above macros.
// if pReturnCode is set, it will return one of the following values (IFACE_OK, IFACE_FAILED)
// extend this for other error conditions/code
//-----------------------------------------------------------------------------
DLL_EXPORT void* CreateInterface(const char *pName, int *pReturnCode);
#if defined( _X360 )
DLL_EXPORT void *CreateInterfaceThunk( const char *pName, int *pReturnCode );
#endif
//-----------------------------------------------------------------------------
// UNDONE: This is obsolete, use the module load/unload/get instead!!!
//-----------------------------------------------------------------------------
extern CreateInterfaceFn Sys_GetFactory( CSysModule *pModule );
extern CreateInterfaceFn Sys_GetFactory( const char *pModuleName );
extern CreateInterfaceFn Sys_GetFactoryThis( void );
//-----------------------------------------------------------------------------
// Load & Unload should be called in exactly one place for each module
// The factory for that module should be passed on to dependent components for
// proper versioning.
//-----------------------------------------------------------------------------
extern CSysModule *Sys_LoadModule( const char *pModuleName );
extern void Sys_UnloadModule( CSysModule *pModule );
// Determines if current process is running with any debug modules
extern bool Sys_RunningWithDebugModules();
// This is a helper function to load a module, get its factory, and get a specific interface.
// You are expected to free all of these things.
// Returns false and cleans up if any of the steps fail.
bool Sys_LoadInterface(
const char *pModuleName,
const char *pInterfaceVersionName,
CSysModule **pOutModule,
void **pOutInterface );
bool Sys_IsDebuggerPresent();
//-----------------------------------------------------------------------------
// Purpose: Place this as a singleton at module scope (e.g.) and use it to get the factory from the specified module name.
//
// When the singleton goes out of scope (.dll unload if at module scope),
// then it'll call Sys_UnloadModule on the module so that the refcount is decremented
// and the .dll actually can unload from memory.
//-----------------------------------------------------------------------------
class CDllDemandLoader
{
public:
CDllDemandLoader( char const *pchModuleName );
virtual ~CDllDemandLoader();
CreateInterfaceFn GetFactory();
void Unload();
private:
char const *m_pchModuleName;
CSysModule *m_hModule;
bool m_bLoadAttempted;
};
#endif

519
external/vpc/public/tier1/keyvalues.h vendored Normal file
View File

@@ -0,0 +1,519 @@
//========= Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#ifndef KEYVALUES_H
#define KEYVALUES_H
#ifdef _WIN32
#pragma once
#endif
#ifndef NULL
#ifdef __cplusplus
#define NULL 0
#else
#define NULL ((void *)0)
#endif
#endif
#include "utlvector.h"
#include "color.h"
#include "exprevaluator.h"
#define FOR_EACH_SUBKEY( kvRoot, kvSubKey ) \
for ( KeyValues * kvSubKey = kvRoot->GetFirstSubKey(); kvSubKey != NULL; kvSubKey = kvSubKey->GetNextKey() )
#define FOR_EACH_TRUE_SUBKEY( kvRoot, kvSubKey ) \
for ( KeyValues * kvSubKey = kvRoot->GetFirstTrueSubKey(); kvSubKey != NULL; kvSubKey = kvSubKey->GetNextTrueSubKey() )
#define FOR_EACH_VALUE( kvRoot, kvValue ) \
for ( KeyValues * kvValue = kvRoot->GetFirstValue(); kvValue != NULL; kvValue = kvValue->GetNextValue() )
class IBaseFileSystem;
class CUtlBuffer;
class Color;
class KeyValues;
class IKeyValuesDumpContext;
typedef void * FileHandle_t;
class CKeyValuesGrowableStringTable;
// single byte identifies a xbox kv file in binary format
// strings are pooled from a searchpath/zip mounted symbol table
#define KV_BINARY_POOLED_FORMAT 0xAA
#define FOR_EACH_SUBKEY( kvRoot, kvSubKey ) \
for ( KeyValues * kvSubKey = kvRoot->GetFirstSubKey(); kvSubKey != NULL; kvSubKey = kvSubKey->GetNextKey() )
#define FOR_EACH_TRUE_SUBKEY( kvRoot, kvSubKey ) \
for ( KeyValues * kvSubKey = kvRoot->GetFirstTrueSubKey(); kvSubKey != NULL; kvSubKey = kvSubKey->GetNextTrueSubKey() )
#define FOR_EACH_VALUE( kvRoot, kvValue ) \
for ( KeyValues * kvValue = kvRoot->GetFirstValue(); kvValue != NULL; kvValue = kvValue->GetNextValue() )
//-----------------------------------------------------------------------------
// Purpose: Simple recursive data access class
// Used in vgui for message parameters and resource files
// Destructor deletes all child KeyValues nodes
// Data is stored in key (string names) - (string/int/float)value pairs called nodes.
//
// About KeyValues Text File Format:
// It has 3 control characters '{', '}' and '"'. Names and values may be quoted or
// not. The quote '"' character must not be used within name or values, only for
// quoting whole tokens. You may use escape sequences wile parsing and add within a
// quoted token a \" to add quotes within your name or token. When using Escape
// Sequence the parser must now that by setting KeyValues::UsesEscapeSequences( true ),
// which it's off by default. Non-quoted tokens ends with a whitespace, '{', '}' and '"'.
// So you may use '{' and '}' within quoted tokens, but not for non-quoted tokens.
// An open bracket '{' after a key name indicates a list of subkeys which is finished
// with a closing bracket '}'. Subkeys use the same definitions recursively.
// Whitespaces are space, return, newline and tabulator. Allowed Escape sequences
// are \n, \t, \\, \n and \". The number character '#' is used for macro purposes
// (eg #include), don't use it as first character in key names.
//-----------------------------------------------------------------------------
class KeyValues
{
public:
// By default, the KeyValues class uses a string table for the key names that is
// limited to 4MB. The game will exit in error if this space is exhausted. In
// general this is preferable for game code for performance and memory fragmentation
// reasons.
//
// If this is not acceptable, you can use this call to switch to a table that can grow
// arbitrarily. This call must be made before any KeyValues objects are allocated or it
// will result in undefined behavior. If you use the growable string table, you cannot
// share KeyValues pointers directly with any other module. You can serialize them across
// module boundaries. These limitations are acceptable in the Steam backend code
// this option was written for, but may not be in other situations. Make sure to
// understand the implications before using this.
static void SetUseGrowableStringTable( bool bUseGrowableTable );
explicit KeyValues( const char *setName );
//
// AutoDelete class to automatically free the keyvalues.
// Simply construct it with the keyvalues you allocated and it will free them when falls out of scope.
// When you decide that keyvalues shouldn't be deleted call Assign(NULL) on it.
// If you constructed AutoDelete(NULL) you can later assign the keyvalues to be deleted with Assign(pKeyValues).
//
class AutoDelete
{
public:
explicit inline AutoDelete( KeyValues *pKeyValues ) : m_pKeyValues( pKeyValues ) {}
explicit inline AutoDelete( const char *pchKVName ) : m_pKeyValues( new KeyValues( pchKVName ) ) {}
inline ~AutoDelete( void ) { if( m_pKeyValues ) m_pKeyValues->deleteThis(); }
inline void Assign( KeyValues *pKeyValues ) { m_pKeyValues = pKeyValues; }
KeyValues *operator->() { return m_pKeyValues; }
operator KeyValues *() { return m_pKeyValues; }
private:
AutoDelete( AutoDelete const &x ); // forbid
AutoDelete & operator= ( AutoDelete const &x ); // forbid
protected:
KeyValues *m_pKeyValues;
};
//
// AutoDeleteInline is useful when you want to hold your keyvalues object inside
// and delete it right after using.
// You can also pass temporary KeyValues object as an argument to a function by wrapping it into KeyValues::AutoDeleteInline
// instance: call_my_function( KeyValues::AutoDeleteInline( new KeyValues( "test" ) ) )
//
class AutoDeleteInline : public AutoDelete
{
public:
explicit inline AutoDeleteInline( KeyValues *pKeyValues ) : AutoDelete( pKeyValues ) {}
inline operator KeyValues *() const { return m_pKeyValues; }
inline KeyValues * Get() const { return m_pKeyValues; }
};
// Quick setup constructors
KeyValues( const char *setName, const char *firstKey, const char *firstValue );
KeyValues( const char *setName, const char *firstKey, const wchar_t *firstValue );
KeyValues( const char *setName, const char *firstKey, int firstValue );
KeyValues( const char *setName, const char *firstKey, const char *firstValue, const char *secondKey, const char *secondValue );
KeyValues( const char *setName, const char *firstKey, int firstValue, const char *secondKey, int secondValue );
// Section name
const char *GetName() const;
void SetName( const char *setName);
// gets the name as a unique int
int GetNameSymbol() const;
int GetNameSymbolCaseSensitive() const;
// File access. Set UsesEscapeSequences true, if resource file/buffer uses Escape Sequences (eg \n, \t)
void UsesEscapeSequences(bool state); // default false
bool LoadFromFile( IBaseFileSystem *filesystem, const char *resourceName, const char *pathID = NULL, GetSymbolProc_t pfnEvaluateSymbolProc = NULL);
bool SaveToFile( IBaseFileSystem *filesystem, const char *resourceName, const char *pathID = NULL);
// Read from a buffer... Note that the buffer must be null terminated
bool LoadFromBuffer( char const *resourceName, const char *pBuffer, IBaseFileSystem* pFileSystem = NULL, const char *pPathID = NULL, GetSymbolProc_t pfnEvaluateSymbolProc = NULL );
// Read from a utlbuffer...
bool LoadFromBuffer( char const *resourceName, CUtlBuffer &buf, IBaseFileSystem* pFileSystem = NULL, const char *pPathID = NULL, GetSymbolProc_t pfnEvaluateSymbolProc = NULL );
// Find a keyValue, create it if it is not found.
// Set bCreate to true to create the key if it doesn't already exist (which ensures a valid pointer will be returned)
KeyValues *FindKey(const char *keyName, bool bCreate = false);
KeyValues *FindKey(int keySymbol) const;
KeyValues *CreateNewKey(); // creates a new key, with an autogenerated name. name is guaranteed to be an integer, of value 1 higher than the highest other integer key name
void AddSubKey( KeyValues *pSubkey ); // Adds a subkey. Make sure the subkey isn't a child of some other keyvalues
void RemoveSubKey(KeyValues *subKey); // removes a subkey from the list, DOES NOT DELETE IT
void InsertSubKey( int nIndex, KeyValues *pSubKey ); // Inserts the given sub-key before the Nth child location
bool ContainsSubKey( KeyValues *pSubKey ); // Returns true if this key values contains the specified sub key, false otherwise.
void SwapSubKey( KeyValues *pExistingSubKey, KeyValues *pNewSubKey ); // Swaps an existing subkey for a new one, DOES NOT DELETE THE OLD ONE but takes ownership of the new one
void ElideSubKey( KeyValues *pSubKey ); // Removes a subkey but inserts all of its children in its place, in-order (flattens a tree, like firing a manager!)
// Key iteration.
//
// NOTE: GetFirstSubKey/GetNextKey will iterate keys AND values. Use the functions
// below if you want to iterate over just the keys or just the values.
//
KeyValues *GetFirstSubKey(); // returns the first subkey in the list
KeyValues *GetNextKey(); // returns the next subkey
void SetNextKey( KeyValues * pDat);
//
// These functions can be used to treat it like a true key/values tree instead of
// confusing values with keys.
//
// So if you wanted to iterate all subkeys, then all values, it would look like this:
// for ( KeyValues *pKey = pRoot->GetFirstTrueSubKey(); pKey; pKey = pKey->GetNextTrueSubKey() )
// {
// Msg( "Key name: %s\n", pKey->GetName() );
// }
// for ( KeyValues *pValue = pRoot->GetFirstValue(); pKey; pKey = pKey->GetNextValue() )
// {
// Msg( "Int value: %d\n", pValue->GetInt() ); // Assuming pValue->GetDataType() == TYPE_INT...
// }
KeyValues* GetFirstTrueSubKey();
KeyValues* GetNextTrueSubKey();
KeyValues* GetFirstValue(); // When you get a value back, you can use GetX and pass in NULL to get the value.
KeyValues* GetNextValue();
// Data access
int GetInt( const char *keyName = NULL, int defaultValue = 0 );
uint64 GetUint64( const char *keyName = NULL, uint64 defaultValue = 0 );
float GetFloat( const char *keyName = NULL, float defaultValue = 0.0f );
const char *GetString( const char *keyName = NULL, const char *defaultValue = "" );
const wchar_t *GetWString( const char *keyName = NULL, const wchar_t *defaultValue = L"" );
void *GetPtr( const char *keyName = NULL, void *defaultValue = (void*)0 );
Color GetColor( const char *keyName = NULL , const Color &defaultColor = Color( 0, 0, 0, 0 ) );
bool GetBool( const char *keyName = NULL, bool defaultValue = false ) { return GetInt( keyName, defaultValue ? 1 : 0 ) ? true : false; }
bool IsEmpty(const char *keyName = NULL);
// Data access
int GetInt( int keySymbol, int defaultValue = 0 );
uint64 GetUint64( int keySymbol, uint64 defaultValue = 0 );
float GetFloat( int keySymbol, float defaultValue = 0.0f );
const char *GetString( int keySymbol, const char *defaultValue = "" );
const wchar_t *GetWString( int keySymbol, const wchar_t *defaultValue = L"" );
void *GetPtr( int keySymbol, void *defaultValue = (void*)0 );
Color GetColor( int keySymbol /* default value is all black */);
bool GetBool( int keySymbol, bool defaultValue = false ) { return GetInt( keySymbol, defaultValue ? 1 : 0 ) ? true : false; }
bool IsEmpty( int keySymbol );
// Key writing
void SetWString( const char *keyName, const wchar_t *value );
void SetString( const char *keyName, const char *value );
void SetInt( const char *keyName, int value );
void SetUint64( const char *keyName, uint64 value );
void SetFloat( const char *keyName, float value );
void SetPtr( const char *keyName, void *value );
void SetColor( const char *keyName, Color value);
void SetBool( const char *keyName, bool value ) { SetInt( keyName, value ? 1 : 0 ); }
// Memory allocation (optimized)
void *operator new( size_t iAllocSize );
void *operator new( size_t iAllocSize, int nBlockUse, const char *pFileName, int nLine );
void operator delete( void *pMem );
void operator delete( void *pMem, int nBlockUse, const char *pFileName, int nLine );
KeyValues& operator=( KeyValues& src );
// Adds a chain... if we don't find stuff in this keyvalue, we'll look
// in the one we're chained to.
void ChainKeyValue( KeyValues* pChain );
void RecursiveSaveToFile( CUtlBuffer& buf, int indentLevel );
bool WriteAsBinary( CUtlBuffer &buffer ) const;
bool ReadAsBinary( CUtlBuffer &buffer );
// Allocate & create a new copy of the keys
KeyValues *MakeCopy( void ) const;
// Make a new copy of all subkeys, add them all to the passed-in keyvalues
void CopySubkeys( KeyValues *pParent ) const;
// Clear out all subkeys, and the current value
void Clear( void );
// Data type
enum types_t
{
TYPE_NONE = 0,
TYPE_STRING,
TYPE_INT,
TYPE_FLOAT,
TYPE_PTR,
TYPE_WSTRING,
TYPE_COLOR,
TYPE_UINT64,
TYPE_COMPILED_INT_BYTE, // hack to collapse 1 byte ints in the compiled format
TYPE_COMPILED_INT_0, // hack to collapse 0 in the compiled format
TYPE_COMPILED_INT_1, // hack to collapse 1 in the compiled format
TYPE_NUMTYPES,
};
types_t GetDataType(const char *keyName = NULL);
// Virtual deletion function - ensures that KeyValues object is deleted from correct heap
void deleteThis();
void SetStringValue( char const *strValue );
// unpack a key values list into a structure
void UnpackIntoStructure( struct KeyValuesUnpackStructure const *pUnpackTable, void *pDest );
// Process conditional keys for widescreen support.
bool ProcessResolutionKeys( const char *pResString );
// Dump keyvalues recursively into a dump context
bool Dump( IKeyValuesDumpContext *pDump, int nIndentLevel = 0 );
// Merge operations describing how two keyvalues can be combined
enum MergeKeyValuesOp_t
{
MERGE_KV_ALL,
MERGE_KV_UPDATE, // update values are copied into storage, adding new keys to storage or updating existing ones
MERGE_KV_DELETE, // update values specify keys that get deleted from storage
MERGE_KV_BORROW, // update values only update existing keys in storage, keys in update that do not exist in storage are discarded
};
void MergeFrom( KeyValues *kvMerge, MergeKeyValuesOp_t eOp = MERGE_KV_ALL );
// Assign keyvalues from a string
static KeyValues * FromString( char const *szName, char const *szStringVal, char const **ppEndOfParse = NULL );
protected:
KeyValues( KeyValues& ); // prevent copy constructor being used
// prevent delete being called except through deleteThis()
~KeyValues();
KeyValues* CreateKey( const char *keyName );
void RecursiveCopyKeyValues( KeyValues& src );
void RemoveEverything();
// void RecursiveSaveToFile( IBaseFileSystem *filesystem, CUtlBuffer &buffer, int indentLevel );
// void WriteConvertedString( CUtlBuffer &buffer, const char *pszString );
// NOTE: If both filesystem and pBuf are non-null, it'll save to both of them.
// If filesystem is null, it'll ignore f.
void RecursiveSaveToFile( IBaseFileSystem *filesystem, FileHandle_t f, CUtlBuffer *pBuf, int indentLevel );
void WriteConvertedString( IBaseFileSystem *filesystem, FileHandle_t f, CUtlBuffer *pBuf, const char *pszString );
void RecursiveLoadFromBuffer( char const *resourceName, CUtlBuffer &buf, GetSymbolProc_t pfnEvaluateSymbolProc );
// for handling #include "filename"
void AppendIncludedKeys( CUtlVector< KeyValues * >& includedKeys );
void ParseIncludedKeys( char const *resourceName, const char *filetoinclude,
IBaseFileSystem* pFileSystem, const char *pPathID, CUtlVector< KeyValues * >& includedKeys, GetSymbolProc_t pfnEvaluateSymbolProc );
// For handling #base "filename"
void MergeBaseKeys( CUtlVector< KeyValues * >& baseKeys );
void RecursiveMergeKeyValues( KeyValues *baseKV );
// NOTE: If both filesystem and pBuf are non-null, it'll save to both of them.
// If filesystem is null, it'll ignore f.
void InternalWrite( IBaseFileSystem *filesystem, FileHandle_t f, CUtlBuffer *pBuf, const void *pData, int len );
void Init();
const char * ReadToken( CUtlBuffer &buf, bool &wasQuoted, bool &wasConditional );
void WriteIndents( IBaseFileSystem *filesystem, FileHandle_t f, CUtlBuffer *pBuf, int indentLevel );
void FreeAllocatedValue();
void AllocateValueBlock(int size);
bool ReadAsBinaryPooledFormat( CUtlBuffer &buf, IBaseFileSystem *pFileSystem, unsigned int poolKey, GetSymbolProc_t pfnEvaluateSymbolProc );
bool EvaluateConditional( const char *pExpressionString, GetSymbolProc_t pfnEvaluateSymbolProc );
uint32 m_iKeyName : 24; // keyname is a symbol defined in KeyValuesSystem
uint32 m_iKeyNameCaseSensitive1 : 8; // 1st part of case sensitive symbol defined in KeyValueSystem
// These are needed out of the union because the API returns string pointers
char *m_sValue;
wchar_t *m_wsValue;
// we don't delete these
union
{
int m_iValue;
float m_flValue;
void *m_pValue;
unsigned char m_Color[4];
};
char m_iDataType;
char m_bHasEscapeSequences; // true, if while parsing this KeyValue, Escape Sequences are used (default false)
uint16 m_iKeyNameCaseSensitive2; // 2nd part of case sensitive symbol defined in KeyValueSystem;
KeyValues *m_pPeer; // pointer to next key in list
KeyValues *m_pSub; // pointer to Start of a new sub key list
KeyValues *m_pChain;// Search here if it's not in our list
GetSymbolProc_t m_pExpressionGetSymbolProc;
private:
// Statics to implement the optional growable string table
// Function pointers that will determine which mode we are in
static int (*s_pfGetSymbolForString)( const char *name, bool bCreate );
static const char *(*s_pfGetStringForSymbol)( int symbol );
static CKeyValuesGrowableStringTable *s_pGrowableStringTable;
public:
// Functions that invoke the default behavior
static int GetSymbolForStringClassic( const char *name, bool bCreate = true );
static const char *GetStringForSymbolClassic( int symbol );
// Functions that use the growable string table
static int GetSymbolForStringGrowable( const char *name, bool bCreate = true );
static const char *GetStringForSymbolGrowable( int symbol );
};
typedef KeyValues::AutoDelete KeyValuesAD;
enum KeyValuesUnpackDestinationTypes_t
{
UNPACK_TYPE_FLOAT, // dest is a float
UNPACK_TYPE_VECTOR, // dest is a Vector
UNPACK_TYPE_VECTOR_COLOR, // dest is a vector, src is a color
UNPACK_TYPE_STRING, // dest is a char *. unpacker will allocate.
UNPACK_TYPE_INT, // dest is an int
UNPACK_TYPE_FOUR_FLOATS, // dest is an array of 4 floats. source is a string like "1 2 3 4"
UNPACK_TYPE_TWO_FLOATS, // dest is an array of 2 floats. source is a string like "1 2"
};
#define UNPACK_FIXED( kname, kdefault, dtype, ofs ) { kname, kdefault, dtype, ofs, 0 }
#define UNPACK_VARIABLE( kname, kdefault, dtype, ofs, sz ) { kname, kdefault, dtype, ofs, sz }
#define UNPACK_END_MARKER { NULL, NULL, UNPACK_TYPE_FLOAT, 0 }
struct KeyValuesUnpackStructure
{
char const *m_pKeyName; // null to terminate tbl
char const *m_pKeyDefault; // null ok
KeyValuesUnpackDestinationTypes_t m_eDataType; // UNPACK_TYPE_INT, ..
size_t m_nFieldOffset; // use offsetof to set
size_t m_nFieldSize; // for strings or other variable length
};
//-----------------------------------------------------------------------------
// inline methods
//-----------------------------------------------------------------------------
inline int KeyValues::GetInt( int keySymbol, int defaultValue )
{
KeyValues *dat = FindKey( keySymbol );
return dat ? dat->GetInt( (const char *)NULL, defaultValue ) : defaultValue;
}
inline uint64 KeyValues::GetUint64( int keySymbol, uint64 defaultValue )
{
KeyValues *dat = FindKey( keySymbol );
return dat ? dat->GetUint64( (const char *)NULL, defaultValue ) : defaultValue;
}
inline float KeyValues::GetFloat( int keySymbol, float defaultValue )
{
KeyValues *dat = FindKey( keySymbol );
return dat ? dat->GetFloat( (const char *)NULL, defaultValue ) : defaultValue;
}
inline const char *KeyValues::GetString( int keySymbol, const char *defaultValue )
{
KeyValues *dat = FindKey( keySymbol );
return dat ? dat->GetString( (const char *)NULL, defaultValue ) : defaultValue;
}
inline const wchar_t *KeyValues::GetWString( int keySymbol, const wchar_t *defaultValue )
{
KeyValues *dat = FindKey( keySymbol );
return dat ? dat->GetWString( (const char *)NULL, defaultValue ) : defaultValue;
}
inline void *KeyValues::GetPtr( int keySymbol, void *defaultValue )
{
KeyValues *dat = FindKey( keySymbol );
return dat ? dat->GetPtr( (const char *)NULL, defaultValue ) : defaultValue;
}
inline Color KeyValues::GetColor( int keySymbol )
{
Color defaultValue( 0, 0, 0, 0 );
KeyValues *dat = FindKey( keySymbol );
return dat ? dat->GetColor( ) : defaultValue;
}
inline bool KeyValues::IsEmpty( int keySymbol )
{
KeyValues *dat = FindKey( keySymbol );
return dat ? dat->IsEmpty( ) : true;
}
//
// KeyValuesDumpContext and generic implementations
//
class IKeyValuesDumpContext
{
public:
virtual bool KvBeginKey( KeyValues *pKey, int nIndentLevel ) = 0;
virtual bool KvWriteValue( KeyValues *pValue, int nIndentLevel ) = 0;
virtual bool KvEndKey( KeyValues *pKey, int nIndentLevel ) = 0;
};
class IKeyValuesDumpContextAsText : public IKeyValuesDumpContext
{
public:
virtual bool KvBeginKey( KeyValues *pKey, int nIndentLevel );
virtual bool KvWriteValue( KeyValues *pValue, int nIndentLevel );
virtual bool KvEndKey( KeyValues *pKey, int nIndentLevel );
public:
virtual bool KvWriteIndent( int nIndentLevel );
virtual bool KvWriteText( char const *szText ) = 0;
};
class CKeyValuesDumpContextAsDevMsg : public IKeyValuesDumpContextAsText
{
public:
// Overrides developer level to dump in DevMsg, zero to dump as Msg
CKeyValuesDumpContextAsDevMsg( int nDeveloperLevel = 1 ) : m_nDeveloperLevel( nDeveloperLevel ) {}
public:
virtual bool KvBeginKey( KeyValues *pKey, int nIndentLevel );
virtual bool KvWriteText( char const *szText );
protected:
int m_nDeveloperLevel;
};
inline bool KeyValuesDumpAsDevMsg( KeyValues *pKeyValues, int nIndentLevel = 0, int nDeveloperLevel = 1 )
{
CKeyValuesDumpContextAsDevMsg ctx( nDeveloperLevel );
return pKeyValues->Dump( &ctx, nIndentLevel );
}
#endif // KEYVALUES_H

649
external/vpc/public/tier1/mempool.h vendored Normal file
View File

@@ -0,0 +1,649 @@
//===== Copyright 1996-2005, Valve Corporation, All rights reserved. ======//
//
// Purpose:
//
// $Workfile: $
// $Date: $
//
//-----------------------------------------------------------------------------
// $Log: $
//
// $NoKeywords: $
//===========================================================================//
#ifndef MEMPOOL_H
#define MEMPOOL_H
#ifdef _WIN32
#pragma once
#endif
#include "tier0/memalloc.h"
#include "tier0/tslist.h"
#include "tier0/platform.h"
#include "tier1/utlvector.h"
#include "tier1/utlrbtree.h"
//-----------------------------------------------------------------------------
// Purpose: Optimized pool memory allocator
//-----------------------------------------------------------------------------
typedef void (*MemoryPoolReportFunc_t)( char const* pMsg, ... );
class CUtlMemoryPool
{
public:
// Ways the memory pool can grow when it needs to make a new blob.
enum MemoryPoolGrowType_t
{
GROW_NONE=0, // Don't allow new blobs.
GROW_FAST=1, // New blob size is numElements * (i+1) (ie: the blocks it allocates
// get larger and larger each time it allocates one).
GROW_SLOW=2 // New blob size is numElements.
};
CUtlMemoryPool( int blockSize, int numElements, int growMode = GROW_FAST, const char *pszAllocOwner = NULL, int nAlignment = 0 );
~CUtlMemoryPool();
void* Alloc(); // Allocate the element size you specified in the constructor.
void* Alloc( size_t amount );
void* AllocZero(); // Allocate the element size you specified in the constructor, zero the memory before construction
void* AllocZero( size_t amount );
void Free(void *pMem);
// Frees everything
void Clear();
// Error reporting...
static void SetErrorReportFunc( MemoryPoolReportFunc_t func );
// returns number of allocated blocks
int Count() const { return m_BlocksAllocated; }
int PeakCount() const { return m_PeakAlloc; }
int BlockSize() const { return m_BlockSize; }
int Size() const { return m_NumBlobs * m_BlocksPerBlob * m_BlockSize; }
bool IsAllocationWithinPool( void *pMem ) const;
protected:
class CBlob
{
public:
CBlob *m_pPrev, *m_pNext;
int m_NumBytes; // Number of bytes in this blob.
char m_Data[1];
char m_Padding[3]; // to int align the struct
};
// Resets the pool
void Init();
void AddNewBlob();
void ReportLeaks();
int m_BlockSize;
int m_BlocksPerBlob;
int m_GrowMode; // GROW_ enum.
// FIXME: Change m_ppMemBlob into a growable array?
void *m_pHeadOfFreeList;
int m_BlocksAllocated;
int m_PeakAlloc;
unsigned short m_nAlignment;
unsigned short m_NumBlobs;
const char * m_pszAllocOwner;
// CBlob could be not a multiple of 4 bytes so stuff it at the end here to keep us otherwise aligned
CBlob m_BlobHead;
static MemoryPoolReportFunc_t g_ReportFunc;
};
//-----------------------------------------------------------------------------
// Multi-thread/Thread Safe Memory Class
//-----------------------------------------------------------------------------
class CMemoryPoolMT : public CUtlMemoryPool
{
public:
CMemoryPoolMT( int blockSize, int numElements, int growMode = GROW_FAST, const char *pszAllocOwner = NULL, int nAlignment = 0) : CUtlMemoryPool( blockSize, numElements, growMode, pszAllocOwner, nAlignment ) {}
void* Alloc() { AUTO_LOCK( m_mutex ); return CUtlMemoryPool::Alloc(); }
void* Alloc( size_t amount ) { AUTO_LOCK( m_mutex ); return CUtlMemoryPool::Alloc( amount ); }
void* AllocZero() { AUTO_LOCK( m_mutex ); return CUtlMemoryPool::AllocZero(); }
void* AllocZero( size_t amount ) { AUTO_LOCK( m_mutex ); return CUtlMemoryPool::AllocZero( amount ); }
void Free(void *pMem) { AUTO_LOCK( m_mutex ); CUtlMemoryPool::Free( pMem ); }
// Frees everything
void Clear() { AUTO_LOCK( m_mutex ); return CUtlMemoryPool::Clear(); }
private:
CThreadFastMutex m_mutex; // @TODO: Rework to use tslist (toml 7/6/2007)
};
//-----------------------------------------------------------------------------
// Wrapper macro to make an allocator that returns particular typed allocations
// and construction and destruction of objects.
//-----------------------------------------------------------------------------
template< class T >
class CClassMemoryPool : public CUtlMemoryPool
{
public:
CClassMemoryPool(int numElements, int growMode = GROW_FAST, int nAlignment = 0 ) :
CUtlMemoryPool( sizeof(T), numElements, growMode, MEM_ALLOC_CLASSNAME(T), nAlignment ) {}
T* Alloc();
T* AllocZero();
void Free( T *pMem );
void Clear();
};
//-----------------------------------------------------------------------------
// Specialized pool for aligned data management (e.g., Xbox textures)
//-----------------------------------------------------------------------------
template <int ITEM_SIZE, int ALIGNMENT, int CHUNK_SIZE, class CAllocator, bool GROWMODE = false, int COMPACT_THRESHOLD = 4 >
class CAlignedMemPool
{
enum
{
BLOCK_SIZE = COMPILETIME_MAX( ALIGN_VALUE( ITEM_SIZE, ALIGNMENT ), 8 ),
};
public:
CAlignedMemPool();
void *Alloc();
void Free( void *p );
static int __cdecl CompareChunk( void * const *ppLeft, void * const *ppRight );
void Compact();
int NumTotal() { AUTO_LOCK( m_mutex ); return m_Chunks.Count() * ( CHUNK_SIZE / BLOCK_SIZE ); }
int NumAllocated() { AUTO_LOCK( m_mutex ); return NumTotal() - m_nFree; }
int NumFree() { AUTO_LOCK( m_mutex ); return m_nFree; }
int BytesTotal() { AUTO_LOCK( m_mutex ); return NumTotal() * BLOCK_SIZE; }
int BytesAllocated() { AUTO_LOCK( m_mutex ); return NumAllocated() * BLOCK_SIZE; }
int BytesFree() { AUTO_LOCK( m_mutex ); return NumFree() * BLOCK_SIZE; }
int ItemSize() { return ITEM_SIZE; }
int BlockSize() { return BLOCK_SIZE; }
int ChunkSize() { return CHUNK_SIZE; }
private:
struct FreeBlock_t
{
FreeBlock_t *pNext;
byte reserved[ BLOCK_SIZE - sizeof( FreeBlock_t *) ];
};
CUtlVector<void *> m_Chunks; // Chunks are tracked outside blocks (unlike CUtlMemoryPool) to simplify alignment issues
FreeBlock_t * m_pFirstFree;
int m_nFree;
CAllocator m_Allocator;
double m_TimeLastCompact;
CThreadFastMutex m_mutex;
};
//-----------------------------------------------------------------------------
// Pool variant using standard allocation
//-----------------------------------------------------------------------------
template <typename T, int nInitialCount = 0, bool bDefCreateNewIfEmpty = true >
class CObjectPool
{
public:
CObjectPool()
{
int i = nInitialCount;
while ( i-- > 0 )
{
m_AvailableObjects.PushItem( new T );
}
}
~CObjectPool()
{
Purge();
}
int NumAvailable()
{
return m_AvailableObjects.Count();
}
void Purge()
{
T *p = NULL;
while ( m_AvailableObjects.PopItem( &p ) )
{
delete p;
}
}
T *GetObject( bool bCreateNewIfEmpty = bDefCreateNewIfEmpty )
{
T *p = NULL;
if ( !m_AvailableObjects.PopItem( &p ) )
{
p = ( bCreateNewIfEmpty ) ? new T : NULL;
}
return p;
}
void PutObject( T *p )
{
m_AvailableObjects.PushItem( p );
}
private:
CTSList<T *> m_AvailableObjects;
};
//-----------------------------------------------------------------------------
// Fixed budget pool with overflow to malloc
//-----------------------------------------------------------------------------
template <size_t PROVIDED_ITEM_SIZE, int ITEM_COUNT>
class CFixedBudgetMemoryPool
{
public:
CFixedBudgetMemoryPool()
{
m_pBase = m_pLimit = 0;
COMPILE_TIME_ASSERT( ITEM_SIZE % 4 == 0 );
}
bool Owns( void *p )
{
return ( p >= m_pBase && p < m_pLimit );
}
void *Alloc()
{
MEM_ALLOC_CREDIT_CLASS();
#ifndef USE_MEM_DEBUG
if ( !m_pBase )
{
LOCAL_THREAD_LOCK();
if ( !m_pBase )
{
byte *pMemory = m_pBase = (byte *)malloc( ITEM_COUNT * ITEM_SIZE );
m_pLimit = m_pBase + ( ITEM_COUNT * ITEM_SIZE );
for ( int i = 0; i < ITEM_COUNT; i++ )
{
m_freeList.Push( (TSLNodeBase_t *)pMemory );
pMemory += ITEM_SIZE;
}
}
}
void *p = m_freeList.Pop();
if ( p )
return p;
#endif
return malloc( ITEM_SIZE );
}
void Free( void *p )
{
#ifndef USE_MEM_DEBUG
if ( Owns( p ) )
m_freeList.Push( (TSLNodeBase_t *)p );
else
#endif
free( p );
}
void Clear()
{
#ifndef USE_MEM_DEBUG
if ( m_pBase )
{
free( m_pBase );
}
m_pBase = m_pLimit = 0;
Construct( &m_freeList );
#endif
}
bool IsEmpty()
{
#ifndef USE_MEM_DEBUG
if ( m_pBase && m_freeList.Count() != ITEM_COUNT )
return false;
#endif
return true;
}
enum
{
ITEM_SIZE = ALIGN_VALUE( PROVIDED_ITEM_SIZE, TSLIST_NODE_ALIGNMENT )
};
CTSListBase m_freeList;
byte *m_pBase;
byte *m_pLimit;
};
#define BIND_TO_FIXED_BUDGET_POOL( poolName ) \
inline void* operator new( size_t size ) { return poolName.Alloc(); } \
inline void* operator new( size_t size, int nBlockUse, const char *pFileName, int nLine ) { return poolName.Alloc(); } \
inline void operator delete( void* p ) { poolName.Free(p); } \
inline void operator delete( void* p, int nBlockUse, const char *pFileName, int nLine ) { poolName.Free(p); }
//-----------------------------------------------------------------------------
template< class T >
inline T* CClassMemoryPool<T>::Alloc()
{
T *pRet;
{
MEM_ALLOC_CREDIT_CLASS();
pRet = (T*)CUtlMemoryPool::Alloc();
}
if ( pRet )
{
Construct( pRet );
}
return pRet;
}
template< class T >
inline T* CClassMemoryPool<T>::AllocZero()
{
T *pRet;
{
MEM_ALLOC_CREDIT_CLASS();
pRet = (T*)CUtlMemoryPool::AllocZero();
}
if ( pRet )
{
Construct( pRet );
}
return pRet;
}
template< class T >
inline void CClassMemoryPool<T>::Free(T *pMem)
{
if ( pMem )
{
Destruct( pMem );
}
CUtlMemoryPool::Free( pMem );
}
template< class T >
inline void CClassMemoryPool<T>::Clear()
{
CUtlRBTree<void *> freeBlocks;
SetDefLessFunc( freeBlocks );
void *pCurFree = m_pHeadOfFreeList;
while ( pCurFree != NULL )
{
freeBlocks.Insert( pCurFree );
pCurFree = *((void**)pCurFree);
}
for( CBlob *pCur=m_BlobHead.m_pNext; pCur != &m_BlobHead; pCur=pCur->m_pNext )
{
T *p = (T *)pCur->m_Data;
T *pLimit = (T *)(pCur->m_Data + pCur->m_NumBytes);
while ( p < pLimit )
{
if ( freeBlocks.Find( p ) == freeBlocks.InvalidIndex() )
{
Destruct( p );
}
p++;
}
}
CUtlMemoryPool::Clear();
}
//-----------------------------------------------------------------------------
// Macros that make it simple to make a class use a fixed-size allocator
// Put DECLARE_FIXEDSIZE_ALLOCATOR in the private section of a class,
// Put DEFINE_FIXEDSIZE_ALLOCATOR in the CPP file
//-----------------------------------------------------------------------------
#define DECLARE_FIXEDSIZE_ALLOCATOR( _class ) \
public: \
inline void* operator new( size_t size ) { MEM_ALLOC_CREDIT_(#_class " pool"); return s_Allocator.Alloc(size); } \
inline void* operator new( size_t size, int nBlockUse, const char *pFileName, int nLine ) { MEM_ALLOC_CREDIT_(#_class " pool"); return s_Allocator.Alloc(size); } \
inline void operator delete( void* p ) { s_Allocator.Free(p); } \
inline void operator delete( void* p, int nBlockUse, const char *pFileName, int nLine ) { s_Allocator.Free(p); } \
private: \
static CUtlMemoryPool s_Allocator
#define DEFINE_FIXEDSIZE_ALLOCATOR( _class, _initsize, _grow ) \
CUtlMemoryPool _class::s_Allocator(sizeof(_class), _initsize, _grow, #_class " pool")
#define DEFINE_FIXEDSIZE_ALLOCATOR_ALIGNED( _class, _initsize, _grow, _alignment ) \
CUtlMemoryPool _class::s_Allocator(sizeof(_class), _initsize, _grow, #_class " pool", _alignment )
#define DECLARE_FIXEDSIZE_ALLOCATOR_MT( _class ) \
public: \
inline void* operator new( size_t size ) { MEM_ALLOC_CREDIT_(#_class " pool"); return s_Allocator.Alloc(size); } \
inline void* operator new( size_t size, int nBlockUse, const char *pFileName, int nLine ) { MEM_ALLOC_CREDIT_(#_class " pool"); return s_Allocator.Alloc(size); } \
inline void operator delete( void* p ) { s_Allocator.Free(p); } \
inline void operator delete( void* p, int nBlockUse, const char *pFileName, int nLine ) { s_Allocator.Free(p); } \
private: \
static CMemoryPoolMT s_Allocator
#define DEFINE_FIXEDSIZE_ALLOCATOR_MT( _class, _initsize, _grow ) \
CMemoryPoolMT _class::s_Allocator(sizeof(_class), _initsize, _grow, #_class " pool")
//-----------------------------------------------------------------------------
// Macros that make it simple to make a class use a fixed-size allocator
// This version allows us to use a memory pool which is externally defined...
// Put DECLARE_FIXEDSIZE_ALLOCATOR_EXTERNAL in the private section of a class,
// Put DEFINE_FIXEDSIZE_ALLOCATOR_EXTERNAL in the CPP file
//-----------------------------------------------------------------------------
#define DECLARE_FIXEDSIZE_ALLOCATOR_EXTERNAL( _class ) \
public: \
inline void* operator new( size_t size ) { MEM_ALLOC_CREDIT_(#_class " pool"); return s_pAllocator->Alloc(size); } \
inline void* operator new( size_t size, int nBlockUse, const char *pFileName, int nLine ) { MEM_ALLOC_CREDIT_(#_class " pool"); return s_pAllocator->Alloc(size); } \
inline void operator delete( void* p ) { s_pAllocator->Free(p); } \
private: \
static CUtlMemoryPool* s_pAllocator
#define DEFINE_FIXEDSIZE_ALLOCATOR_EXTERNAL( _class, _allocator ) \
CUtlMemoryPool* _class::s_pAllocator = _allocator
template <int ITEM_SIZE, int ALIGNMENT, int CHUNK_SIZE, class CAllocator, bool GROWMODE, int COMPACT_THRESHOLD >
inline CAlignedMemPool<ITEM_SIZE, ALIGNMENT, CHUNK_SIZE, CAllocator, GROWMODE, COMPACT_THRESHOLD>::CAlignedMemPool()
: m_pFirstFree( 0 ),
m_nFree( 0 ),
m_TimeLastCompact( 0 )
{
COMPILE_TIME_ASSERT( sizeof( FreeBlock_t ) >= BLOCK_SIZE );
COMPILE_TIME_ASSERT( ALIGN_VALUE( sizeof( FreeBlock_t ), ALIGNMENT ) == sizeof( FreeBlock_t ) );
}
template <int ITEM_SIZE, int ALIGNMENT, int CHUNK_SIZE, class CAllocator, bool GROWMODE, int COMPACT_THRESHOLD >
inline void *CAlignedMemPool<ITEM_SIZE, ALIGNMENT, CHUNK_SIZE, CAllocator, GROWMODE, COMPACT_THRESHOLD>::Alloc()
{
AUTO_LOCK( m_mutex );
if ( !m_pFirstFree )
{
if ( !GROWMODE && m_Chunks.Count() )
{
return NULL;
}
FreeBlock_t *pNew = (FreeBlock_t *)m_Allocator.Alloc( CHUNK_SIZE );
Assert( (unsigned)pNew % ALIGNMENT == 0 );
m_Chunks.AddToTail( pNew );
m_nFree = CHUNK_SIZE / BLOCK_SIZE;
m_pFirstFree = pNew;
for ( int i = 0; i < m_nFree - 1; i++ )
{
pNew->pNext = pNew + 1;
pNew++;
}
pNew->pNext = NULL;
}
void *p = m_pFirstFree;
m_pFirstFree = m_pFirstFree->pNext;
m_nFree--;
return p;
}
template <int ITEM_SIZE, int ALIGNMENT, int CHUNK_SIZE, class CAllocator, bool GROWMODE, int COMPACT_THRESHOLD >
inline void CAlignedMemPool<ITEM_SIZE, ALIGNMENT, CHUNK_SIZE, CAllocator, GROWMODE, COMPACT_THRESHOLD>::Free( void *p )
{
AUTO_LOCK( m_mutex );
// Insertion sort to encourage allocation clusters in chunks
FreeBlock_t *pFree = ((FreeBlock_t *)p);
FreeBlock_t *pCur = m_pFirstFree;
FreeBlock_t *pPrev = NULL;
while ( pCur && pFree > pCur )
{
pPrev = pCur;
pCur = pCur->pNext;
}
pFree->pNext = pCur;
if ( pPrev )
{
pPrev->pNext = pFree;
}
else
{
m_pFirstFree = pFree;
}
m_nFree++;
if ( m_nFree >= ( CHUNK_SIZE / BLOCK_SIZE ) * COMPACT_THRESHOLD )
{
double time = Plat_FloatTime();
double compactTime = ( m_nFree >= ( CHUNK_SIZE / BLOCK_SIZE ) * COMPACT_THRESHOLD * 4 ) ? 15.0 : 30.0;
if ( m_TimeLastCompact > time || m_TimeLastCompact + compactTime < time )
{
Compact();
m_TimeLastCompact = time;
}
}
}
template <int ITEM_SIZE, int ALIGNMENT, int CHUNK_SIZE, class CAllocator, bool GROWMODE, int COMPACT_THRESHOLD >
inline int __cdecl CAlignedMemPool<ITEM_SIZE, ALIGNMENT, CHUNK_SIZE, CAllocator, GROWMODE, COMPACT_THRESHOLD>::CompareChunk( void * const *ppLeft, void * const *ppRight )
{
return ((unsigned)*ppLeft) - ((unsigned)*ppRight);
}
template <int ITEM_SIZE, int ALIGNMENT, int CHUNK_SIZE, class CAllocator, bool GROWMODE, int COMPACT_THRESHOLD >
inline void CAlignedMemPool<ITEM_SIZE, ALIGNMENT, CHUNK_SIZE, CAllocator, GROWMODE, COMPACT_THRESHOLD>::Compact()
{
FreeBlock_t *pCur = m_pFirstFree;
FreeBlock_t *pPrev = NULL;
m_Chunks.Sort( CompareChunk );
#ifdef VALIDATE_ALIGNED_MEM_POOL
{
FreeBlock_t *p = m_pFirstFree;
while ( p )
{
if ( p->pNext && p > p->pNext )
{
__asm { int 3 }
}
p = p->pNext;
}
for ( int i = 0; i < m_Chunks.Count(); i++ )
{
if ( i + 1 < m_Chunks.Count() )
{
if ( m_Chunks[i] > m_Chunks[i + 1] )
{
__asm { int 3 }
}
}
}
}
#endif
int i;
for ( i = 0; i < m_Chunks.Count(); i++ )
{
int nBlocksPerChunk = CHUNK_SIZE / BLOCK_SIZE;
FreeBlock_t *pChunkLimit = ((FreeBlock_t *)m_Chunks[i]) + nBlocksPerChunk;
int nFromChunk = 0;
if ( pCur == m_Chunks[i] )
{
FreeBlock_t *pFirst = pCur;
while ( pCur && pCur >= m_Chunks[i] && pCur < pChunkLimit )
{
pCur = pCur->pNext;
nFromChunk++;
}
pCur = pFirst;
}
while ( pCur && pCur >= m_Chunks[i] && pCur < pChunkLimit )
{
if ( nFromChunk != nBlocksPerChunk )
{
if ( pPrev )
{
pPrev->pNext = pCur;
}
else
{
m_pFirstFree = pCur;
}
pPrev = pCur;
}
else if ( pPrev )
{
pPrev->pNext = NULL;
}
else
{
m_pFirstFree = NULL;
}
pCur = pCur->pNext;
}
if ( nFromChunk == nBlocksPerChunk )
{
m_Allocator.Free( m_Chunks[i] );
m_nFree -= nBlocksPerChunk;
m_Chunks[i] = 0;
}
}
for ( i = m_Chunks.Count() - 1; i >= 0 ; i-- )
{
if ( !m_Chunks[i] )
{
m_Chunks.FastRemove( i );
}
}
}
#endif // MEMPOOL_H

348
external/vpc/public/tier1/memstack.h vendored Normal file
View File

@@ -0,0 +1,348 @@
//===== Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ======//
//
// Purpose: A fast stack memory allocator that uses virtual memory if available
//
//===========================================================================//
#ifndef MEMSTACK_H
#define MEMSTACK_H
#if defined( _WIN32 )
#pragma once
#endif
#include "tier1/utlvector.h"
#if defined( _WIN32 ) || defined( _PS3 )
#define MEMSTACK_VIRTUAL_MEMORY_AVAILABLE
#endif
//-----------------------------------------------------------------------------
typedef unsigned MemoryStackMark_t;
class CMemoryStack
{
public:
CMemoryStack();
~CMemoryStack();
bool Init( const char *pszAllocOwner, unsigned maxSize = 0, unsigned commitSize = 0, unsigned initialCommit = 0, unsigned alignment = 16 );
#ifdef _GAMECONSOLE
bool InitPhysical( const char *pszAllocOwner, uint size, uint nBaseAddrAlignment, uint alignment = 16, uint32 nAdditionalFlags = 0 );
#endif
void Term();
int GetSize();
int GetMaxSize();
int GetUsed();
void *Alloc( unsigned bytes, bool bClear = false ) RESTRICT;
MemoryStackMark_t GetCurrentAllocPoint();
void FreeToAllocPoint( MemoryStackMark_t mark, bool bDecommit = true );
void FreeAll( bool bDecommit = true );
void Access( void **ppRegion, unsigned *pBytes );
void PrintContents();
void *GetBase();
const void *GetBase() const { return const_cast<CMemoryStack *>(this)->GetBase(); }
bool CommitSize( int );
void SetAllocOwner( const char *pszAllocOwner );
private:
bool CommitTo( byte * ) RESTRICT;
void RegisterAllocation();
void RegisterDeallocation( bool bShouldSpew );
byte *m_pNextAlloc;
byte *m_pCommitLimit;
byte *m_pAllocLimit;
byte *m_pBase;
bool m_bRegisteredAllocation;
bool m_bPhysical;
char *m_pszAllocOwner;
unsigned m_maxSize;
unsigned m_alignment;
#ifdef MEMSTACK_VIRTUAL_MEMORY_AVAILABLE
unsigned m_commitSize;
unsigned m_minCommit;
#endif
#if defined( MEMSTACK_VIRTUAL_MEMORY_AVAILABLE ) && defined( _PS3 )
IVirtualMemorySection *m_pVirtualMemorySection;
#endif
};
//-------------------------------------
FORCEINLINE void *CMemoryStack::Alloc( unsigned bytes, bool bClear ) RESTRICT
{
Assert( m_pBase );
bytes = MAX( bytes, m_alignment );
bytes = AlignValue( bytes, m_alignment );
void *pResult = m_pNextAlloc;
byte *pNextAlloc = m_pNextAlloc + bytes;
if ( pNextAlloc > m_pCommitLimit )
{
if ( !CommitTo( pNextAlloc ) )
{
return NULL;
}
}
if ( bClear )
{
memset( pResult, 0, bytes );
}
m_pNextAlloc = pNextAlloc;
return pResult;
}
//-------------------------------------
inline bool CMemoryStack::CommitSize( int nBytes )
{
if ( GetSize() != nBytes )
{
return CommitTo( m_pBase + nBytes );
}
return true;
}
//-------------------------------------
inline int CMemoryStack::GetMaxSize()
{
return m_maxSize;
}
//-------------------------------------
inline int CMemoryStack::GetUsed()
{
return ( m_pNextAlloc - m_pBase );
}
//-------------------------------------
inline void *CMemoryStack::GetBase()
{
return m_pBase;
}
//-------------------------------------
inline MemoryStackMark_t CMemoryStack::GetCurrentAllocPoint()
{
return ( m_pNextAlloc - m_pBase );
}
//-----------------------------------------------------------------------------
// The CUtlMemoryStack class:
// A fixed memory class
//-----------------------------------------------------------------------------
template< typename T, typename I, size_t MAX_SIZE, size_t COMMIT_SIZE = 0, size_t INITIAL_COMMIT = 0 >
class CUtlMemoryStack
{
public:
// constructor, destructor
CUtlMemoryStack( int nGrowSize = 0, int nInitSize = 0 ) { m_MemoryStack.Init( "CUtlMemoryStack", MAX_SIZE * sizeof(T), COMMIT_SIZE * sizeof(T), INITIAL_COMMIT * sizeof(T), 4 ); COMPILE_TIME_ASSERT( sizeof(T) % 4 == 0 ); }
CUtlMemoryStack( T* pMemory, int numElements ) { Assert( 0 ); }
// Can we use this index?
bool IsIdxValid( I i ) const { long x=i; return (x >= 0) && (x < m_nAllocated); }
// Specify the invalid ('null') index that we'll only return on failure
static const I INVALID_INDEX = ( I )-1; // For use with COMPILE_TIME_ASSERT
static I InvalidIndex() { return INVALID_INDEX; }
class Iterator_t
{
Iterator_t( I i ) : index( i ) {}
I index;
friend class CUtlMemoryStack<T,I,MAX_SIZE, COMMIT_SIZE, INITIAL_COMMIT>;
public:
bool operator==( const Iterator_t it ) const { return index == it.index; }
bool operator!=( const Iterator_t it ) const { return index != it.index; }
};
Iterator_t First() const { return Iterator_t( m_nAllocated ? 0 : InvalidIndex() ); }
Iterator_t Next( const Iterator_t &it ) const { return Iterator_t( it.index < m_nAllocated ? it.index + 1 : InvalidIndex() ); }
I GetIndex( const Iterator_t &it ) const { return it.index; }
bool IsIdxAfter( I i, const Iterator_t &it ) const { return i > it.index; }
bool IsValidIterator( const Iterator_t &it ) const { long x=it.index; return x >= 0 && x < m_nAllocated; }
Iterator_t InvalidIterator() const { return Iterator_t( InvalidIndex() ); }
// Gets the base address
T* Base() { return (T*)m_MemoryStack.GetBase(); }
const T* Base() const { return (const T*)m_MemoryStack.GetBase(); }
// element access
T& operator[]( I i ) { Assert( IsIdxValid(i) ); return Base()[i]; }
const T& operator[]( I i ) const { Assert( IsIdxValid(i) ); return Base()[i]; }
T& Element( I i ) { Assert( IsIdxValid(i) ); return Base()[i]; }
const T& Element( I i ) const { Assert( IsIdxValid(i) ); return Base()[i]; }
// Attaches the buffer to external memory....
void SetExternalBuffer( T* pMemory, int numElements ) { Assert( 0 ); }
// Size
int NumAllocated() const { return m_nAllocated; }
int Count() const { return m_nAllocated; }
// Grows the memory, so that at least allocated + num elements are allocated
void Grow( int num = 1 ) { Assert( num > 0 ); m_nAllocated += num; m_MemoryStack.Alloc( num * sizeof(T) ); }
// Makes sure we've got at least this much memory
void EnsureCapacity( int num ) { Assert( num <= MAX_SIZE ); if ( m_nAllocated < num ) Grow( num - m_nAllocated ); }
// Memory deallocation
void Purge() { m_MemoryStack.FreeAll(); m_nAllocated = 0; }
// is the memory externally allocated?
bool IsExternallyAllocated() const { return false; }
// Set the size by which the memory grows
void SetGrowSize( int size ) { Assert( 0 ); }
// Identify the owner of this memory stack's memory
void SetAllocOwner( const char *pszAllocOwner ) { m_MemoryStack.SetAllocOwner( pszAllocOwner ); }
private:
CMemoryStack m_MemoryStack;
int m_nAllocated;
};
#ifdef _X360
//-----------------------------------------------------------------------------
// A memory stack used for allocating physical memory on the 360
// Usage pattern anticipates we usually never go over the initial allocation
// When we do so, we're ok with slightly slower allocation
//-----------------------------------------------------------------------------
class CPhysicalMemoryStack
{
public:
CPhysicalMemoryStack();
~CPhysicalMemoryStack();
// The physical memory stack is allocated in chunks. We will initially
// allocate nInitChunkCount chunks, which will always be in memory.
// When FreeAll() is called, it will free down to the initial chunk count
// but not below it.
bool Init( size_t nChunkSizeInBytes, size_t nAlignment, int nInitialChunkCount, uint32 nAdditionalFlags );
void Term();
size_t GetSize() const;
size_t GetPeakUsed() const;
size_t GetUsed() const;
size_t GetFramePeakUsed() const;
MemoryStackMark_t GetCurrentAllocPoint() const;
void FreeToAllocPoint( MemoryStackMark_t mark, bool bUnused = true ); // bUnused is for interface compat with CMemoryStack
void *Alloc( size_t nSizeInBytes, bool bClear = false ) RESTRICT;
void FreeAll( bool bUnused = true ); // bUnused is for interface compat with CMemoryStack
void PrintContents();
private:
void *AllocFromOverflow( size_t nSizeInBytes );
struct PhysicalChunk_t
{
uint8 *m_pBase;
uint8 *m_pNextAlloc;
uint8 *m_pAllocLimit;
};
PhysicalChunk_t m_InitialChunk;
CUtlVector< PhysicalChunk_t > m_ExtraChunks;
size_t m_nUsage;
size_t m_nFramePeakUsage;
size_t m_nPeakUsage;
size_t m_nAlignment;
size_t m_nChunkSizeInBytes;
int m_nFirstAvailableChunk;
int m_nAdditionalFlags;
PhysicalChunk_t *m_pLastAllocedChunk;
};
//-------------------------------------
FORCEINLINE void *CPhysicalMemoryStack::Alloc( size_t nSizeInBytes, bool bClear ) RESTRICT
{
if ( nSizeInBytes )
{
nSizeInBytes = AlignValue( nSizeInBytes, m_nAlignment );
}
else
{
nSizeInBytes = m_nAlignment;
}
// Can't do an allocation bigger than the chunk size
Assert( nSizeInBytes <= m_nChunkSizeInBytes );
void *pResult = m_InitialChunk.m_pNextAlloc;
uint8 *pNextAlloc = m_InitialChunk.m_pNextAlloc + nSizeInBytes;
if ( pNextAlloc <= m_InitialChunk.m_pAllocLimit )
{
m_InitialChunk.m_pNextAlloc = pNextAlloc;
m_pLastAllocedChunk = &m_InitialChunk;
}
else
{
pResult = AllocFromOverflow( nSizeInBytes );
}
m_nUsage += nSizeInBytes;
m_nFramePeakUsage = MAX( m_nUsage, m_nFramePeakUsage );
m_nPeakUsage = MAX( m_nUsage, m_nPeakUsage );
if ( bClear )
{
memset( pResult, 0, nSizeInBytes );
}
return pResult;
}
//-------------------------------------
inline size_t CPhysicalMemoryStack::GetPeakUsed() const
{
return m_nPeakUsage;
}
//-------------------------------------
inline size_t CPhysicalMemoryStack::GetUsed() const
{
return m_nUsage;
}
inline size_t CPhysicalMemoryStack::GetFramePeakUsed() const
{
return m_nFramePeakUsage;
}
inline MemoryStackMark_t CPhysicalMemoryStack::GetCurrentAllocPoint() const
{
Assert( m_pLastAllocedChunk );
return ( m_pLastAllocedChunk->m_pNextAlloc - m_pLastAllocedChunk->m_pBase );
}
#endif // _X360
#endif // MEMSTACK_H

73
external/vpc/public/tier1/netadr.h vendored Normal file
View File

@@ -0,0 +1,73 @@
//========= Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//
//=============================================================================//
// netadr.h
#ifndef NETADR_H
#define NETADR_H
#ifdef _WIN32
#pragma once
#endif
#include "tier0/platform.h"
#undef SetPort
typedef enum
{
NA_NULL = 0,
NA_LOOPBACK,
NA_BROADCAST,
NA_IP,
} netadrtype_t;
struct netadr_t
{
public:
netadr_t() { SetIP( 0 ); SetPort( 0 ); SetType( NA_IP ); }
netadr_t( uint unIP, uint16 usPort ) { SetIP( unIP ); SetPort( usPort ); SetType( NA_IP ); }
netadr_t( const char *pch ) { SetFromString( pch ); }
void Clear(); // invalids Address
void SetType( netadrtype_t type );
void SetPort( unsigned short port );
bool SetFromSockadr(const struct sockaddr *s);
void SetIP(uint8 b1, uint8 b2, uint8 b3, uint8 b4);
void SetIP(uint unIP); // Sets IP. unIP is in host order (little-endian)
void SetIPAndPort( uint unIP, unsigned short usPort ) { SetIP( unIP ); SetPort( usPort ); }
void SetFromString(const char *pch, bool bUseDNS = false ); // if bUseDNS is true then do a DNS lookup if needed
bool CompareAdr (const netadr_t &a, bool onlyBase = false) const;
bool CompareClassBAdr (const netadr_t &a) const;
bool CompareClassCAdr (const netadr_t &a) const;
netadrtype_t GetType() const;
unsigned short GetPort() const;
const char* ToString( bool onlyBase = false ) const; // returns xxx.xxx.xxx.xxx:ppppp
void ToSockadr(struct sockaddr *s) const;
unsigned int GetIP() const;
bool IsLocalhost() const; // true, if this is the localhost IP
bool IsLoopback() const; // true if engine loopback buffers are used
bool IsReservedAdr() const; // true, if this is a private LAN IP
bool IsValid() const; // ip & port != 0
bool IsBaseAdrValid() const; // ip != 0
void SetFromSocket( int hSocket );
// These function names are decorated because the Xbox360 defines macros for ntohl and htonl
unsigned long addr_ntohl() const;
unsigned long addr_htonl() const;
bool operator==(const netadr_t &netadr) const {return ( CompareAdr( netadr ) );}
bool operator<(const netadr_t &netadr) const;
public: // members are public to avoid to much changes
netadrtype_t type;
unsigned char ip[4];
unsigned short port;
};
#endif // NETADR_H

384
external/vpc/public/tier1/refcount.h vendored Normal file
View File

@@ -0,0 +1,384 @@
//========== Copyright <20> 2005, Valve Corporation, All rights reserved. ========
//
// Purpose: Tools for correctly implementing & handling reference counted
// objects
//
//=============================================================================
#ifndef REFCOUNT_H
#define REFCOUNT_H
#include "tier0/threadtools.h"
#if defined( _WIN32 )
#pragma once
#endif
//-----------------------------------------------------------------------------
// Purpose: Implement a standard reference counted interface. Use of this
// is optional insofar as all the concrete tools only require
// at compile time that the function signatures match.
//-----------------------------------------------------------------------------
class IRefCounted
{
public:
virtual int AddRef() = 0;
virtual int Release() = 0;
};
//-----------------------------------------------------------------------------
// Purpose: Release a pointer and mark it NULL
//-----------------------------------------------------------------------------
template <class REFCOUNTED_ITEM_PTR>
inline int SafeRelease( REFCOUNTED_ITEM_PTR &pRef )
{
// Use funny syntax so that this works on "auto pointers"
REFCOUNTED_ITEM_PTR *ppRef = &pRef;
if ( *ppRef )
{
int result = (*ppRef)->Release();
*ppRef = NULL;
return result;
}
return 0;
}
//-----------------------------------------------------------------------------
// Purpose: Maintain a reference across a scope
//-----------------------------------------------------------------------------
template <class T = IRefCounted>
class CAutoRef
{
public:
CAutoRef( T *pRef )
: m_pRef( pRef )
{
if ( m_pRef )
m_pRef->AddRef();
}
~CAutoRef()
{
if (m_pRef)
m_pRef->Release();
}
private:
T *m_pRef;
};
//-----------------------------------------------------------------------------
// Purpose: Do a an inline AddRef then return the pointer, useful when
// returning an object from a function
//-----------------------------------------------------------------------------
#define RetAddRef( p ) ( (p)->AddRef(), (p) )
#define InlineAddRef( p ) ( (p)->AddRef(), (p) )
//-----------------------------------------------------------------------------
// Purpose: A class to both hold a pointer to an object and its reference.
// Base exists to support other cleanup models
//-----------------------------------------------------------------------------
template <class T>
class CBaseAutoPtr
{
public:
CBaseAutoPtr() : m_pObject(0) {}
CBaseAutoPtr(T *pFrom) : m_pObject(pFrom) {}
operator const void *() const { return m_pObject; }
operator void *() { return m_pObject; }
operator const T *() const { return m_pObject; }
operator const T *() { return m_pObject; }
operator T *() { return m_pObject; }
int operator=( int i ) { AssertMsg( i == 0, "Only NULL allowed on integer assign" ); m_pObject = 0; return 0; }
T * operator=( T *p ) { m_pObject = p; return p; }
bool operator !() const { return ( !m_pObject ); }
bool operator!=( int i ) const { AssertMsg( i == 0, "Only NULL allowed on integer compare" ); return (m_pObject != NULL); }
bool operator==( const void *p ) const { return ( m_pObject == p ); }
bool operator!=( const void *p ) const { return ( m_pObject != p ); }
bool operator==( T *p ) const { return operator==( (void *)p ); }
bool operator!=( T *p ) const { return operator!=( (void *)p ); }
bool operator==( const CBaseAutoPtr<T> &p ) const { return operator==( (const void *)p ); }
bool operator!=( const CBaseAutoPtr<T> &p ) const { return operator!=( (const void *)p ); }
T * operator->() { return m_pObject; }
T & operator *() { return *m_pObject; }
T ** operator &() { return &m_pObject; }
const T * operator->() const { return m_pObject; }
const T & operator *() const { return *m_pObject; }
T * const * operator &() const { return &m_pObject; }
protected:
CBaseAutoPtr( const CBaseAutoPtr<T> &from ) : m_pObject( from.m_pObject ) {}
void operator=( const CBaseAutoPtr<T> &from ) { m_pObject = from.m_pObject; }
T *m_pObject;
};
//---------------------------------------------------------
template <class T>
class CRefPtr : public CBaseAutoPtr<T>
{
typedef CBaseAutoPtr<T> BaseClass;
public:
CRefPtr() {}
CRefPtr( T *pInit ) : BaseClass( pInit ) {}
CRefPtr( const CRefPtr<T> &from ) : BaseClass( from ) {}
~CRefPtr() { if ( BaseClass::m_pObject ) BaseClass::m_pObject->Release(); }
void operator=( const CRefPtr<T> &from ) { BaseClass::operator=( from ); }
int operator=( int i ) { return BaseClass::operator=( i ); }
T *operator=( T *p ) { return BaseClass::operator=( p ); }
operator bool() const { return !BaseClass::operator!(); }
operator bool() { return !BaseClass::operator!(); }
void SafeRelease() { if ( BaseClass::m_pObject ) BaseClass::m_pObject->Release(); BaseClass::m_pObject = 0; }
void AssignAddRef( T *pFrom ) { SafeRelease(); if (pFrom) pFrom->AddRef(); BaseClass::m_pObject = pFrom; }
void AddRefAssignTo( T *&pTo ) { ::SafeRelease( pTo ); if ( BaseClass::m_pObject ) BaseClass::m_pObject->AddRef(); pTo = BaseClass::m_pObject; }
};
//-----------------------------------------------------------------------------
// Purpose: Traits classes defining reference count threading model
//-----------------------------------------------------------------------------
class CRefMT
{
public:
static int Increment( int *p) { return ThreadInterlockedIncrement( (int32 *)p ); }
static int Decrement( int *p) { return ThreadInterlockedDecrement( (int32 *)p ); }
};
class CRefST
{
public:
static int Increment( int *p) { return ++(*p); }
static int Decrement( int *p) { return --(*p); }
};
//-----------------------------------------------------------------------------
// Purpose: Actual reference counting implementation. Pulled out to reduce
// code bloat.
//-----------------------------------------------------------------------------
template <const bool bSelfDelete, typename CRefThreading = CRefMT>
class NO_VTABLE CRefCountServiceBase
{
protected:
CRefCountServiceBase()
: m_iRefs( 1 )
{
}
virtual ~CRefCountServiceBase()
{
}
virtual bool OnFinalRelease()
{
return true;
}
int GetRefCount() const
{
return m_iRefs;
}
int DoAddRef()
{
return CRefThreading::Increment( &m_iRefs );
}
int DoRelease()
{
int result = CRefThreading::Decrement( &m_iRefs );
if ( result )
return result;
if ( OnFinalRelease() && bSelfDelete )
delete this;
return 0;
}
private:
int m_iRefs;
};
class CRefCountServiceNull
{
protected:
static int DoAddRef() { return 1; }
static int DoRelease() { return 1; }
};
template <typename CRefThreading = CRefMT>
class NO_VTABLE CRefCountServiceDestruct
{
protected:
CRefCountServiceDestruct()
: m_iRefs( 1 )
{
}
virtual ~CRefCountServiceDestruct()
{
}
int GetRefCount() const
{
return m_iRefs;
}
int DoAddRef()
{
return CRefThreading::Increment( &m_iRefs );
}
int DoRelease()
{
int result = CRefThreading::Decrement( &m_iRefs );
if ( result )
return result;
this->~CRefCountServiceDestruct();
return 0;
}
private:
int m_iRefs;
};
typedef CRefCountServiceBase<true, CRefST> CRefCountServiceST;
typedef CRefCountServiceBase<false, CRefST> CRefCountServiceNoDeleteST;
typedef CRefCountServiceBase<true, CRefMT> CRefCountServiceMT;
typedef CRefCountServiceBase<false, CRefMT> CRefCountServiceNoDeleteMT;
// Default to threadsafe
typedef CRefCountServiceNoDeleteMT CRefCountServiceNoDelete;
typedef CRefCountServiceMT CRefCountService;
//-----------------------------------------------------------------------------
// Purpose: Base classes to implement reference counting
//-----------------------------------------------------------------------------
template < class REFCOUNT_SERVICE = CRefCountService >
class NO_VTABLE CRefCounted : public REFCOUNT_SERVICE
{
public:
virtual ~CRefCounted() {}
int AddRef() { return REFCOUNT_SERVICE::DoAddRef(); }
int Release() { return REFCOUNT_SERVICE::DoRelease(); }
};
//-------------------------------------
template < class BASE1, class REFCOUNT_SERVICE = CRefCountService >
class NO_VTABLE CRefCounted1 : public BASE1,
public REFCOUNT_SERVICE
{
public:
virtual ~CRefCounted1() {}
int AddRef() { return REFCOUNT_SERVICE::DoAddRef(); }
int Release() { return REFCOUNT_SERVICE::DoRelease(); }
};
//-------------------------------------
template < class BASE1, class BASE2, class REFCOUNT_SERVICE = CRefCountService >
class NO_VTABLE CRefCounted2 : public BASE1, public BASE2,
public REFCOUNT_SERVICE
{
public:
virtual ~CRefCounted2() {}
int AddRef() { return REFCOUNT_SERVICE::DoAddRef(); }
int Release() { return REFCOUNT_SERVICE::DoRelease(); }
};
//-------------------------------------
template < class BASE1, class BASE2, class BASE3, class REFCOUNT_SERVICE = CRefCountService >
class NO_VTABLE CRefCounted3 : public BASE1, public BASE2, public BASE3,
public REFCOUNT_SERVICE
{
virtual ~CRefCounted3() {}
int AddRef() { return REFCOUNT_SERVICE::DoAddRef(); }
int Release() { return REFCOUNT_SERVICE::DoRelease(); }
};
//-------------------------------------
template < class BASE1, class BASE2, class BASE3, class BASE4, class REFCOUNT_SERVICE = CRefCountService >
class NO_VTABLE CRefCounted4 : public BASE1, public BASE2, public BASE3, public BASE4,
public REFCOUNT_SERVICE
{
public:
virtual ~CRefCounted4() {}
int AddRef() { return REFCOUNT_SERVICE::DoAddRef(); }
int Release() { return REFCOUNT_SERVICE::DoRelease(); }
};
//-------------------------------------
template < class BASE1, class BASE2, class BASE3, class BASE4, class BASE5, class REFCOUNT_SERVICE = CRefCountService >
class NO_VTABLE CRefCounted5 : public BASE1, public BASE2, public BASE3, public BASE4, public BASE5,
public REFCOUNT_SERVICE
{
public:
virtual ~CRefCounted5() {}
int AddRef() { return REFCOUNT_SERVICE::DoAddRef(); }
int Release() { return REFCOUNT_SERVICE::DoRelease(); }
};
//-----------------------------------------------------------------------------
// Purpose: Class to throw around a reference counted item to debug
// referencing problems
//-----------------------------------------------------------------------------
#ifdef _DEBUG
template <class BASE_REFCOUNTED, int FINAL_REFS = 0, const char *pszName = (const char *)NULL >
class CRefDebug : public BASE_REFCOUNTED
{
public:
CRefDebug()
{
AssertMsg( this->GetRefCount() == 1, "Expected initial ref count of 1" );
DevMsg( "%s:create 0x%x\n", ( pszName ) ? pszName : "", this );
}
virtual ~CRefDebug()
{
AssertDevMsg( this->GetRefCount() == FINAL_REFS, "Object still referenced on destroy?" );
DevMsg( "%s:destroy 0x%x\n", ( pszName ) ? pszName : "", this );
}
int AddRef()
{
DevMsg( "%s:(0x%x)->AddRef() --> %d\n", ( pszName ) ? pszName : "", this, this->GetRefCount() + 1 );
return BASE_REFCOUNTED::AddRef();
}
int Release()
{
DevMsg( "%s:(0x%x)->Release() --> %d\n", ( pszName ) ? pszName : "", this, this->GetRefCount() - 1 );
Assert( this->GetRefCount() > 0 );
return BASE_REFCOUNTED::Release();
}
};
#endif
//-----------------------------------------------------------------------------
#endif // REFCOUNT_H

106
external/vpc/public/tier1/stringpool.h vendored Normal file
View File

@@ -0,0 +1,106 @@
//========= Copyright (c) 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#ifndef STRINGPOOL_H
#define STRINGPOOL_H
#if defined( _WIN32 )
#pragma once
#endif
#include "utlrbtree.h"
#include "utlvector.h"
#include "utlbuffer.h"
//-----------------------------------------------------------------------------
// Purpose: Allocates memory for strings, checking for duplicates first,
// reusing exising strings if duplicate found.
//-----------------------------------------------------------------------------
enum StringPoolCase_t
{
StringPoolCaseInsensitive,
StringPoolCaseSensitive
};
class CStringPool
{
public:
CStringPool( StringPoolCase_t caseSensitivity = StringPoolCaseInsensitive );
~CStringPool();
unsigned int Count() const;
const char * Allocate( const char *pszValue );
// This feature is deliberately not supported because it's pretty dangerous
// given current uses of CStringPool, which assume they can copy string pointers without
// any refcounts.
//void Free( const char *pszValue );
void FreeAll();
// searches for a string already in the pool
const char * Find( const char *pszValue );
protected:
typedef CUtlRBTree<const char *, unsigned short> CStrSet;
CStrSet m_Strings;
};
//-----------------------------------------------------------------------------
// Purpose: A reference counted string pool.
//
// Elements are stored more efficiently than in the conventional string pool,
// quicker to look up, and storage is tracked via reference counts.
//
// At some point this should replace CStringPool
//-----------------------------------------------------------------------------
class CCountedStringPool
{
public: // HACK, hash_item_t structure should not be public.
struct hash_item_t
{
char* pString;
unsigned short nNextElement;
unsigned char nReferenceCount;
unsigned char pad;
};
enum
{
INVALID_ELEMENT = 0,
MAX_REFERENCE = 0xFF,
HASH_TABLE_SIZE = 1024
};
CUtlVector<unsigned short> m_HashTable; // Points to each element
CUtlVector<hash_item_t> m_Elements;
unsigned short m_FreeListStart;
StringPoolCase_t m_caseSensitivity;
public:
CCountedStringPool( StringPoolCase_t caseSensitivity = StringPoolCaseInsensitive );
virtual ~CCountedStringPool();
void FreeAll();
char *FindString( const char* pIntrinsic );
char *ReferenceString( const char* pIntrinsic );
void DereferenceString( const char* pIntrinsic );
// These are only reliable if there are less than 64k strings in your string pool
unsigned short FindStringHandle( const char* pIntrinsic );
unsigned short ReferenceStringHandle( const char* pIntrinsic );
char *HandleToString( unsigned short handle );
void SpewStrings();
unsigned Hash( const char *pszKey );
bool SaveToBuffer( CUtlBuffer &buffer );
bool RestoreFromBuffer( CUtlBuffer &buffer );};
#endif // STRINGPOOL_H

589
external/vpc/public/tier1/strtools.h vendored Normal file
View File

@@ -0,0 +1,589 @@
//===== Copyright 1996-2005, Valve Corporation, All rights reserved. ======//
//
// Purpose:
//
// $NoKeywords: $
//
//===========================================================================//
#ifndef TIER1_STRTOOLS_H
#define TIER1_STRTOOLS_H
#include "tier0/basetypes.h"
#ifdef _WIN32
#pragma once
#elif POSIX
#include <ctype.h>
#include <wchar.h>
#include <math.h>
#include <wctype.h>
#endif
#include <string.h>
#include <stdlib.h>
// 3d memcpy. Copy (up-to) 3 dimensional data with arbitrary source and destination
// strides. Optimizes to just a single memcpy when possible. For 2d data, set numslices to 1.
void CopyMemory3D( void *pDestAdr, void const *pSrcAdr,
int nNumCols, int nNumRows, int nNumSlices, // dimensions of copy
int nSrcBytesPerRow, int nSrcBytesPerSlice, // strides for source.
int nDestBytesPerRow, int nDestBytesPerSlice // strides for dest
);
template< class T, class I > class CUtlMemory;
template< class T, class A > class CUtlVector;
//-----------------------------------------------------------------------------
// Portable versions of standard string functions
//-----------------------------------------------------------------------------
void _V_memset ( void *dest, int fill, int count );
void _V_memcpy ( void *dest, const void *src, int count );
void _V_memmove ( void *dest, const void *src, int count );
int _V_memcmp ( const void *m1, const void *m2, int count );
int _V_strlen ( const char *str );
void _V_strcpy ( char *dest, const char *src );
char* _V_strrchr ( const char *s, char c );
int _V_strcmp ( const char *s1, const char *s2 );
int _V_wcscmp ( const wchar_t *s1, const wchar_t *s2 );
int _V_stricmp ( const char *s1, const char *s2 );
char* _V_strstr ( const char *s1, const char *search );
char* _V_strupr ( char *start );
char* _V_strlower ( char *start );
int _V_wcslen ( const wchar_t *pwch );
wchar_t* _V_wcslower (const char* file, int line, wchar_t *start);
wchar_t* _V_wcsupr (const char* file, int line, wchar_t *start);
#ifdef POSIX
inline char *strupr( char *start )
{
char *str = start;
while( str && *str )
{
*str = (char)toupper(*str);
str++;
}
return start;
}
inline char *strlwr( char *start )
{
char *str = start;
while( str && *str )
{
*str = (char)tolower(*str);
str++;
}
return start;
}
inline wchar_t *_wcslwr( wchar_t *start )
{
wchar_t *str = start;
while( str && *str )
{
*str = (wchar_t)towlower(static_cast<wint_t>(*str));
str++;
}
return start;
};
inline wchar_t *_wcsupr( wchar_t *start )
{
wchar_t *str = start;
while( str && *str )
{
*str = (wchar_t)towupper(static_cast<wint_t>(*str));
str++;
}
return start;
};
#endif // POSIX
// there are some users of these via tier1 templates in used in tier0. but tier0 can't depend on vstdlib which means in tier0 we always need the inlined ones
#if ( !defined( TIER0_DLL_EXPORT ) )
#if !defined( _DEBUG ) && defined( _PS3 )
#include "tier1/strtools_inlines.h"
// To avoid cross-prx calls, making the V_* fucntions that don't do anything but debug checks and call through to the non V_* function
// go ahead and call the non-V_* functions directly.
#define V_memset(dest, fill, count) memset ((dest), (fill), (count))
#define V_memcpy(dest, src, count) memcpy ((dest), (src), (count))
#define V_memmove(dest, src, count) memmove ((dest), (src), (count))
#define V_memcmp(m1, m2, count) memcmp ((m1), (m2), (count))
#define V_strcpy(dest, src) strcpy ((dest), (src))
#define V_strcmp(s1, s2) strcmp ((s1), (s2))
#define V_strupr(start) strupr ((start))
#define V_strlower(start) strlwr ((start))
#define V_wcslen(pwch) wcslen ((pwch))
// To avoid cross-prx calls, using inline versions of these custom functions:
#define V_strlen(str) _V_strlen_inline ((str))
#define V_strrchr(s, c) _V_strrchr_inline ((s), (c))
#define V_wcscmp(s1, s2) _V_wcscmp_inline ((s1), (s2))
#define V_stricmp(s1, s2 ) _V_stricmp_inline ((s1), (s2) )
#define V_strstr(s1, search ) _V_strstr_inline ((s1), (search) )
#else
#define V_memset(dest, fill, count) _V_memset ((dest), (fill), (count))
#define V_memcpy(dest, src, count) _V_memcpy ((dest), (src), (count))
#define V_memmove(dest, src, count) _V_memmove ((dest), (src), (count))
#define V_memcmp(m1, m2, count) _V_memcmp ((m1), (m2), (count))
#define V_strlen(str) _V_strlen ((str))
#define V_strcpy(dest, src) _V_strcpy ((dest), (src))
#define V_strrchr(s, c) _V_strrchr ((s), (c))
#define V_strcmp(s1, s2) _V_strcmp ((s1), (s2))
#define V_wcscmp(s1, s2) _V_wcscmp ((s1), (s2))
#define V_stricmp(s1, s2 ) _V_stricmp ((s1), (s2) )
#define V_strstr(s1, search ) _V_strstr ((s1), (search) )
#define V_strupr(start) _V_strupr ((start))
#define V_strlower(start) _V_strlower ((start))
#define V_wcslen(pwch) _V_wcslen ((pwch))
#endif
#else
inline void V_memset (void *dest, int fill, int count) { memset( dest, fill, count ); }
inline void V_memcpy (void *dest, const void *src, int count) { memcpy( dest, src, count ); }
inline void V_memmove (void *dest, const void *src, int count) { memmove( dest, src, count ); }
inline int V_memcmp (const void *m1, const void *m2, int count){ return memcmp( m1, m2, count ); }
inline int V_strlen (const char *str) { return (int) strlen ( str ); }
inline void V_strcpy (char *dest, const char *src) { strcpy( dest, src ); }
inline int V_wcslen(const wchar_t *pwch) { return (int)wcslen(pwch); }
inline char* V_strrchr (const char *s, char c) { return (char*)strrchr( s, c ); }
inline int V_strcmp (const char *s1, const char *s2) { return strcmp( s1, s2 ); }
inline int V_wcscmp (const wchar_t *s1, const wchar_t *s2) { return wcscmp( s1, s2 ); }
inline int V_stricmp( const char *s1, const char *s2 ) { return stricmp( s1, s2 ); }
inline char* V_strstr( const char *s1, const char *search ) { return (char*)strstr( s1, search ); }
#ifndef COMPILER_PS3
inline char* V_strupr (char *start) { return strupr( start ); }
inline char* V_strlower (char *start) { return strlwr( start ); }
inline wchar_t* V_wcsupr (wchar_t *start) { return _wcsupr( start ); }
#endif
#endif
int V_strncmp (const char *s1, const char *s2, int count);
int V_strcasecmp (const char *s1, const char *s2);
int V_strncasecmp (const char *s1, const char *s2, int n);
int V_strnicmp (const char *s1, const char *s2, int n);
int V_atoi (const char *str);
int64 V_atoi64(const char *str);
uint64 V_atoui64(const char *str);
float V_atof (const char *str);
char* V_stristr( char* pStr, const char* pSearch );
const char* V_stristr( const char* pStr, const char* pSearch );
const char* V_strnistr( const char* pStr, const char* pSearch, int n );
const char* V_strnchr( const char* pStr, char c, int n );
// returns string immediately following prefix, (ie str+strlen(prefix)) or NULL if prefix not found
const char *StringAfterPrefix ( const char *str, const char *prefix );
const char *StringAfterPrefixCaseSensitive( const char *str, const char *prefix );
inline bool StringHasPrefix ( const char *str, const char *prefix ) { return StringAfterPrefix ( str, prefix ) != NULL; }
inline bool StringHasPrefixCaseSensitive( const char *str, const char *prefix ) { return StringAfterPrefixCaseSensitive( str, prefix ) != NULL; }
// Normalizes a float string in place.
// (removes leading zeros, trailing zeros after the decimal point, and the decimal point itself where possible)
void V_normalizeFloatString( char* pFloat );
inline bool V_isspace(int c)
{
// The standard white-space characters are the following: space, tab, carriage-return, newline, vertical tab, and form-feed. In the C locale, V_isspace() returns true only for the standard white-space characters.
//return c == ' ' || c == 9 /*horizontal tab*/ || c == '\r' || c == '\n' || c == 11 /*vertical tab*/ || c == '\f';
// codes of whitespace symbols: 9 HT, 10 \n, 11 VT, 12 form feed, 13 \r, 32 space
// easy to understand version, validated:
// return ((1 << (c-1)) & 0x80001F00) != 0 && ((c-1)&0xE0) == 0;
// 5% faster on Core i7, 35% faster on Xbox360, no branches, validated:
#ifdef _X360
return ((1 << (c-1)) & 0x80001F00 & ~(-int((c-1)&0xE0))) != 0;
#else
// this is 11% faster on Core i7 than the previous, VC2005 compiler generates a seemingly unbalanced search tree that's faster
switch(c)
{
case ' ':
case 9:
case '\r':
case '\n':
case 11:
case '\f':
return true;
default:
return false;
}
#endif
}
// These are versions of functions that guarantee NULL termination.
//
// maxLen is the maximum number of bytes in the destination string.
// pDest[maxLen-1] is always NULL terminated if pSrc's length is >= maxLen.
//
// This means the last parameter can usually be a sizeof() of a string.
void V_strncpy( char *pDest, const char *pSrc, int maxLen );
int V_snprintf( char *pDest, int destLen, const char *pFormat, ... ) FMTFUNCTION( 3, 4 );
void V_wcsncpy( wchar_t *pDest, wchar_t const *pSrc, int maxLenInBytes );
int V_snwprintf( wchar_t *pDest, int maxLenInNumWideCharacters, const wchar_t *pFormat, ... );
#define COPY_ALL_CHARACTERS -1
char *V_strncat(char *, const char *, size_t maxLenInBytes, int max_chars_to_copy=COPY_ALL_CHARACTERS );
wchar_t *V_wcsncat(wchar_t *, const wchar_t *, int maxLenInBytes, int max_chars_to_copy=COPY_ALL_CHARACTERS );
char *V_strnlwr(char *, size_t);
// UNDONE: Find a non-compiler-specific way to do this
#ifdef _WIN32
#ifndef _VA_LIST_DEFINED
#ifdef _M_ALPHA
struct va_list
{
char *a0; /* pointer to first homed integer argument */
int offset; /* byte offset of next parameter */
};
#else // !_M_ALPHA
typedef char * va_list;
#endif // !_M_ALPHA
#define _VA_LIST_DEFINED
#endif // _VA_LIST_DEFINED
#elif POSIX
#include <stdarg.h>
#endif
#ifdef _WIN32
#define CORRECT_PATH_SEPARATOR '\\'
#define CORRECT_PATH_SEPARATOR_S "\\"
#define INCORRECT_PATH_SEPARATOR '/'
#define INCORRECT_PATH_SEPARATOR_S "/"
#elif POSIX || defined( _PS3 )
#define CORRECT_PATH_SEPARATOR '/'
#define CORRECT_PATH_SEPARATOR_S "/"
#define INCORRECT_PATH_SEPARATOR '\\'
#define INCORRECT_PATH_SEPARATOR_S "\\"
#endif
int V_vsnprintf( char *pDest, int maxLen, const char *pFormat, va_list params );
int V_vsnprintfRet( char *pDest, int maxLen, const char *pFormat, va_list params, bool *pbTruncated );
// Prints out a pretified memory counter string value ( e.g., 7,233.27 Mb, 1,298.003 Kb, 127 bytes )
char *V_pretifymem( float value, int digitsafterdecimal = 2, bool usebinaryonek = false );
// Prints out a pretified integer with comma separators (eg, 7,233,270,000)
char *V_pretifynum( int64 value );
// Functions for converting hexidecimal character strings back into binary data etc.
//
// e.g.,
// int output;
// V_hextobinary( "ffffffff", 8, &output, sizeof( output ) );
// would make output == 0xfffffff or -1
// Similarly,
// char buffer[ 9 ];
// V_binarytohex( &output, sizeof( output ), buffer, sizeof( buffer ) );
// would put "ffffffff" into buffer (note null terminator!!!)
void V_hextobinary( char const *in, int numchars, byte *out, int maxoutputbytes );
void V_binarytohex( const byte *in, int inputbytes, char *out, int outsize );
// Tools for working with filenames
// Extracts the base name of a file (no path, no extension, assumes '/' or '\' as path separator)
void V_FileBase( const char *in, char *out,int maxlen );
// Remove the final characters of ppath if it's '\' or '/'.
void V_StripTrailingSlash( char *ppath );
// Remove any extension from in and return resulting string in out
void V_StripExtension( const char *in, char *out, int outLen );
// Make path end with extension if it doesn't already have an extension
void V_DefaultExtension( char *path, const char *extension, int pathStringLength );
// Strips any current extension from path and ensures that extension is the new extension.
// NOTE: extension string MUST include the . character
void V_SetExtension( char *path, const char *extension, int pathStringLength );
// Removes any filename from path ( strips back to previous / or \ character )
void V_StripFilename( char *path );
// Remove the final directory from the path
bool V_StripLastDir( char *dirName, int maxlen );
// Returns a pointer to the unqualified file name (no path) of a file name
const char * V_UnqualifiedFileName( const char * in );
char * V_UnqualifiedFileName( char * in );
// Given a path and a filename, composes "path\filename", inserting the (OS correct) separator if necessary
void V_ComposeFileName( const char *path, const char *filename, char *dest, int destSize );
// Copy out the path except for the stuff after the final pathseparator
bool V_ExtractFilePath( const char *path, char *dest, int destSize );
// Copy out the file extension into dest
void V_ExtractFileExtension( const char *path, char *dest, int destSize );
const char *V_GetFileExtension( const char * path );
// returns a pointer to just the filename part of the path
// (everything after the last path seperator)
const char *V_GetFileName( const char * path );
// This removes "./" and "../" from the pathname. pFilename should be a full pathname.
// Returns false if it tries to ".." past the root directory in the drive (in which case
// it is an invalid path).
bool V_RemoveDotSlashes( char *pFilename, char separator = CORRECT_PATH_SEPARATOR );
// If pPath is a relative path, this function makes it into an absolute path
// using the current working directory as the base, or pStartingDir if it's non-NULL.
// Returns false if it runs out of room in the string, or if pPath tries to ".." past the root directory.
void V_MakeAbsolutePath( char *pOut, int outLen, const char *pPath, const char *pStartingDir = NULL );
// Creates a relative path given two full paths
// The first is the full path of the file to make a relative path for.
// The second is the full path of the directory to make the first file relative to
// Returns false if they can't be made relative (on separate drives, for example)
bool V_MakeRelativePath( const char *pFullPath, const char *pDirectory, char *pRelativePath, int nBufLen );
// Fixes up a file name, removing dot slashes, fixing slashes, converting to lowercase, etc.
void V_FixupPathName( char *pOut, size_t nOutLen, const char *pPath );
// Adds a path separator to the end of the string if there isn't one already. Returns false if it would run out of space.
void V_AppendSlash( char *pStr, int strSize );
// Returns true if the path is an absolute path.
bool V_IsAbsolutePath( const char *pPath );
// Scans pIn and replaces all occurences of pMatch with pReplaceWith.
// Writes the result to pOut.
// Returns true if it completed successfully.
// If it would overflow pOut, it fills as much as it can and returns false.
bool V_StrSubst( const char *pIn, const char *pMatch, const char *pReplaceWith,
char *pOut, int outLen, bool bCaseSensitive=false );
// Split the specified string on the specified separator.
// Returns a list of strings separated by pSeparator.
// You are responsible for freeing the contents of outStrings (call outStrings.PurgeAndDeleteElements).
void V_SplitString( const char *pString, const char *pSeparator, CUtlVector<char*, CUtlMemory<char*, int> > &outStrings );
// Just like V_SplitString, but it can use multiple possible separators.
void V_SplitString2( const char *pString, const char **pSeparators, int nSeparators, CUtlVector<char*, CUtlMemory<char*, int> > &outStrings );
// Returns false if the buffer is not large enough to hold the working directory name.
bool V_GetCurrentDirectory( char *pOut, int maxLen );
// Set the working directory thus.
bool V_SetCurrentDirectory( const char *pDirName );
// This function takes a slice out of pStr and stores it in pOut.
// It follows the Python slice convention:
// Negative numbers wrap around the string (-1 references the last character).
// Large numbers are clamped to the end of the string.
void V_StrSlice( const char *pStr, int firstChar, int lastCharNonInclusive, char *pOut, int outSize );
// Chop off the left nChars of a string.
void V_StrLeft( const char *pStr, int nChars, char *pOut, int outSize );
// Chop off the right nChars of a string.
void V_StrRight( const char *pStr, int nChars, char *pOut, int outSize );
// change "special" characters to have their c-style backslash sequence. like \n, \r, \t, ", etc.
// returns a pointer to a newly allocated string, which you must delete[] when finished with.
char *V_AddBackSlashesToSpecialChars( char const *pSrc );
// Force slashes of either type to be = separator character
void V_FixSlashes( char *pname, char separator = CORRECT_PATH_SEPARATOR );
// This function fixes cases of filenames like materials\\blah.vmt or somepath\otherpath\\ and removes the extra double slash.
void V_FixDoubleSlashes( char *pStr );
// Convert multibyte to wchar + back
// Specify -1 for nInSize for null-terminated string
void V_strtowcs( const char *pString, int nInSize, wchar_t *pWString, int nOutSize );
void V_wcstostr( const wchar_t *pWString, int nInSize, char *pString, int nOutSize );
// buffer-safe strcat
inline void V_strcat( char *dest, const char *src, int maxLenInBytes )
{
V_strncat( dest, src, maxLenInBytes, COPY_ALL_CHARACTERS );
}
// buffer-safe strcat
inline void V_wcscat( wchar_t *dest, const wchar_t *src, int maxLenInBytes )
{
V_wcsncat( dest, src, maxLenInBytes, COPY_ALL_CHARACTERS );
}
// Convert from a string to an array of integers.
void V_StringToIntArray( int *pVector, int count, const char *pString );
// Convert from a string to a 4 byte color value.
void V_StringToColor32( color32 *color, const char *pString );
// Convert \r\n (Windows linefeeds) to \n (Unix linefeeds).
void V_TranslateLineFeedsToUnix( char *pStr );
//-----------------------------------------------------------------------------
// generic unique name helper functions
//-----------------------------------------------------------------------------
// returns -1 if no match, nDefault if pName==prefix, and N if pName==prefix+N
inline int V_IndexAfterPrefix( const char *pName, const char *prefix, int nDefault = 0 )
{
if ( !pName || !prefix )
return -1;
const char *pIndexStr = StringAfterPrefix( pName, prefix );
if ( !pIndexStr )
return -1;
if ( !*pIndexStr )
return nDefault;
return atoi( pIndexStr );
}
// returns startindex if none found, 2 if "prefix" found, and n+1 if "prefixn" found
template < class NameArray >
int V_GenerateUniqueNameIndex( const char *prefix, const NameArray &nameArray, int startindex = 0 )
{
if ( !prefix )
return 0;
int freeindex = startindex;
int nNames = nameArray.Count();
for ( int i = 0; i < nNames; ++i )
{
int index = V_IndexAfterPrefix( nameArray[ i ], prefix, 1 ); // returns -1 if no match, 0 for exact match, N for
if ( index >= freeindex )
{
// TODO - check that there isn't more junk after the index in pElementName
freeindex = index + 1;
}
}
return freeindex;
}
template < class NameArray >
bool V_GenerateUniqueName( char *name, int memsize, const char *prefix, const NameArray &nameArray )
{
if ( name == NULL || memsize == 0 )
return false;
if ( prefix == NULL )
{
name[ 0 ] = '\0';
return false;
}
int prefixLength = V_strlen( prefix );
if ( prefixLength + 1 > memsize )
{
name[ 0 ] = '\0';
return false;
}
int i = V_GenerateUniqueNameIndex( prefix, nameArray );
if ( i <= 0 )
{
V_strncpy( name, prefix, memsize );
return true;
}
int newlen = prefixLength + ( int )log10( ( float )i ) + 1;
if ( newlen + 1 > memsize )
{
V_strncpy( name, prefix, memsize );
return false;
}
V_snprintf( name, memsize, "%s%d", prefix, i );
return true;
}
extern bool V_StringToBin( const char*pString, void *pBin, uint nBinSize );
extern bool V_BinToString( char*pString, void *pBin, uint nBinSize );
template<typename T>
struct BinString_t
{
BinString_t(){}
BinString_t( const char *pStr )
{
V_strncpy( m_string, pStr, sizeof(m_string) );
ToBin();
}
BinString_t( const T & that )
{
m_bin = that;
ToString();
}
bool ToBin()
{
return V_StringToBin( m_string, &m_bin, sizeof( m_bin ) );
}
void ToString()
{
V_BinToString( m_string, &m_bin, sizeof( m_bin ) );
}
T m_bin;
char m_string[sizeof(T)*2+2]; // 0-terminated string representing the binary data in hex
};
template <typename T>
inline BinString_t<T> MakeBinString( const T& that )
{
return BinString_t<T>( that );
}
#if defined(_PS3) || defined(POSIX)
#define PRI_WS_FOR_WS L"%ls"
#define PRI_WS_FOR_S "%ls"
#define PRI_S_FOR_WS L"%s"
#define PRI_S_FOR_S "%s"
#else
#define PRI_WS_FOR_WS L"%s"
#define PRI_WS_FOR_S "%S"
#define PRI_S_FOR_WS L"%S"
#define PRI_S_FOR_S "%s"
#endif
namespace AsianWordWrap
{
// Functions used by Asian language line wrapping to determine if a character can end a line, begin a line, or be broken up when repeated (eg: "...")
bool CanEndLine( wchar_t wcCandidate );
bool CanBeginLine( wchar_t wcCandidate );
bool CanBreakRepeated( wchar_t wcCandidate );
// Used to determine if we can break a line between the first two characters passed; calls the above functions on each character
bool CanBreakAfter( const wchar_t* wsz );
}
// We use this function to determine where it is permissible to break lines
// of text while wrapping them. On most platforms, the native iswspace() function
// returns FALSE for the "non-breaking space" characters 0x00a0 and 0x202f, and so we don't
// break on them. On the 360, however, iswspace returns TRUE for them. So, on that
// platform, we work around it by defining this wrapper which returns false
// for &nbsp; and calls through to the library function for everything else.
int isbreakablewspace( wchar_t ch );
#endif // TIER1_STRTOOLS_H

85
external/vpc/public/tier1/tier1.h vendored Normal file
View File

@@ -0,0 +1,85 @@
//===== Copyright <20> 2005-2005, Valve Corporation, All rights reserved. ======//
//
// Purpose: A higher level link library for general use in the game and tools.
//
//===========================================================================//
#ifndef TIER1_H
#define TIER1_H
#if defined( _WIN32 )
#pragma once
#endif
#include "appframework/iappsystem.h"
#include "tier1/convar.h"
//-----------------------------------------------------------------------------
// Forward declarations
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// Call this to connect to/disconnect from all tier 1 libraries.
// It's up to the caller to check the globals it cares about to see if ones are missing
//-----------------------------------------------------------------------------
void ConnectTier1Libraries( CreateInterfaceFn *pFactoryList, int nFactoryCount );
void DisconnectTier1Libraries();
//-----------------------------------------------------------------------------
// Helper empty implementation of an IAppSystem for tier2 libraries
//-----------------------------------------------------------------------------
template< class IInterface, int ConVarFlag = 0 >
class CTier1AppSystem : public CTier0AppSystem< IInterface >
{
typedef CTier0AppSystem< IInterface > BaseClass;
public:
virtual bool Connect( CreateInterfaceFn factory )
{
if ( !BaseClass::Connect( factory ) )
return false;
ConnectTier1Libraries( &factory, 1 );
return true;
}
virtual void Disconnect()
{
DisconnectTier1Libraries();
BaseClass::Disconnect();
}
virtual InitReturnVal_t Init()
{
InitReturnVal_t nRetVal = BaseClass::Init();
if ( nRetVal != INIT_OK )
return nRetVal;
if ( g_pCVar )
{
ConVar_Register( ConVarFlag );
}
return INIT_OK;
}
virtual void Shutdown()
{
if ( g_pCVar )
{
ConVar_Unregister( );
}
BaseClass::Shutdown( );
}
virtual AppSystemTier_t GetTier()
{
return APP_SYSTEM_TIER1;
}
};
#endif // TIER1_H

View File

@@ -0,0 +1,349 @@
//===== Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ======//
//
// Purpose:
//
// $NoKeywords: $
//
// A growable memory class.
//===========================================================================//
#ifndef UTLBLOCKMEMORY_H
#define UTLBLOCKMEMORY_H
#ifdef _WIN32
#pragma once
#endif
#include "tier0/dbg.h"
#include "tier0/platform.h"
#include "mathlib/mathlib.h"
#include "tier0/memalloc.h"
#include "tier0/memdbgon.h"
#pragma warning (disable:4100)
#pragma warning (disable:4514)
//-----------------------------------------------------------------------------
#ifdef UTBLOCKLMEMORY_TRACK
#define UTLBLOCKMEMORY_TRACK_ALLOC() MemAlloc_RegisterAllocation( "||Sum of all UtlBlockMemory||", 0, NumAllocated() * sizeof(T), NumAllocated() * sizeof(T), 0 )
#define UTLBLOCKMEMORY_TRACK_FREE() if ( !m_pMemory ) ; else MemAlloc_RegisterDeallocation( "||Sum of all UtlBlockMemory||", 0, NumAllocated() * sizeof(T), NumAllocated() * sizeof(T), 0 )
#else
#define UTLBLOCKMEMORY_TRACK_ALLOC() ((void)0)
#define UTLBLOCKMEMORY_TRACK_FREE() ((void)0)
#endif
//-----------------------------------------------------------------------------
// The CUtlBlockMemory class:
// A growable memory class that allocates non-sequential blocks, but is indexed sequentially
//-----------------------------------------------------------------------------
template< class T, class I >
class CUtlBlockMemory
{
public:
// constructor, destructor
CUtlBlockMemory( int nGrowSize = 0, int nInitSize = 0 );
~CUtlBlockMemory();
// Set the size by which the memory grows - round up to the next power of 2
void Init( int nGrowSize = 0, int nInitSize = 0 );
// here to match CUtlMemory, but only used by ResetDbgInfo, so it can just return NULL
T* Base() { return NULL; }
const T* Base() const { return NULL; }
class Iterator_t
{
public:
Iterator_t( I i ) : index( i ) {}
I index;
bool operator==( const Iterator_t it ) const { return index == it.index; }
bool operator!=( const Iterator_t it ) const { return index != it.index; }
};
Iterator_t First() const { return Iterator_t( IsIdxValid( 0 ) ? 0 : InvalidIndex() ); }
Iterator_t Next( const Iterator_t &it ) const { return Iterator_t( IsIdxValid( it.index + 1 ) ? it.index + 1 : InvalidIndex() ); }
I GetIndex( const Iterator_t &it ) const { return it.index; }
bool IsIdxAfter( I i, const Iterator_t &it ) const { return i > it.index; }
bool IsValidIterator( const Iterator_t &it ) const { return IsIdxValid( it.index ); }
Iterator_t InvalidIterator() const { return Iterator_t( InvalidIndex() ); }
// element access
T& operator[]( I i );
const T& operator[]( I i ) const;
T& Element( I i );
const T& Element( I i ) const;
// Can we use this index?
bool IsIdxValid( I i ) const;
static I InvalidIndex() { return ( I )-1; }
void Swap( CUtlBlockMemory< T, I > &mem );
// Size
int NumAllocated() const;
int Count() const { return NumAllocated(); }
// Grows memory by max(num,growsize) rounded up to the next power of 2, and returns the allocation index/ptr
void Grow( int num = 1 );
// Makes sure we've got at least this much memory
void EnsureCapacity( int num );
// Memory deallocation
void Purge();
// Purge all but the given number of elements
void Purge( int numElements );
protected:
int Index( int major, int minor ) const { return ( major << m_nIndexShift ) | minor; }
int MajorIndex( int i ) const { return i >> m_nIndexShift; }
int MinorIndex( int i ) const { return i & m_nIndexMask; }
void ChangeSize( int nBlocks );
int NumElementsInBlock() const { return m_nIndexMask + 1; }
T** m_pMemory;
int m_nBlocks;
int m_nIndexMask : 27;
int m_nIndexShift : 5;
};
//-----------------------------------------------------------------------------
// constructor, destructor
//-----------------------------------------------------------------------------
template< class T, class I >
CUtlBlockMemory<T,I>::CUtlBlockMemory( int nGrowSize, int nInitAllocationCount )
: m_pMemory( 0 ), m_nBlocks( 0 ), m_nIndexMask( 0 ), m_nIndexShift( 0 )
{
Init( nGrowSize, nInitAllocationCount );
}
template< class T, class I >
CUtlBlockMemory<T,I>::~CUtlBlockMemory()
{
Purge();
}
//-----------------------------------------------------------------------------
// Fast swap
//-----------------------------------------------------------------------------
template< class T, class I >
void CUtlBlockMemory<T,I>::Swap( CUtlBlockMemory< T, I > &mem )
{
V_swap( m_pMemory, mem.m_pMemory );
V_swap( m_nBlocks, mem.m_nBlocks );
V_swap( m_nIndexMask, mem.m_nIndexMask );
V_swap( m_nIndexShift, mem.m_nIndexShift );
}
//-----------------------------------------------------------------------------
// Set the size by which the memory grows - round up to the next power of 2
//-----------------------------------------------------------------------------
template< class T, class I >
void CUtlBlockMemory<T,I>::Init( int nGrowSize /* = 0 */, int nInitSize /* = 0 */ )
{
Purge();
if ( nGrowSize == 0)
{
// default grow size is smallest size s.t. c++ allocation overhead is ~6% of block size
nGrowSize = ( 127 + sizeof( T ) ) / sizeof( T );
}
nGrowSize = SmallestPowerOfTwoGreaterOrEqual( nGrowSize );
m_nIndexMask = nGrowSize - 1;
m_nIndexShift = 0;
while ( nGrowSize > 1 )
{
nGrowSize >>= 1;
++m_nIndexShift;
}
Assert( m_nIndexMask + 1 == ( 1 << m_nIndexShift ) );
Grow( nInitSize );
}
//-----------------------------------------------------------------------------
// element access
//-----------------------------------------------------------------------------
template< class T, class I >
inline T& CUtlBlockMemory<T,I>::operator[]( I i )
{
Assert( IsIdxValid(i) );
T *pBlock = m_pMemory[ MajorIndex( i ) ];
return pBlock[ MinorIndex( i ) ];
}
template< class T, class I >
inline const T& CUtlBlockMemory<T,I>::operator[]( I i ) const
{
Assert( IsIdxValid(i) );
const T *pBlock = m_pMemory[ MajorIndex( i ) ];
return pBlock[ MinorIndex( i ) ];
}
template< class T, class I >
inline T& CUtlBlockMemory<T,I>::Element( I i )
{
Assert( IsIdxValid(i) );
T *pBlock = m_pMemory[ MajorIndex( i ) ];
return pBlock[ MinorIndex( i ) ];
}
template< class T, class I >
inline const T& CUtlBlockMemory<T,I>::Element( I i ) const
{
Assert( IsIdxValid(i) );
const T *pBlock = m_pMemory[ MajorIndex( i ) ];
return pBlock[ MinorIndex( i ) ];
}
//-----------------------------------------------------------------------------
// Size
//-----------------------------------------------------------------------------
template< class T, class I >
inline int CUtlBlockMemory<T,I>::NumAllocated() const
{
return m_nBlocks * NumElementsInBlock();
}
//-----------------------------------------------------------------------------
// Is element index valid?
//-----------------------------------------------------------------------------
template< class T, class I >
inline bool CUtlBlockMemory<T,I>::IsIdxValid( I i ) const
{
return ( i >= 0 ) && ( MajorIndex( i ) < m_nBlocks );
}
template< class T, class I >
void CUtlBlockMemory<T,I>::Grow( int num )
{
if ( num <= 0 )
return;
int nBlockSize = NumElementsInBlock();
int nBlocks = ( num + nBlockSize - 1 ) / nBlockSize;
ChangeSize( m_nBlocks + nBlocks );
}
template< class T, class I >
void CUtlBlockMemory<T,I>::ChangeSize( int nBlocks )
{
UTLBLOCKMEMORY_TRACK_FREE(); // this must stay before the recalculation of m_nBlocks, since it implicitly uses the old value
int nBlocksOld = m_nBlocks;
m_nBlocks = nBlocks;
UTLBLOCKMEMORY_TRACK_ALLOC(); // this must stay after the recalculation of m_nBlocks, since it implicitly uses the new value
// free old blocks if shrinking
for ( int i = m_nBlocks; i < nBlocksOld; ++i )
{
UTLBLOCKMEMORY_TRACK_FREE();
free( (void*)m_pMemory[ i ] );
}
if ( m_pMemory )
{
MEM_ALLOC_CREDIT_CLASS();
m_pMemory = (T**)realloc( m_pMemory, m_nBlocks * sizeof(T*) );
Assert( m_pMemory );
}
else
{
MEM_ALLOC_CREDIT_CLASS();
m_pMemory = (T**)malloc( m_nBlocks * sizeof(T*) );
Assert( m_pMemory );
}
if ( !m_pMemory )
{
Error( "CUtlBlockMemory overflow!\n" );
}
// allocate new blocks if growing
int nBlockSize = NumElementsInBlock();
for ( int i = nBlocksOld; i < m_nBlocks; ++i )
{
MEM_ALLOC_CREDIT_CLASS();
m_pMemory[ i ] = (T*)malloc( nBlockSize * sizeof( T ) );
Assert( m_pMemory[ i ] );
}
}
//-----------------------------------------------------------------------------
// Makes sure we've got at least this much memory
//-----------------------------------------------------------------------------
template< class T, class I >
inline void CUtlBlockMemory<T,I>::EnsureCapacity( int num )
{
Grow( num - NumAllocated() );
}
//-----------------------------------------------------------------------------
// Memory deallocation
//-----------------------------------------------------------------------------
template< class T, class I >
void CUtlBlockMemory<T,I>::Purge()
{
if ( !m_pMemory )
return;
for ( int i = 0; i < m_nBlocks; ++i )
{
UTLBLOCKMEMORY_TRACK_FREE();
free( (void*)m_pMemory[ i ] );
}
m_nBlocks = 0;
UTLBLOCKMEMORY_TRACK_FREE();
free( (void*)m_pMemory );
m_pMemory = 0;
}
template< class T, class I >
void CUtlBlockMemory<T,I>::Purge( int numElements )
{
Assert( numElements >= 0 );
int nAllocated = NumAllocated();
if ( numElements > nAllocated )
{
// Ensure this isn't a grow request in disguise.
Assert( numElements <= nAllocated );
return;
}
if ( numElements <= 0 )
{
Purge();
return;
}
int nBlockSize = NumElementsInBlock();
int nBlocksOld = m_nBlocks;
int nBlocks = ( numElements + nBlockSize - 1 ) / nBlockSize;
// If the number of blocks is the same as the allocated number of blocks, we are done.
if ( nBlocks == m_nBlocks )
return;
ChangeSize( nBlocks );
}
#include "tier0/memdbgoff.h"
#endif // UTLBLOCKMEMORY_H

1396
external/vpc/public/tier1/utlbuffer.h vendored Normal file

File diff suppressed because it is too large Load Diff

338
external/vpc/public/tier1/utldict.h vendored Normal file
View File

@@ -0,0 +1,338 @@
//====== Copyright <20> 1996-2005, Valve Corporation, All rights reserved. =======//
//
// Purpose: A dictionary mapping from symbol to structure
//
// $Header: $
// $NoKeywords: $
//=============================================================================//
#ifndef UTLDICT_H
#define UTLDICT_H
#ifdef _WIN32
#pragma once
#endif
#include "tier0/dbg.h"
#include "tier1/utlmap.h"
// Include this because tons of code was implicitly getting utlsymbol or utlvector via utldict.h
#include "tier1/utlsymbol.h"
#include "tier0/memdbgon.h"
enum EDictCompareType
{
k_eDictCompareTypeCaseSensitive=0,
k_eDictCompareTypeCaseInsensitive=1,
k_eDictCompareTypeFilenames // Slashes and backslashes count as the same character..
};
//-----------------------------------------------------------------------------
// A dictionary mapping from symbol to structure
//-----------------------------------------------------------------------------
#define FOR_EACH_DICT( dictName, iteratorName ) \
for( int iteratorName=dictName.First(); iteratorName != dictName.InvalidIndex(); iteratorName = dictName.Next( iteratorName ) )
// faster iteration, but in an unspecified order
#define FOR_EACH_DICT_FAST( dictName, iteratorName ) \
for ( int iteratorName = 0; iteratorName < dictName.MaxElement(); ++iteratorName ) if ( !dictName.IsValidIndex( iteratorName ) ) continue; else
//-----------------------------------------------------------------------------
// A dictionary mapping from symbol to structure
//-----------------------------------------------------------------------------
template <class T, class I = int >
class CUtlDict
{
public:
// constructor, destructor
// Left at growSize = 0, the memory will first allocate 1 element and double in size
// at each increment.
CUtlDict( int compareType = k_eDictCompareTypeCaseInsensitive, int growSize = 0, int initSize = 0 );
~CUtlDict( );
void EnsureCapacity( int );
// gets particular elements
T& Element( I i );
const T& Element( I i ) const;
T& operator[]( I i );
const T& operator[]( I i ) const;
// gets element names
char *GetElementName( I i );
char const *GetElementName( I i ) const;
void SetElementName( I i, char const *pName );
// Number of elements
unsigned int Count() const;
// Checks if a node is valid and in the tree
bool IsValidIndex( I i ) const;
// Invalid index
static I InvalidIndex();
// Insert method (inserts in order)
I Insert( const char *pName, const T &element );
I Insert( const char *pName );
// Find method
I Find( const char *pName ) const;
// Remove methods
void RemoveAt( I i );
void Remove( const char *pName );
void RemoveAll( );
// Purge memory
void Purge();
void PurgeAndDeleteElements(); // Call delete on each element.
// Iteration methods
I First() const;
I Next( I i ) const;
// Nested typedefs, for code that might need
// to fish out the index type from a given dict
typedef I IndexType_t;
protected:
typedef CUtlMap<const char *, T, I> DictElementMap_t;
DictElementMap_t m_Elements;
};
//-----------------------------------------------------------------------------
// constructor, destructor
//-----------------------------------------------------------------------------
template <class T, class I>
CUtlDict<T, I>::CUtlDict( int compareType, int growSize, int initSize ) : m_Elements( growSize, initSize )
{
if ( compareType == k_eDictCompareTypeFilenames )
{
m_Elements.SetLessFunc( CaselessStringLessThanIgnoreSlashes );
}
else if ( compareType == k_eDictCompareTypeCaseInsensitive )
{
m_Elements.SetLessFunc( CaselessStringLessThan );
}
else
{
m_Elements.SetLessFunc( StringLessThan );
}
}
template <class T, class I>
CUtlDict<T, I>::~CUtlDict()
{
Purge();
}
template <class T, class I>
inline void CUtlDict<T, I>::EnsureCapacity( int num )
{
return m_Elements.EnsureCapacity( num );
}
//-----------------------------------------------------------------------------
// gets particular elements
//-----------------------------------------------------------------------------
template <class T, class I>
inline T& CUtlDict<T, I>::Element( I i )
{
return m_Elements[i];
}
template <class T, class I>
inline const T& CUtlDict<T, I>::Element( I i ) const
{
return m_Elements[i];
}
//-----------------------------------------------------------------------------
// gets element names
//-----------------------------------------------------------------------------
template <class T, class I>
inline char *CUtlDict<T, I>::GetElementName( I i )
{
return (char *)m_Elements.Key( i );
}
template <class T, class I>
inline char const *CUtlDict<T, I>::GetElementName( I i ) const
{
return m_Elements.Key( i );
}
template <class T, class I>
inline T& CUtlDict<T, I>::operator[]( I i )
{
return Element(i);
}
template <class T, class I>
inline const T & CUtlDict<T, I>::operator[]( I i ) const
{
return Element(i);
}
template <class T, class I>
inline void CUtlDict<T, I>::SetElementName( I i, char const *pName )
{
MEM_ALLOC_CREDIT_CLASS();
// TODO: This makes a copy of the old element
// TODO: This relies on the rb tree putting the most recently
// removed element at the head of the insert list
free( (void *)m_Elements.Key( i ) );
m_Elements.Reinsert( strdup( pName ), i );
}
//-----------------------------------------------------------------------------
// Num elements
//-----------------------------------------------------------------------------
template <class T, class I>
inline unsigned int CUtlDict<T, I>::Count() const
{
return m_Elements.Count();
}
//-----------------------------------------------------------------------------
// Checks if a node is valid and in the tree
//-----------------------------------------------------------------------------
template <class T, class I>
inline bool CUtlDict<T, I>::IsValidIndex( I i ) const
{
return m_Elements.IsValidIndex(i);
}
//-----------------------------------------------------------------------------
// Invalid index
//-----------------------------------------------------------------------------
template <class T, class I>
inline I CUtlDict<T, I>::InvalidIndex()
{
return DictElementMap_t::InvalidIndex();
}
//-----------------------------------------------------------------------------
// Delete a node from the tree
//-----------------------------------------------------------------------------
template <class T, class I>
void CUtlDict<T, I>::RemoveAt(I elem)
{
free( (void *)m_Elements.Key( elem ) );
m_Elements.RemoveAt(elem);
}
//-----------------------------------------------------------------------------
// remove a node in the tree
//-----------------------------------------------------------------------------
template <class T, class I> void CUtlDict<T, I>::Remove( const char *search )
{
I node = Find( search );
if (node != InvalidIndex())
{
RemoveAt(node);
}
}
//-----------------------------------------------------------------------------
// Removes all nodes from the tree
//-----------------------------------------------------------------------------
template <class T, class I>
void CUtlDict<T, I>::RemoveAll()
{
typename DictElementMap_t::IndexType_t index = m_Elements.FirstInorder();
while ( index != m_Elements.InvalidIndex() )
{
const char *pKey = m_Elements.Key( index );
free( const_cast<char*>(pKey) );
index = m_Elements.NextInorder( index );
}
m_Elements.RemoveAll();
}
template <class T, class I>
void CUtlDict<T, I>::Purge()
{
RemoveAll();
}
template <class T, class I>
void CUtlDict<T, I>::PurgeAndDeleteElements()
{
// Delete all the elements.
I index = m_Elements.FirstInorder();
while ( index != m_Elements.InvalidIndex() )
{
const char* pKey = m_Elements.Key( index );
free( const_cast<char*>(pKey) );
delete m_Elements[index];
index = m_Elements.NextInorder( index );
}
m_Elements.RemoveAll();
}
//-----------------------------------------------------------------------------
// inserts a node into the tree
//-----------------------------------------------------------------------------
template <class T, class I>
I CUtlDict<T, I>::Insert( const char *pName, const T &element )
{
MEM_ALLOC_CREDIT_CLASS();
return m_Elements.Insert( strdup( pName ), element );
}
template <class T, class I>
I CUtlDict<T, I>::Insert( const char *pName )
{
MEM_ALLOC_CREDIT_CLASS();
return m_Elements.Insert( strdup( pName ) );
}
//-----------------------------------------------------------------------------
// finds a node in the tree
//-----------------------------------------------------------------------------
template <class T, class I>
I CUtlDict<T, I>::Find( const char *pName ) const
{
MEM_ALLOC_CREDIT_CLASS();
if ( pName )
return m_Elements.Find( pName );
else
return InvalidIndex();
}
//-----------------------------------------------------------------------------
// Iteration methods
//-----------------------------------------------------------------------------
template <class T, class I>
I CUtlDict<T, I>::First() const
{
return m_Elements.FirstInorder();
}
template <class T, class I>
I CUtlDict<T, I>::Next( I i ) const
{
return m_Elements.NextInorder(i);
}
#include "tier0/memdbgoff.h"
#endif // UTLDICT_H

241
external/vpc/public/tier1/utlenvelope.h vendored Normal file
View File

@@ -0,0 +1,241 @@
//========== Copyright <20> 2005, Valve Corporation, All rights reserved. ========
//
// Purpose: A class to wrap data for transport over a boundary like a thread
// or window.
//
//=============================================================================
#include "tier1/utlstring.h"
#include "tier0/basetypes.h"
#ifndef UTLENVELOPE_H
#define UTLENVELOPE_H
#if defined( _WIN32 )
#pragma once
#endif
//-----------------------------------------------------------------------------
class CUtlDataEnvelope
{
public:
CUtlDataEnvelope( const void *pData, int nBytes );
CUtlDataEnvelope( const CUtlDataEnvelope &from );
~CUtlDataEnvelope();
CUtlDataEnvelope &operator=( const CUtlDataEnvelope &from );
operator void *();
operator void *() const;
private:
void Assign( const void *pData, int nBytes );
void Assign( const CUtlDataEnvelope &from );
void Purge();
// TODO: switch to a reference counted array?
union
{
byte *m_pData;
byte m_data[4];
};
int m_nBytes;
};
//-----------------------------------------------------------------------------
template <typename T>
class CUtlEnvelope : protected CUtlDataEnvelope
{
public:
CUtlEnvelope( const T *pData, int nElems = 1 );
CUtlEnvelope( const CUtlEnvelope<T> &from );
CUtlEnvelope<T> &operator=( const CUtlEnvelope<T> &from );
operator T *();
operator T *() const;
operator void *();
operator void *() const;
};
//-----------------------------------------------------------------------------
template <>
class CUtlEnvelope<const char *>
{
public:
CUtlEnvelope( const char *pData )
{
m_string = pData;
}
CUtlEnvelope( const CUtlEnvelope<const char *> &from )
{
m_string = from.m_string;
}
CUtlEnvelope<const char *> &operator=( const CUtlEnvelope<const char *> &from )
{
m_string = from.m_string;
return *this;
}
operator char *()
{
return (char *) m_string.Get();
}
operator char *() const
{
return (char *) m_string.Get();
}
operator void *()
{
return (void *) m_string.Get();
}
operator void *() const
{
return (void *) m_string.Get();
}
private:
CUtlString m_string;
};
//-----------------------------------------------------------------------------
#include "tier0/memdbgon.h"
inline void CUtlDataEnvelope::Assign( const void *pData, int nBytes )
{
if ( pData )
{
m_nBytes = nBytes;
if ( m_nBytes > 4 )
{
m_pData = new byte[nBytes];
memcpy( m_pData, pData, nBytes );
}
else
{
memcpy( m_data, pData, nBytes );
}
}
else
{
m_pData = NULL;
m_nBytes = 0;
}
}
inline void CUtlDataEnvelope::Assign( const CUtlDataEnvelope &from )
{
Assign( from.operator void *(), from.m_nBytes );
}
inline void CUtlDataEnvelope::Purge()
{
if (m_nBytes > 4)
delete [] m_pData;
m_nBytes = 0;
}
inline CUtlDataEnvelope::CUtlDataEnvelope( const void *pData, int nBytes )
{
Assign( pData, nBytes );
}
inline CUtlDataEnvelope::CUtlDataEnvelope( const CUtlDataEnvelope &from )
{
Assign( from );
}
inline CUtlDataEnvelope::~CUtlDataEnvelope()
{
Purge();
}
inline CUtlDataEnvelope &CUtlDataEnvelope::operator=( const CUtlDataEnvelope &from )
{
Purge();
Assign( from );
return *this;
}
inline CUtlDataEnvelope::operator void *()
{
if ( !m_nBytes )
{
return NULL;
}
return ( m_nBytes > 4) ? m_pData : m_data;
}
inline CUtlDataEnvelope::operator void *() const
{
if ( !m_nBytes )
{
return NULL;
}
return ( m_nBytes > 4) ? (void *)m_pData : (void *)m_data;
}
//-----------------------------------------------------------------------------
template <typename T>
inline CUtlEnvelope<T>::CUtlEnvelope( const T *pData, int nElems )
: CUtlDataEnvelope( pData, sizeof(T) * nElems )
{
}
template <typename T>
inline CUtlEnvelope<T>::CUtlEnvelope( const CUtlEnvelope<T> &from )
: CUtlDataEnvelope( from )
{
}
template <typename T>
inline CUtlEnvelope<T> &CUtlEnvelope<T>::operator=( const CUtlEnvelope<T> &from )
{
CUtlDataEnvelope::operator=( from );
return *this;
}
template <typename T>
inline CUtlEnvelope<T>::operator T *()
{
return (T *)CUtlDataEnvelope::operator void *();
}
template <typename T>
inline CUtlEnvelope<T>::operator T *() const
{
return (T *)( (const_cast<CUtlEnvelope<T> *>(this))->operator T *() );
}
template <typename T>
inline CUtlEnvelope<T>::operator void *()
{
return CUtlDataEnvelope::operator void *();
}
template <typename T>
inline CUtlEnvelope<T>::operator void *() const
{
return ( (const_cast<CUtlEnvelope<T> *>(this))->operator void *() );
}
//-----------------------------------------------------------------------------
#include "tier0/memdbgoff.h"
#endif // UTLENVELOPE_H

View File

@@ -0,0 +1,354 @@
//===== Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ======//
//
// Purpose:
//
// $NoKeywords: $
//
// A growable memory class.
//===========================================================================//
#ifndef UTLFIXEDMEMORY_H
#define UTLFIXEDMEMORY_H
#ifdef _WIN32
#pragma once
#endif
#include "tier0/dbg.h"
#include "tier0/platform.h"
#include "tier0/memalloc.h"
#include "tier0/memdbgon.h"
#pragma warning (disable:4100)
#pragma warning (disable:4514)
//-----------------------------------------------------------------------------
#ifdef UTLFIXEDMEMORY_TRACK
#define UTLFIXEDMEMORY_TRACK_ALLOC() MemAlloc_RegisterAllocation( "||Sum of all UtlFixedMemory||", 0, NumAllocated() * sizeof(T), NumAllocated() * sizeof(T), 0 )
#define UTLFIXEDMEMORY_TRACK_FREE() if ( !m_pMemory ) ; else MemAlloc_RegisterDeallocation( "||Sum of all UtlFixedMemory||", 0, NumAllocated() * sizeof(T), NumAllocated() * sizeof(T), 0 )
#else
#define UTLFIXEDMEMORY_TRACK_ALLOC() ((void)0)
#define UTLFIXEDMEMORY_TRACK_FREE() ((void)0)
#endif
//-----------------------------------------------------------------------------
// The CUtlFixedMemory class:
// A growable memory class that allocates non-sequential blocks, but is indexed sequentially
//-----------------------------------------------------------------------------
template< class T >
class CUtlFixedMemory
{
public:
// constructor, destructor
CUtlFixedMemory( int nGrowSize = 0, int nInitSize = 0 );
~CUtlFixedMemory();
// Set the size by which the memory grows
void Init( int nGrowSize = 0, int nInitSize = 0 );
// here to match CUtlMemory, but only used by ResetDbgInfo, so it can just return NULL
T* Base() { return NULL; }
const T* Base() const { return NULL; }
protected:
struct BlockHeader_t;
public:
class Iterator_t
{
public:
Iterator_t( BlockHeader_t *p, int i ) : m_pBlockHeader( p ), m_nIndex( i ) {}
BlockHeader_t *m_pBlockHeader;
int m_nIndex;
bool operator==( const Iterator_t it ) const { return m_pBlockHeader == it.m_pBlockHeader && m_nIndex == it.m_nIndex; }
bool operator!=( const Iterator_t it ) const { return m_pBlockHeader != it.m_pBlockHeader || m_nIndex != it.m_nIndex; }
};
Iterator_t First() const { return m_pBlocks ? Iterator_t( m_pBlocks, 0 ) : InvalidIterator(); }
Iterator_t Next( const Iterator_t &it ) const
{
Assert( IsValidIterator( it ) );
if ( !IsValidIterator( it ) )
return InvalidIterator();
BlockHeader_t * RESTRICT pHeader = it.m_pBlockHeader;
if ( it.m_nIndex + 1 < pHeader->m_nBlockSize )
return Iterator_t( pHeader, it.m_nIndex + 1 );
return pHeader->m_pNext ? Iterator_t( pHeader->m_pNext, 0 ) : InvalidIterator();
}
int GetIndex( const Iterator_t &it ) const
{
Assert( IsValidIterator( it ) );
if ( !IsValidIterator( it ) )
return InvalidIndex();
return ( int )( HeaderToBlock( it.m_pBlockHeader ) + it.m_nIndex );
}
bool IsIdxAfter( int i, const Iterator_t &it ) const
{
Assert( IsValidIterator( it ) );
if ( !IsValidIterator( it ) )
return false;
if ( IsInBlock( i, it.m_pBlockHeader ) )
return i > GetIndex( it );
for ( BlockHeader_t * RESTRICT pbh = it.m_pBlockHeader->m_pNext; pbh; pbh = pbh->m_pNext )
{
if ( IsInBlock( i, pbh ) )
return true;
}
return false;
}
bool IsValidIterator( const Iterator_t &it ) const { return it.m_pBlockHeader && it.m_nIndex >= 0 && it.m_nIndex < it.m_pBlockHeader->m_nBlockSize; }
Iterator_t InvalidIterator() const { return Iterator_t( NULL, -1 ); }
// element access
T& operator[]( int i );
const T& operator[]( int i ) const;
T& Element( int i );
const T& Element( int i ) const;
// Can we use this index?
bool IsIdxValid( int i ) const;
// Specify the invalid ('null') index that we'll only return on failure
static const int INVALID_INDEX = 0; // For use with COMPILE_TIME_ASSERT
static int InvalidIndex() { return INVALID_INDEX; }
// Size
int NumAllocated() const;
int Count() const { return NumAllocated(); }
// Grows memory by max(num,growsize), and returns the allocation index/ptr
void Grow( int num = 1 );
// Makes sure we've got at least this much memory
void EnsureCapacity( int num );
// Memory deallocation
void Purge();
protected:
// Fast swap - WARNING: Swap invalidates all ptr-based indices!!!
void Swap( CUtlFixedMemory< T > &mem );
bool IsInBlock( int i, BlockHeader_t *pBlockHeader ) const
{
T *p = ( T* )i;
const T *p0 = HeaderToBlock( pBlockHeader );
return p >= p0 && p < p0 + pBlockHeader->m_nBlockSize;
}
struct BlockHeader_t
{
BlockHeader_t *m_pNext;
int m_nBlockSize;
};
const T *HeaderToBlock( const BlockHeader_t *pHeader ) const { return ( T* )( pHeader + 1 ); }
const BlockHeader_t *BlockToHeader( const T *pBlock ) const { return ( BlockHeader_t* )( pBlock ) - 1; }
BlockHeader_t* m_pBlocks;
int m_nAllocationCount;
int m_nGrowSize;
};
//-----------------------------------------------------------------------------
// constructor, destructor
//-----------------------------------------------------------------------------
template< class T >
CUtlFixedMemory<T>::CUtlFixedMemory( int nGrowSize, int nInitAllocationCount )
: m_pBlocks( 0 ), m_nAllocationCount( 0 ), m_nGrowSize( 0 )
{
Init( nGrowSize, nInitAllocationCount );
}
template< class T >
CUtlFixedMemory<T>::~CUtlFixedMemory()
{
Purge();
}
//-----------------------------------------------------------------------------
// Fast swap - WARNING: Swap invalidates all ptr-based indices!!!
//-----------------------------------------------------------------------------
template< class T >
void CUtlFixedMemory<T>::Swap( CUtlFixedMemory< T > &mem )
{
V_swap( m_pBlocks, mem.m_pBlocks );
V_swap( m_nAllocationCount, mem.m_nAllocationCount );
V_swap( m_nGrowSize, mem.m_nGrowSize );
}
//-----------------------------------------------------------------------------
// Set the size by which the memory grows - round up to the next power of 2
//-----------------------------------------------------------------------------
template< class T >
void CUtlFixedMemory<T>::Init( int nGrowSize /* = 0 */, int nInitSize /* = 0 */ )
{
Purge();
m_nGrowSize = nGrowSize;
Grow( nInitSize );
}
//-----------------------------------------------------------------------------
// element access
//-----------------------------------------------------------------------------
template< class T >
inline T& CUtlFixedMemory<T>::operator[]( int i )
{
Assert( IsIdxValid(i) );
return *( T* )i;
}
template< class T >
inline const T& CUtlFixedMemory<T>::operator[]( int i ) const
{
Assert( IsIdxValid(i) );
return *( T* )i;
}
template< class T >
inline T& CUtlFixedMemory<T>::Element( int i )
{
Assert( IsIdxValid(i) );
return *( T* )i;
}
template< class T >
inline const T& CUtlFixedMemory<T>::Element( int i ) const
{
Assert( IsIdxValid(i) );
return *( T* )i;
}
//-----------------------------------------------------------------------------
// Size
//-----------------------------------------------------------------------------
template< class T >
inline int CUtlFixedMemory<T>::NumAllocated() const
{
return m_nAllocationCount;
}
//-----------------------------------------------------------------------------
// Is element index valid?
//-----------------------------------------------------------------------------
template< class T >
inline bool CUtlFixedMemory<T>::IsIdxValid( int i ) const
{
#ifdef _DEBUG
for ( BlockHeader_t *pbh = m_pBlocks; pbh; pbh = pbh->m_pNext )
{
if ( IsInBlock( i, pbh ) )
return true;
}
return false;
#else
return i != InvalidIndex();
#endif
}
template< class T >
void CUtlFixedMemory<T>::Grow( int num )
{
if ( num <= 0 )
return;
int nBlockSize = m_nGrowSize;
if ( nBlockSize == 0 )
{
if ( m_nAllocationCount )
{
nBlockSize = m_nAllocationCount;
}
else
{
// Compute an allocation which is at least as big as a cache line...
nBlockSize = ( 31 + sizeof( T ) ) / sizeof( T );
Assert( nBlockSize );
}
}
if ( nBlockSize < num )
{
int n = ( num + nBlockSize -1 ) / nBlockSize;
Assert( n * nBlockSize >= num );
Assert( ( n - 1 ) * nBlockSize < num );
nBlockSize *= n;
}
m_nAllocationCount += nBlockSize;
MEM_ALLOC_CREDIT_CLASS();
BlockHeader_t * RESTRICT pBlockHeader = ( BlockHeader_t* )malloc( sizeof( BlockHeader_t ) + nBlockSize * sizeof( T ) );
if ( !pBlockHeader )
{
Error( "CUtlFixedMemory overflow!\n" );
}
pBlockHeader->m_pNext = NULL;
pBlockHeader->m_nBlockSize = nBlockSize;
if ( !m_pBlocks )
{
m_pBlocks = pBlockHeader;
}
else
{
#if 1 // IsIdxAfter assumes that newly allocated blocks are at the end
BlockHeader_t * RESTRICT pbh = m_pBlocks;
while ( pbh->m_pNext )
{
pbh = pbh->m_pNext;
}
pbh->m_pNext = pBlockHeader;
#else
pBlockHeader = m_pBlocks;
pBlockHeader->m_pNext = m_pBlocks;
#endif
}
}
//-----------------------------------------------------------------------------
// Makes sure we've got at least this much memory
//-----------------------------------------------------------------------------
template< class T >
inline void CUtlFixedMemory<T>::EnsureCapacity( int num )
{
Grow( num - NumAllocated() );
}
//-----------------------------------------------------------------------------
// Memory deallocation
//-----------------------------------------------------------------------------
template< class T >
void CUtlFixedMemory<T>::Purge()
{
if ( !m_pBlocks )
return;
for ( BlockHeader_t *pbh = m_pBlocks; pbh; )
{
BlockHeader_t *pFree = pbh;
pbh = pbh->m_pNext;
free( pFree );
}
m_pBlocks = NULL;
m_nAllocationCount = 0;
}
#include "tier0/memdbgoff.h"
#endif // UTLFIXEDMEMORY_H

658
external/vpc/public/tier1/utlgraph.h vendored Normal file
View File

@@ -0,0 +1,658 @@
//========= Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $Header: $
// $NoKeywords: $
//=============================================================================//
#ifndef UTLGRAPH_H
#define UTLGRAPH_H
#include "tier1/utlmap.h"
#include "tier1/utlvector.h"
#include <limits.h>
//-------------------------------------
//-----------------------------------------------------------------------------
// A Graph class
//
// Nodes must have a unique Node ID.
//
// Edges are unidirectional, specified from the beginning node.
//
//-----------------------------------------------------------------------------
template <class T, class C >
class CUtlGraphVisitor;
template <class T, class C = int >
class CUtlGraph
{
public:
typedef int I;
typedef I IndexType_t;
typedef T NodeID_t;
typedef C CostType_t;
typedef CUtlGraphVisitor<T,C> Visitor_t;
struct Edge_t
{
IndexType_t m_DestinationNode;
CostType_t m_EdgeCost;
Edge_t( IndexType_t i = 0 )
{
m_DestinationNode = i;
m_EdgeCost = 0;
}
bool operator==(const Edge_t &that ) const
{
return m_DestinationNode == that.m_DestinationNode;
}
static int SortFn( const Edge_t *plhs, const Edge_t *prhs )
{
if ( plhs->m_EdgeCost < prhs->m_EdgeCost )
return -1;
else if ( plhs->m_EdgeCost > prhs->m_EdgeCost )
return 1;
else return 0;
}
};
typedef CUtlVector<Edge_t> vecEdges_t;
// constructor, destructor
CUtlGraph( );
~CUtlGraph();
// Add an edge
bool AddEdge( T SourceNode, T DestNode, C nCost );
// Remove an edge
bool RemoveEdge( T SourceNode, T DestNode );
// gets particular elements
T& Element( I i );
T const &Element( I i ) const;
T& operator[]( I i );
T const &operator[]( I i ) const;
// Find a node
I Find( T Node ) { return m_Nodes.Find( Node ); }
I Find( T Node ) const { return m_Nodes.Find( Node ); }
// Num elements
unsigned int Count() const { return m_Nodes.Count() ; }
// Max "size" of the vector
I MaxElement() const { return m_Nodes.MaxElement(); }
// Checks if a node is valid and in the graph
bool IsValidIndex( I i ) const { return m_Nodes.IsValidIndex( i ); }
// Checks if the graph as a whole is valid
bool IsValid() const { return m_Nodes.IsValid(); }
// Invalid index
static I InvalidIndex() { return CUtlMap< NodeID_t, vecEdges_t*>::InvalidIndex(); }
// Remove methods
void RemoveAt( I i );
void RemoveAll();
// Makes sure we have enough memory allocated to store a requested # of elements
void EnsureCapacity( int num );
// Create Path Matrix once you've added all nodes and edges
void CreatePathMatrix();
// For Visitor classes
vecEdges_t *GetEdges( I i );
// shortest path costs
vecEdges_t *GetPathCosts( I i );
#ifdef DBGFLAG_VALIDATE
void Validate( CValidator &validator, const char *pchName );
#endif // DBGFLAG_VALIDATE
protected:
struct Node_t
{
vecEdges_t *m_pvecEdges;
vecEdges_t *m_pvecPaths;
Node_t()
{
m_pvecEdges = NULL;
m_pvecPaths = NULL;
}
};
CUtlMap< NodeID_t, Node_t > m_Nodes;
};
//-----------------------------------------------------------------------------
// A Graph "visitor" class
//
// From the specified beginning point, visits each node in an expanding radius
//
//-----------------------------------------------------------------------------
template <class T, class C = int >
class CUtlGraphVisitor
{
public:
CUtlGraphVisitor( CUtlGraph<T, C> &graph );
bool Begin( T StartNode );
bool Advance();
T CurrentNode();
C AccumulatedCost();
int CurrentRadius();
private:
typedef typename CUtlGraph<T,C>::IndexType_t IndexType_t;
typedef typename CUtlGraph<T,C>::Edge_t Edge_t;
typedef CUtlVector<Edge_t> vecEdges_t;
CUtlGraph<T, C> &m_Graph;
vecEdges_t m_vecVisitQueue;
int m_iVisiting;
int m_nCurrentRadius;
vecEdges_t m_vecFringeQueue;
CUtlVector<T> m_vecNodesVisited;
};
//-----------------------------------------------------------------------------
// constructor, destructor
//-----------------------------------------------------------------------------
template <class T, class C >
inline CUtlGraph<T, C>::CUtlGraph()
{
SetDefLessFunc( m_Nodes );
}
template <class T, class C >
inline CUtlGraph<T, C>::~CUtlGraph()
{
RemoveAll();
}
//-----------------------------------------------------------------------------
// gets particular elements
//-----------------------------------------------------------------------------
template <class T, class C >
inline T &CUtlGraph<T, C>::Element( I i )
{
return m_Nodes.Key( i );
}
template <class T, class C >
inline T const &CUtlGraph<T, C>::Element( I i ) const
{
return m_Nodes.Key( i );
}
template <class T, class C >
inline T &CUtlGraph<T, C>::operator[]( I i )
{
return Element(i);
}
template <class T, class C >
inline T const &CUtlGraph<T, C>::operator[]( I i ) const
{
return Element(i);
}
//-----------------------------------------------------------------------------
//
// various accessors
//
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// Removes all nodes from the tree
//-----------------------------------------------------------------------------
template <class T, class C >
void CUtlGraph<T, C>::RemoveAll()
{
FOR_EACH_MAP_FAST( m_Nodes, iNode )
{
delete m_Nodes[iNode].m_pvecEdges;
delete m_Nodes[iNode].m_pvecPaths;
}
m_Nodes.RemoveAll();
}
//-----------------------------------------------------------------------------
// Makes sure we have enough memory allocated to store a requested # of elements
//-----------------------------------------------------------------------------
template <class T, class C >
void CUtlGraph<T, C>::EnsureCapacity( int num )
{
m_Nodes.EnsureCapacity(num);
}
//-----------------------------------------------------------------------------
// Add an edge
//-----------------------------------------------------------------------------
template <class T, class C >
bool CUtlGraph<T, C>::AddEdge( T SourceNode, T DestNode, C nCost )
{
I iSrcNode = m_Nodes.Find( SourceNode );
if ( !m_Nodes.IsValidIndex( iSrcNode ) )
{
Node_t Node;
Node.m_pvecEdges = new vecEdges_t();
Node.m_pvecPaths = new vecEdges_t();
iSrcNode = m_Nodes.Insert( SourceNode, Node );
}
I iDstNode = m_Nodes.Find( DestNode );
if ( !m_Nodes.IsValidIndex( iDstNode ) )
{
Node_t Node;
Node.m_pvecEdges = new vecEdges_t();
Node.m_pvecPaths = new vecEdges_t();
iDstNode = m_Nodes.Insert( DestNode, Node );
}
vecEdges_t &vecEdges = *m_Nodes[iSrcNode].m_pvecEdges;
#ifdef _DEBUG
FOR_EACH_VEC( vecEdges, iEdge )
{
if ( vecEdges[iEdge].m_DestinationNode == iDstNode )
return false;
}
#endif
Edge_t newEdge;
newEdge.m_DestinationNode = iDstNode;
newEdge.m_EdgeCost = nCost;
vecEdges[ vecEdges.AddToTail() ] = newEdge;
return true;
}
//-----------------------------------------------------------------------------
// Remove an edge
//-----------------------------------------------------------------------------
template <class T, class C >
bool CUtlGraph<T, C>::RemoveEdge( T SourceNode, T DestNode )
{
I iSrcNode = m_Nodes.Find( SourceNode );
if ( !m_Nodes.IsValidIndex( iSrcNode ) )
return false;
I iDstNode = m_Nodes.Find( DestNode );
if ( !m_Nodes.IsValidIndex( iDstNode ) )
return false;
vecEdges_t &vecEdges = *m_Nodes[iSrcNode].m_pvecEdges;
FOR_EACH_VEC( vecEdges, iEdge )
{
if ( vecEdges[iEdge].m_DestinationNode == iDstNode )
{
// could use FastRemove, but nodes won't have that
// many edges, and the elements are small, and
// preserving the original ordering is nice
vecEdges.Remove( iEdge );
return true;
}
}
return false;
}
//-----------------------------------------------------------------------------
// Get all of a Node's edges
//-----------------------------------------------------------------------------
template <class T, class C >
typename CUtlGraph<T, C>::vecEdges_t *CUtlGraph<T, C>::GetEdges( I i )
{
return m_Nodes[i].m_pvecEdges;
}
//-----------------------------------------------------------------------------
// Get all of a Node's edges
//-----------------------------------------------------------------------------
template <class T, class C >
typename CUtlGraph<T, C>::vecEdges_t *CUtlGraph<T, C>::GetPathCosts( I i )
{
return m_Nodes[i].m_pvecPaths;
}
//-----------------------------------------------------------------------------
// Data and memory validation
//-----------------------------------------------------------------------------
#ifdef DBGFLAG_VALIDATE
template <class T, class C >
void CUtlGraph<T, C>::Validate( CValidator &validator, const char *pchName )
{
#ifdef _WIN32
validator.Push( typeid(*this).raw_name(), this, pchName );
#else
validator.Push( typeid(*this).name(), this, pchName );
#endif
ValidateObj( m_Nodes );
FOR_EACH_MAP_FAST( m_Nodes, iNode )
{
validator.ClaimMemory( m_Nodes[iNode].m_pvecEdges );
ValidateObj( *m_Nodes[iNode].m_pvecEdges );
validator.ClaimMemory( m_Nodes[iNode].m_pvecPaths );
ValidateObj( *m_Nodes[iNode].m_pvecPaths );
}
validator.Pop();
}
#endif // DBGFLAG_VALIDATE
//-----------------------------------------------------------------------------
// Get all of a Node's edges
//-----------------------------------------------------------------------------
template <class T, class C >
void CUtlGraph<T, C>::CreatePathMatrix()
{
int n = MaxElement();
// Notes
// Because CUtlMap stores its nodes in essentially a vector,
// we know that we can use its indices in our own path matrix
// vectors safely (they will be numbers in the range (0,N) where
// N is largest number of nodes ever present in the graph).
//
// This lets us very quickly access previous best-path estimates
// by indexing into a node's vecPaths directly.
//
// When we are all done, we can then compact the vector, removing
// "null" paths, and then sorting by cost.
// Initialize matrix with all edges
FOR_EACH_MAP_FAST( m_Nodes, iNode )
{
vecEdges_t &vecEdges = *m_Nodes.Element( iNode ).m_pvecEdges;
vecEdges_t &vecPaths = *m_Nodes.Element( iNode ).m_pvecPaths;
vecPaths.RemoveAll();
vecPaths.AddMultipleToTail( n );
FOR_EACH_VEC( vecPaths, iPath )
{
vecPaths[iPath].m_DestinationNode = InvalidIndex();
}
// Path to self
vecPaths[iNode].m_DestinationNode = iNode;
// zero cost to self
vecPaths[iNode].m_EdgeCost = 0;
FOR_EACH_VEC( vecEdges, iEdge )
{
// Path to a neighbor node - we know exactly what the cost is
Edge_t &edge = vecEdges[iEdge];
vecPaths[ edge.m_DestinationNode ].m_DestinationNode = edge.m_DestinationNode;
vecPaths[ edge.m_DestinationNode ].m_EdgeCost = edge.m_EdgeCost;
}
}
// Floyd-Warshall
// for k:= 0 to n-1
// for each (i,j) in (0..n-1)
// path[i][j] = min( path[i][j], path[i][k]+path[k][j] );
for ( int k = 0; k < n; ++ k )
{
if ( !m_Nodes.IsValidIndex( k ) )
continue;
// All current known paths from K
vecEdges_t &destMapFromK = *m_Nodes[k].m_pvecPaths;
for ( int i = 0; i < n; ++i )
{
if ( !m_Nodes.IsValidIndex( i ) )
continue;
// All current known paths from J
vecEdges_t &destMapFromI = *m_Nodes[i].m_pvecPaths;
// Path from I to K?
int iFromIToK = k;
bool bFromIToK = destMapFromI[iFromIToK].m_DestinationNode != InvalidIndex();
CostType_t cIToK = ( bFromIToK ) ? destMapFromI[iFromIToK].m_EdgeCost : INT_MAX;
for ( int j = 0; j < n; ++ j )
{
if ( !m_Nodes.IsValidIndex( j ) )
continue;
// Path from I to J already?
int iFromIToJ = j;
bool bFromIToJ = destMapFromI[iFromIToJ].m_DestinationNode != InvalidIndex();
CostType_t cIToJ = ( bFromIToJ ) ? destMapFromI[iFromIToJ].m_EdgeCost : INT_MAX;
// Path from K to J?
int iFromKToJ = j;
bool bFromKToJ = destMapFromK[iFromKToJ].m_DestinationNode != InvalidIndex();
CostType_t cKToJ = ( bFromKToJ ) ? destMapFromK[iFromKToJ].m_EdgeCost : INT_MAX;
// Is the new path valid?
bool bNewPathFound = ( bFromIToK && bFromKToJ );
if ( bNewPathFound )
{
if ( bFromIToJ )
{
// Pick min of previous best and current path
destMapFromI[iFromIToJ].m_EdgeCost = min( cIToJ, cIToK + cKToJ );
}
else
{
// Current path is the first, hence the best so far
destMapFromI[iFromIToJ].m_DestinationNode = iFromIToJ;
destMapFromI[iFromIToJ].m_EdgeCost = cIToK + cKToJ;
}
}
}
}
}
// Clean up and sort the paths
FOR_EACH_MAP_FAST( m_Nodes, iNode )
{
vecEdges_t &vecPaths = *m_Nodes.Element( iNode ).m_pvecPaths;
FOR_EACH_VEC( vecPaths, iPath )
{
Edge_t &edge = vecPaths[iPath];
if ( edge.m_DestinationNode == InvalidIndex() )
{
// No path to this destination was found.
// Remove this entry from the vector.
vecPaths.FastRemove( iPath );
--iPath; // adjust for the removal
}
}
// Sort the vector by cost, given that it
// is likely consumers will want to
// iterate destinations in that order.
vecPaths.Sort( Edge_t::SortFn );
}
}
//-----------------------------------------------------------------------------
// Constructor
//-----------------------------------------------------------------------------
template <class T, class C >
CUtlGraphVisitor<T, C>::CUtlGraphVisitor( CUtlGraph<T,C> &graph )
: m_Graph( graph )
{
m_iVisiting = 0;
m_nCurrentRadius = 0;
}
//-----------------------------------------------------------------------------
// Begin visiting the nodes in the graph. Returns false if the start node
// does not exist
//-----------------------------------------------------------------------------
template <class T, class C >
bool CUtlGraphVisitor<T, C>::Begin( T StartNode )
{
m_vecVisitQueue.RemoveAll();
m_vecFringeQueue.RemoveAll();
m_vecNodesVisited.RemoveAll();
m_iVisiting = 0;
m_nCurrentRadius = 0;
IndexType_t iStartNode = m_Graph.Find( StartNode );
if ( !m_Graph.IsValidIndex( iStartNode ) )
return false;
vecEdges_t *pvecEdges = m_Graph.GetEdges( iStartNode );
Edge_t edge;
edge.m_DestinationNode = iStartNode;
edge.m_EdgeCost = 0;
m_vecVisitQueue[ m_vecVisitQueue.AddToTail() ] = edge;
m_vecNodesVisited[ m_vecNodesVisited.AddToTail() ] = iStartNode;
m_vecFringeQueue = *pvecEdges;
// cells actually get marked as "visited" as soon as we put
// them in the fringe queue, so we don't put them in the *next*
// fringe queue (we build the fringe queue before we actually visit
// the nodes in the new visit queue).
FOR_EACH_VEC( m_vecFringeQueue, iFringe )
{
m_vecNodesVisited[ m_vecNodesVisited.AddToTail() ] = m_vecFringeQueue[iFringe].m_DestinationNode;
}
return true;
}
//-----------------------------------------------------------------------------
// Advance to the next node. Returns false when all nodes have been visited
//-----------------------------------------------------------------------------
template <class T, class C>
bool CUtlGraphVisitor<T, C>::Advance()
{
m_iVisiting++;
// Is the VisitQueue empty? move outward one radius if so
if ( m_iVisiting >= m_vecVisitQueue.Count() )
{
m_nCurrentRadius++;
m_iVisiting = 0;
m_vecVisitQueue = m_vecFringeQueue;
m_vecFringeQueue.RemoveAll();
if ( !m_vecVisitQueue.Count() )
return false;
// create new fringe queue
FOR_EACH_VEC( m_vecVisitQueue, iNode )
{
Edge_t &node = m_vecVisitQueue[iNode];
vecEdges_t &vecEdges = *m_Graph.GetEdges( node.m_DestinationNode );
FOR_EACH_VEC( vecEdges, iEdge )
{
Edge_t &edge = vecEdges[iEdge];
if ( m_vecNodesVisited.InvalidIndex() == m_vecNodesVisited.Find( edge.m_DestinationNode ) )
{
m_vecNodesVisited[ m_vecNodesVisited.AddToTail() ] = edge.m_DestinationNode;
int iNewFringeNode = m_vecFringeQueue.AddToTail();
m_vecFringeQueue[ iNewFringeNode ] = edge;
// Accumulate the cost to get to the current point
m_vecFringeQueue[ iNewFringeNode ].m_EdgeCost += node.m_EdgeCost;
}
}
}
}
return true;
}
//-----------------------------------------------------------------------------
// Get the current node in the visit sequence
//-----------------------------------------------------------------------------
template <class T, class C>
T CUtlGraphVisitor<T, C>::CurrentNode()
{
if ( m_iVisiting >= m_vecVisitQueue.Count() )
{
AssertMsg( false, "Visitor invalid" );
return T();
}
return m_Graph[ m_vecVisitQueue[ m_iVisiting ].m_DestinationNode ];
}
//-----------------------------------------------------------------------------
// Get the accumulated cost to traverse the graph to the current node
//-----------------------------------------------------------------------------
template <class T, class C>
C CUtlGraphVisitor<T, C>::AccumulatedCost()
{
if ( m_iVisiting >= m_vecVisitQueue.Count() )
{
AssertMsg( false, "Visitor invalid" );
return C();
}
return m_vecVisitQueue[ m_iVisiting ].m_EdgeCost;
}
//-----------------------------------------------------------------------------
// Get the current radius from the start point to this node
//-----------------------------------------------------------------------------
template <class T, class C>
int CUtlGraphVisitor<T, C>::CurrentRadius()
{
if ( m_iVisiting >= m_vecVisitQueue.Count() )
{
AssertMsg( false, "Visitor invalid" );
return 0;
}
return m_nCurrentRadius;
}
#endif // UTLGRAPH_H

1299
external/vpc/public/tier1/utlhash.h vendored Normal file

File diff suppressed because it is too large Load Diff

1087
external/vpc/public/tier1/utllinkedlist.h vendored Normal file

File diff suppressed because it is too large Load Diff

248
external/vpc/public/tier1/utlmap.h vendored Normal file
View File

@@ -0,0 +1,248 @@
//========= Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $Header: $
// $NoKeywords: $
//=============================================================================//
#ifndef UTLMAP_H
#define UTLMAP_H
#ifdef _WIN32
#pragma once
#endif
#include "tier0/dbg.h"
#include "utlrbtree.h"
//-----------------------------------------------------------------------------
//
// Purpose: An associative container. Pretty much identical to std::map.
//
//-----------------------------------------------------------------------------
// This is a useful macro to iterate from start to end in order in a map
#define FOR_EACH_MAP( mapName, iteratorName ) \
for ( int iteratorName = (mapName).FirstInorder(); (mapName).IsUtlMap && iteratorName != (mapName).InvalidIndex(); iteratorName = (mapName).NextInorder( iteratorName ) )
// faster iteration, but in an unspecified order
#define FOR_EACH_MAP_FAST( mapName, iteratorName ) \
for ( int iteratorName = 0; (mapName).IsUtlMap && iteratorName < (mapName).MaxElement(); ++iteratorName ) if ( !(mapName).IsValidIndex( iteratorName ) ) continue; else
struct base_utlmap_t
{
public:
static const bool IsUtlMap = true; // Used to match this at compiletime
};
#if defined( GNUC ) && defined( DEBUG )
const bool base_utlmap_t::IsUtlMap SELECTANY;
#endif
template <typename K, typename T, typename I = unsigned short>
class CUtlMap : public base_utlmap_t
{
public:
typedef K KeyType_t;
typedef T ElemType_t;
typedef I IndexType_t;
// Less func typedef
// Returns true if the first parameter is "less" than the second
typedef bool (*LessFunc_t)( const KeyType_t &, const KeyType_t & );
// constructor, destructor
// Left at growSize = 0, the memory will first allocate 1 element and double in size
// at each increment.
// LessFunc_t is required, but may be set after the constructor using SetLessFunc() below
CUtlMap( int growSize = 0, int initSize = 0, LessFunc_t lessfunc = 0 )
: m_Tree( growSize, initSize, CKeyLess( lessfunc ) )
{
}
CUtlMap( LessFunc_t lessfunc )
: m_Tree( CKeyLess( lessfunc ) )
{
}
void EnsureCapacity( int num ) { m_Tree.EnsureCapacity( num ); }
// gets particular elements
ElemType_t & Element( IndexType_t i ) { return m_Tree.Element( i ).elem; }
const ElemType_t & Element( IndexType_t i ) const { return m_Tree.Element( i ).elem; }
ElemType_t & operator[]( IndexType_t i ) { return m_Tree.Element( i ).elem; }
const ElemType_t & operator[]( IndexType_t i ) const { return m_Tree.Element( i ).elem; }
KeyType_t & Key( IndexType_t i ) { return m_Tree.Element( i ).key; }
const KeyType_t & Key( IndexType_t i ) const { return m_Tree.Element( i ).key; }
// Num elements
unsigned int Count() const { return m_Tree.Count(); }
// Max "size" of the vector
IndexType_t MaxElement() const { return m_Tree.MaxElement(); }
// Checks if a node is valid and in the map
bool IsValidIndex( IndexType_t i ) const { return m_Tree.IsValidIndex( i ); }
// Checks if the map as a whole is valid
bool IsValid() const { return m_Tree.IsValid(); }
// Invalid index
static IndexType_t InvalidIndex() { return CTree::InvalidIndex(); }
// Sets the less func
void SetLessFunc( LessFunc_t func )
{
m_Tree.SetLessFunc( CKeyLess( func ) );
}
// Insert method (inserts in order)
IndexType_t Insert( const KeyType_t &key, const ElemType_t &insert )
{
Node_t node;
node.key = key;
node.elem = insert;
return m_Tree.Insert( node );
}
IndexType_t Insert( const KeyType_t &key )
{
Node_t node;
node.key = key;
return m_Tree.Insert( node );
}
// Find method
IndexType_t Find( const KeyType_t &key ) const
{
Node_t dummyNode;
dummyNode.key = key;
return m_Tree.Find( dummyNode );
}
// Remove methods
void RemoveAt( IndexType_t i ) { m_Tree.RemoveAt( i ); }
bool Remove( const KeyType_t &key )
{
Node_t dummyNode;
dummyNode.key = key;
return m_Tree.Remove( dummyNode );
}
void RemoveAll( ) { m_Tree.RemoveAll(); }
void Purge( ) { m_Tree.Purge(); }
// Purges the list and calls delete on each element in it.
void PurgeAndDeleteElements();
// Iteration
IndexType_t FirstInorder() const { return m_Tree.FirstInorder(); }
IndexType_t NextInorder( IndexType_t i ) const { return m_Tree.NextInorder( i ); }
IndexType_t PrevInorder( IndexType_t i ) const { return m_Tree.PrevInorder( i ); }
IndexType_t LastInorder() const { return m_Tree.LastInorder(); }
// If you change the search key, this can be used to reinsert the
// element into the map.
void Reinsert( const KeyType_t &key, IndexType_t i )
{
m_Tree[i].key = key;
m_Tree.Reinsert(i);
}
IndexType_t InsertOrReplace( const KeyType_t &key, const ElemType_t &insert )
{
IndexType_t i = Find( key );
if ( i != InvalidIndex() )
{
Element( i ) = insert;
return i;
}
return Insert( key, insert );
}
void Swap( CUtlMap< K, T, I > &that )
{
m_Tree.Swap( that.m_Tree );
}
struct Node_t
{
Node_t()
{
}
Node_t( const Node_t &from )
: key( from.key ),
elem( from.elem )
{
}
KeyType_t key;
ElemType_t elem;
};
class CKeyLess
{
public:
CKeyLess( LessFunc_t lessFunc ) : m_LessFunc(lessFunc) {}
bool operator!() const
{
return !m_LessFunc;
}
bool operator()( const Node_t &left, const Node_t &right ) const
{
return m_LessFunc( left.key, right.key );
}
LessFunc_t m_LessFunc;
};
typedef CUtlRBTree<Node_t, I, CKeyLess> CTree;
CTree *AccessTree() { return &m_Tree; }
protected:
CTree m_Tree;
};
//-----------------------------------------------------------------------------
// Purges the list and calls delete on each element in it.
template< typename K, typename T, typename I >
inline void CUtlMap<K, T, I>::PurgeAndDeleteElements()
{
for ( I i = 0; i < MaxElement(); ++i )
{
if ( !IsValidIndex( i ) )
continue;
delete Element( i );
}
Purge();
}
//-----------------------------------------------------------------------------
// This is horrible and slow and meant to be used only when you're dealing with really
// non-time/memory-critical code and desperately want to copy a whole map element-by-element
// for whatever reason.
template < typename K, typename T, typename I >
void DeepCopyMap( const CUtlMap<K,T,I>& pmapIn, CUtlMap<K,T,I> *out_pmapOut )
{
Assert( out_pmapOut );
out_pmapOut->Purge();
FOR_EACH_MAP_FAST( pmapIn, i )
{
out_pmapOut->Insert( i, pmapIn[i] );
}
}
#endif // UTLMAP_H

Some files were not shown because too many files have changed in this diff Show More