mirror of
https://github.com/celisej567/cool-source-archive.git
synced 2025-12-31 17:48:37 +03:00
added VS2019 support
debug build requires a little bit of work
This commit is contained in:
@@ -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
|
||||
|
||||
2261
engine/engine.vpc
2261
engine/engine.vpc
File diff suppressed because it is too large
Load Diff
23
external/crypto++-5.6.3/adhoc.cpp
vendored
Normal file
23
external/crypto++-5.6.3/adhoc.cpp
vendored
Normal 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);
|
||||
2
external/crypto++-5.6.3/adhoc.cpp.copied
vendored
Normal file
2
external/crypto++-5.6.3/adhoc.cpp.copied
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
|
||||
|
||||
17
external/crypto++-5.61/adhoc.cpp
vendored
Normal file
17
external/crypto++-5.61/adhoc.cpp
vendored
Normal 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);
|
||||
2
external/crypto++-5.61/adhoc.cpp.copied
vendored
Normal file
2
external/crypto++-5.61/adhoc.cpp.copied
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
|
||||
|
||||
28
external/vpc/devtools/base.xcconfig
vendored
Normal file
28
external/vpc/devtools/base.xcconfig
vendored
Normal 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
0
external/vpc/devtools/bin/.empty
vendored
Normal file
46
external/vpc/devtools/bin/vpc
vendored
Normal file
46
external/vpc/devtools/bin/vpc
vendored
Normal 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
2
external/vpc/devtools/debug.xcconfig
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
#include "base.xcconfig"
|
||||
GCC_OPTIMIZATION_LEVEL = 0
|
||||
1
external/vpc/devtools/release.xcconfig
vendored
Normal file
1
external/vpc/devtools/release.xcconfig
vendored
Normal file
@@ -0,0 +1 @@
|
||||
#include "base.xcconfig"
|
||||
294
external/vpc/interfaces/interfaces.cpp
vendored
Normal file
294
external/vpc/interfaces/interfaces.cpp
vendored
Normal 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 ® = 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 ® = 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 ® = 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
BIN
external/vpc/lib/common/libclient.lib
vendored
Normal file
Binary file not shown.
BIN
external/vpc/lib/common/libp4sslstub.lib
vendored
Normal file
BIN
external/vpc/lib/common/libp4sslstub.lib
vendored
Normal file
Binary file not shown.
BIN
external/vpc/lib/common/librpc.lib
vendored
Normal file
BIN
external/vpc/lib/common/librpc.lib
vendored
Normal file
Binary file not shown.
BIN
external/vpc/lib/common/libsupp.lib
vendored
Normal file
BIN
external/vpc/lib/common/libsupp.lib
vendored
Normal file
Binary file not shown.
2556
external/vpc/p4lib/p4.cpp
vendored
Normal file
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
43
external/vpc/p4lib/p4lib.vpc
vendored
Normal 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"
|
||||
}
|
||||
}
|
||||
121
external/vpc/public/appframework/iappsystem.h
vendored
Normal file
121
external/vpc/public/appframework/iappsystem.h
vendored
Normal 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
124
external/vpc/public/color.h
vendored
Normal 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
521
external/vpc/public/datamap.h
vendored
Normal 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
958
external/vpc/public/filesystem.h
vendored
Normal 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
|
||||
299
external/vpc/public/filesystem_passthru.h
vendored
Normal file
299
external/vpc/public/filesystem_passthru.h
vendored
Normal 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
213
external/vpc/public/icvar.h
vendored
Normal 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
28
external/vpc/public/ilaunchabledll.h
vendored
Normal 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
|
||||
287
external/vpc/public/interfaces/interfaces.h
vendored
Normal file
287
external/vpc/public/interfaces/interfaces.h
vendored
Normal 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
97
external/vpc/public/mathlib/fltx4.h
vendored
Normal 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
283
external/vpc/public/mathlib/math_pfns.h
vendored
Normal 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
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
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
670
external/vpc/public/mathlib/vector2d.h
vendored
Normal 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
191
external/vpc/public/p4lib/ip4.h
vendored
Normal 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
116
external/vpc/public/tier0/annotations.h
vendored
Normal 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
650
external/vpc/public/tier0/basetypes.h
vendored
Normal 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
149
external/vpc/public/tier0/commonmacros.h
vendored
Normal 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
716
external/vpc/public/tier0/dbg.h
vendored
Normal 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
68
external/vpc/public/tier0/dbgflag.h
vendored
Normal 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
155
external/vpc/public/tier0/etwprof.h
vendored
Normal 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
480
external/vpc/public/tier0/eventmasks.h
vendored
Normal 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
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
625
external/vpc/public/tier0/fasttimer.h
vendored
Normal 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
383
external/vpc/public/tier0/ia32detect.h
vendored
Normal 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
|
||||
65
external/vpc/public/tier0/icommandline.h
vendored
Normal file
65
external/vpc/public/tier0/icommandline.h
vendored
Normal 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
29
external/vpc/public/tier0/ioctlcodes.h
vendored
Normal 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
|
||||
2040
external/vpc/public/tier0/k8performancecounters.h
vendored
Normal file
2040
external/vpc/public/tier0/k8performancecounters.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
47
external/vpc/public/tier0/l2cache.h
vendored
Normal file
47
external/vpc/public/tier0/l2cache.h
vendored
Normal 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
767
external/vpc/public/tier0/logging.h
vendored
Normal 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
50
external/vpc/public/tier0/mem.h
vendored
Normal 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
701
external/vpc/public/tier0/memalloc.h
vendored
Normal 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
25
external/vpc/public/tier0/memdbgoff.h
vendored
Normal 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
281
external/vpc/public/tier0/memdbgon.h
vendored
Normal 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
46
external/vpc/public/tier0/memvirt.h
vendored
Normal 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
82
external/vpc/public/tier0/minidump.h
vendored
Normal 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
|
||||
322
external/vpc/public/tier0/p4performancecounters.h
vendored
Normal file
322
external/vpc/public/tier0/p4performancecounters.h
vendored
Normal 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
|
||||
225
external/vpc/public/tier0/p5p6performancecounters.h
vendored
Normal file
225
external/vpc/public/tier0/p5p6performancecounters.h
vendored
Normal 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
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
212
external/vpc/public/tier0/pmelib.h
vendored
Normal 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
966
external/vpc/public/tier0/stackstats.h
vendored
Normal 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> ©From )
|
||||
: 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> ©From )
|
||||
: 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
153
external/vpc/public/tier0/stacktools.h
vendored
Normal 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 ©From )
|
||||
{
|
||||
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
2402
external/vpc/public/tier0/threadtools.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
630
external/vpc/public/tier0/threadtools.inl
vendored
Normal file
630
external/vpc/public/tier0/threadtools.inl
vendored
Normal 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
858
external/vpc/public/tier0/tslist.h
vendored
Normal 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
73
external/vpc/public/tier0/validator.h
vendored
Normal 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
72
external/vpc/public/tier0/valobject.h
vendored
Normal 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
33
external/vpc/public/tier0/valve_off.h
vendored
Normal 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
37
external/vpc/public/tier0/valve_on.h
vendored
Normal 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
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
31
external/vpc/public/tier0/vprof_sn.h
vendored
Normal 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
101
external/vpc/public/tier0/wchartypes.h
vendored
Normal 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
|
||||
|
||||
|
||||
32
external/vpc/public/tier0/win32consoleio.h
vendored
Normal file
32
external/vpc/public/tier0/win32consoleio.h
vendored
Normal 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
|
||||
16
external/vpc/public/tier0/xbox_codeline_defines.h
vendored
Normal file
16
external/vpc/public/tier0/xbox_codeline_defines.h
vendored
Normal 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
268
external/vpc/public/tier1/byteswap.h
vendored
Normal 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 */
|
||||
43
external/vpc/public/tier1/characterset.h
vendored
Normal file
43
external/vpc/public/tier1/characterset.h
vendored
Normal 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
|
||||
31
external/vpc/public/tier1/checksum_crc.h
vendored
Normal file
31
external/vpc/public/tier1/checksum_crc.h
vendored
Normal 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
|
||||
33
external/vpc/public/tier1/checksum_md5.h
vendored
Normal file
33
external/vpc/public/tier1/checksum_md5.h
vendored
Normal 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
975
external/vpc/public/tier1/convar.h
vendored
Normal 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
|
||||
53
external/vpc/public/tier1/convar_serverbounded.h
vendored
Normal file
53
external/vpc/public/tier1/convar_serverbounded.h
vendored
Normal 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
|
||||
74
external/vpc/public/tier1/exprevaluator.h
vendored
Normal file
74
external/vpc/public/tier1/exprevaluator.h
vendored
Normal 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
366
external/vpc/public/tier1/fmtstr.h
vendored
Normal 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
922
external/vpc/public/tier1/functors.h
vendored
Normal 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
116
external/vpc/public/tier1/generichash.h
vendored
Normal 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
121
external/vpc/public/tier1/iconvar.h
vendored
Normal 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
226
external/vpc/public/tier1/interface.h
vendored
Normal 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
519
external/vpc/public/tier1/keyvalues.h
vendored
Normal 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
649
external/vpc/public/tier1/mempool.h
vendored
Normal 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
348
external/vpc/public/tier1/memstack.h
vendored
Normal 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
73
external/vpc/public/tier1/netadr.h
vendored
Normal 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
384
external/vpc/public/tier1/refcount.h
vendored
Normal 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
106
external/vpc/public/tier1/stringpool.h
vendored
Normal 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
589
external/vpc/public/tier1/strtools.h
vendored
Normal 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 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
85
external/vpc/public/tier1/tier1.h
vendored
Normal 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
|
||||
|
||||
349
external/vpc/public/tier1/utlblockmemory.h
vendored
Normal file
349
external/vpc/public/tier1/utlblockmemory.h
vendored
Normal 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
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
338
external/vpc/public/tier1/utldict.h
vendored
Normal 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
241
external/vpc/public/tier1/utlenvelope.h
vendored
Normal 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
|
||||
354
external/vpc/public/tier1/utlfixedmemory.h
vendored
Normal file
354
external/vpc/public/tier1/utlfixedmemory.h
vendored
Normal 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
658
external/vpc/public/tier1/utlgraph.h
vendored
Normal 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
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
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
248
external/vpc/public/tier1/utlmap.h
vendored
Normal 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
Reference in New Issue
Block a user