aboutsummaryrefslogtreecommitdiff
path: root/mp/src/public/tier0/dbg.h
diff options
context:
space:
mode:
authorJørgen P. Tjernø <[email protected]>2013-12-02 19:31:46 -0800
committerJørgen P. Tjernø <[email protected]>2013-12-02 19:46:31 -0800
commitf56bb35301836e56582a575a75864392a0177875 (patch)
treede61ddd39de3e7df52759711950b4c288592f0dc /mp/src/public/tier0/dbg.h
parentMark some more files as text. (diff)
downloadsource-sdk-2013-f56bb35301836e56582a575a75864392a0177875.tar.xz
source-sdk-2013-f56bb35301836e56582a575a75864392a0177875.zip
Fix line endings. WHAMMY.
Diffstat (limited to 'mp/src/public/tier0/dbg.h')
-rw-r--r--mp/src/public/tier0/dbg.h1590
1 files changed, 795 insertions, 795 deletions
diff --git a/mp/src/public/tier0/dbg.h b/mp/src/public/tier0/dbg.h
index 2faa26a5..ac7930a4 100644
--- a/mp/src/public/tier0/dbg.h
+++ b/mp/src/public/tier0/dbg.h
@@ -1,795 +1,795 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose:
-//
-// $NoKeywords: $
-//
-//=============================================================================//
-#ifndef DBG_H
-#define DBG_H
-
-#ifdef _WIN32
-#pragma once
-#endif
-
-#include "basetypes.h"
-#include "dbgflag.h"
-#include "platform.h"
-#include <math.h>
-#include <stdio.h>
-#include <stdarg.h>
-
-#ifdef POSIX
-#define __cdecl
-#endif
-
-//-----------------------------------------------------------------------------
-// dll export stuff
-//-----------------------------------------------------------------------------
-#ifndef STATIC_TIER0
-
-#ifdef TIER0_DLL_EXPORT
-#define DBG_INTERFACE DLL_EXPORT
-#define DBG_OVERLOAD DLL_GLOBAL_EXPORT
-#define DBG_CLASS DLL_CLASS_EXPORT
-#else
-#define DBG_INTERFACE DLL_IMPORT
-#define DBG_OVERLOAD DLL_GLOBAL_IMPORT
-#define DBG_CLASS DLL_CLASS_IMPORT
-#endif
-
-#else // BUILD_AS_DLL
-
-#define DBG_INTERFACE extern
-#define DBG_OVERLOAD
-#define DBG_CLASS
-#endif // BUILD_AS_DLL
-
-
-class Color;
-
-
-//-----------------------------------------------------------------------------
-// Usage model for the Dbg library
-//
-// 1. Spew.
-//
-// Spew can be used in a static and a dynamic mode. The static
-// mode allows us to display assertions and other messages either only
-// in debug builds, or in non-release builds. The dynamic mode allows us to
-// turn on and off certain spew messages while the application is running.
-//
-// Static Spew messages:
-//
-// Assertions are used to detect and warn about invalid states
-// Spews are used to display a particular status/warning message.
-//
-// 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).
-//
-// To use a warning, use
-//
-// Warning("Oh I feel so %s all over\n", "yummy");
-//
-// Warning will do its magic in only Debug builds. To perform spew in *all*
-// builds, use RelWarning.
-//
-// Three other spew types, Msg, Log, and Error, are compiled into all builds.
-// These error types do *not* need two sets of parenthesis.
-//
-// Msg( "Isn't this exciting %d?", 5 );
-// Error( "I'm just thrilled" );
-//
-// Dynamic Spew messages
-//
-// It is possible to dynamically turn spew on and off. Dynamic spew is
-// identified by a spew group and priority level. To turn spew on for a
-// particular spew group, use SpewActivate( "group", level ). This will
-// cause all spew in that particular group with priority levels <= the
-// level specified in the SpewActivate function to be printed. Use DSpew
-// to perform the spew:
-//
-// DWarning( "group", level, "Oh I feel even yummier!\n" );
-//
-// Priority level 0 means that the spew will *always* be printed, and group
-// '*' is the default spew group. If a DWarning is encountered using a group
-// whose priority has not been set, it will use the priority of the default
-// group. The priority of the default group is initially set to 0.
-//
-// Spew output
-//
-// The output of the spew system can be redirected to an externally-supplied
-// function which is responsible for outputting the spew. By default, the
-// spew is simply printed using printf.
-//
-// To redirect spew output, call SpewOutput.
-//
-// SpewOutputFunc( OutputFunc );
-//
-// This will cause OutputFunc to be called every time a spew message is
-// generated. OutputFunc will be passed a spew type and a message to print.
-// It must return a value indicating whether the debugger should be invoked,
-// whether the program should continue running, or whether the program
-// should abort.
-//
-// 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();
-//-----------------------------------------------------------------------------
-
-/* Various types of spew messages */
-// I'm sure you're asking yourself why SPEW_ instead of DBG_ ?
-// It's because DBG_ is used all over the place in windows.h
-// For example, DBG_CONTINUE is defined. Feh.
-enum SpewType_t
-{
- SPEW_MESSAGE = 0,
- SPEW_WARNING,
- SPEW_ASSERT,
- SPEW_ERROR,
- SPEW_LOG,
-
- SPEW_TYPE_COUNT
-};
-
-enum SpewRetval_t
-{
- SPEW_DEBUGGER = 0,
- SPEW_CONTINUE,
- SPEW_ABORT
-};
-
-/* type of externally defined function used to display debug spew */
-typedef SpewRetval_t (*SpewOutputFunc_t)( SpewType_t spewType, const tchar *pMsg );
-
-/* Used to redirect spew output */
-DBG_INTERFACE void SpewOutputFunc( SpewOutputFunc_t func );
-
-/* Used to get the current spew output function */
-DBG_INTERFACE SpewOutputFunc_t GetSpewOutputFunc( void );
-
-/* This is the default spew fun, which is used if you don't specify one */
-DBG_INTERFACE SpewRetval_t DefaultSpewFunc( SpewType_t type, const tchar *pMsg );
-
-/* Same as the default spew func, but returns SPEW_ABORT for asserts */
-DBG_INTERFACE SpewRetval_t DefaultSpewFuncAbortOnAsserts( SpewType_t type, const tchar *pMsg );
-
-/* Should be called only inside a SpewOutputFunc_t, returns groupname, level, color */
-DBG_INTERFACE const tchar* GetSpewOutputGroup( void );
-DBG_INTERFACE int GetSpewOutputLevel( void );
-DBG_INTERFACE const Color* GetSpewOutputColor( void );
-
-/* Used to manage spew groups and subgroups */
-DBG_INTERFACE void SpewActivate( const tchar* pGroupName, int level );
-DBG_INTERFACE bool IsSpewActive( const tchar* pGroupName, int level );
-
-/* Used to display messages, should never be called directly. */
-DBG_INTERFACE void _SpewInfo( SpewType_t type, const tchar* pFile, int line );
-DBG_INTERFACE SpewRetval_t _SpewMessage( PRINTF_FORMAT_STRING const tchar* pMsg, ... ) FMTFUNCTION( 1, 2 );
-DBG_INTERFACE SpewRetval_t _DSpewMessage( const tchar *pGroupName, int level, PRINTF_FORMAT_STRING const tchar* pMsg, ... ) FMTFUNCTION( 3, 4 );
-DBG_INTERFACE SpewRetval_t ColorSpewMessage( SpewType_t type, const Color *pColor, PRINTF_FORMAT_STRING const tchar* pMsg, ... ) FMTFUNCTION( 3, 4 );
-DBG_INTERFACE void _ExitOnFatalAssert( const tchar* pFile, int line );
-DBG_INTERFACE bool ShouldUseNewAssertDialog();
-
-DBG_INTERFACE bool SetupWin32ConsoleIO();
-
-// Returns true if they want to break in the debugger.
-DBG_INTERFACE bool DoNewAssertDialog( const tchar *pFile, int line, const tchar *pExpression );
-
-// Allows the assert dialogs to be turned off from code
-DBG_INTERFACE bool AreAllAssertsDisabled();
-DBG_INTERFACE void SetAllAssertsDisabled( bool bAssertsEnabled );
-
-// Provides a callback that is called on asserts regardless of spew levels
-typedef void (*AssertFailedNotifyFunc_t)( const char *pchFile, int nLine, const char *pchMessage );
-DBG_INTERFACE void SetAssertFailedNotifyFunc( AssertFailedNotifyFunc_t func );
-DBG_INTERFACE void CallAssertFailedNotifyFunc( const char *pchFile, int nLine, const char *pchMessage );
-
-#if defined( USE_SDL )
-DBG_INTERFACE void SetAssertDialogParent( struct SDL_Window *window );
-DBG_INTERFACE struct SDL_Window * GetAssertDialogParent();
-#endif
-
-/* Used to define macros, never use these directly. */
-
-#ifdef _PREFAST_
- // When doing /analyze builds define _AssertMsg 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.
- // The unfortunate !! is necessary because otherwise /analyze is incapable of evaluating
- // all of the logical expressions that the regular compiler can handle.
- // Include _msg in the macro so that format errors in it are detected.
- #define _AssertMsg( _exp, _msg, _executeExp, _bFatal ) do { __analysis_assume( !!(_exp) ); _msg; } while (0)
- #define _AssertMsgOnce( _exp, _msg, _bFatal ) do { __analysis_assume( !!(_exp) ); _msg; } while (0)
- // Force asserts on for /analyze so that we get a __analysis_assume of all of the constraints.
- #define DBGFLAG_ASSERT
- #define DBGFLAG_ASSERTFATAL
- #define DBGFLAG_ASSERTDEBUG
-#else
- #define _AssertMsg( _exp, _msg, _executeExp, _bFatal ) \
- do { \
- if (!(_exp)) \
- { \
- _SpewInfo( SPEW_ASSERT, __TFILE__, __LINE__ ); \
- SpewRetval_t ret = _SpewMessage("%s", _msg); \
- CallAssertFailedNotifyFunc( __TFILE__, __LINE__, _msg ); \
- _executeExp; \
- if ( ret == SPEW_DEBUGGER) \
- { \
- if ( !ShouldUseNewAssertDialog() || DoNewAssertDialog( __TFILE__, __LINE__, _msg ) ) \
- { \
- DebuggerBreak(); \
- } \
- if ( _bFatal ) \
- { \
- _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
-
-// 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 DbgVerify( _exp ) Assert( _exp )
-
-#define AssertMsg1( _exp, _msg, a1 ) AssertMsg( _exp, (const tchar *)(CDbgFmtMsg( _msg, a1 )) )
-#define AssertMsg2( _exp, _msg, a1, a2 ) AssertMsg( _exp, (const tchar *)(CDbgFmtMsg( _msg, a1, a2 )) )
-#define AssertMsg3( _exp, _msg, a1, a2, a3 ) AssertMsg( _exp, (const tchar *)(CDbgFmtMsg( _msg, a1, a2, a3 )) )
-#define AssertMsg4( _exp, _msg, a1, a2, a3, a4 ) AssertMsg( _exp, (const tchar *)(CDbgFmtMsg( _msg, a1, a2, a3, a4 )) )
-#define AssertMsg5( _exp, _msg, a1, a2, a3, a4, a5 ) AssertMsg( _exp, (const tchar *)(CDbgFmtMsg( _msg, a1, a2, a3, a4, a5 )) )
-#define AssertMsg6( _exp, _msg, a1, a2, a3, a4, a5, a6 ) AssertMsg( _exp, (const tchar *)(CDbgFmtMsg( _msg, a1, a2, a3, a4, a5, a6 )) )
-#define AssertMsg7( _exp, _msg, a1, a2, a3, a4, a5, a6, a7 ) AssertMsg( _exp, (const tchar *)(CDbgFmtMsg( _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( _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( _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 DbgVerify( _exp ) (_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
-
-// The Always version of the assert macros are defined even when DBGFLAG_ASSERT is not,
-// so they will be available even in release.
-#define AssertAlways( _exp ) _AssertMsg( _exp, _T("Assertion Failed: ") _T(#_exp), ((void)0), false )
-#define AssertMsgAlways( _exp, _msg ) _AssertMsg( _exp, _msg, ((void)0), false )
-
-
-#if !defined( _X360 ) || !defined( _RETAIL )
-
-/* These are always compiled in */
-DBG_INTERFACE void Msg( PRINTF_FORMAT_STRING const tchar* pMsg, ... ) FMTFUNCTION( 1, 2 );
-DBG_INTERFACE void DMsg( const tchar *pGroupName, int level, PRINTF_FORMAT_STRING const tchar *pMsg, ... ) FMTFUNCTION( 3, 4 );
-
-DBG_INTERFACE void Warning( PRINTF_FORMAT_STRING const tchar *pMsg, ... ) FMTFUNCTION( 1, 2 );
-DBG_INTERFACE void DWarning( const tchar *pGroupName, int level, PRINTF_FORMAT_STRING const tchar *pMsg, ... ) FMTFUNCTION( 3, 4 );
-
-DBG_INTERFACE void Log( PRINTF_FORMAT_STRING const tchar *pMsg, ... ) FMTFUNCTION( 1, 2 );
-DBG_INTERFACE void DLog( const tchar *pGroupName, int level, PRINTF_FORMAT_STRING const tchar *pMsg, ... ) FMTFUNCTION( 3, 4 );
-
-#ifdef Error
-// p4.cpp does a #define Error Warning and in that case the Error prototype needs to
-// be consistent with the Warning prototype.
-DBG_INTERFACE void Error( PRINTF_FORMAT_STRING const tchar *pMsg, ... ) FMTFUNCTION( 1, 2 );
-#else
-DBG_INTERFACE void NORETURN Error( PRINTF_FORMAT_STRING const tchar *pMsg, ... ) FMTFUNCTION( 1, 2 );
-#endif
-
-#else
-
-inline void Msg( ... ) {}
-inline void DMsg( ... ) {}
-inline void Warning( PRINTF_FORMAT_STRING const tchar *pMsg, ... ) {}
-inline void DWarning( ... ) {}
-inline void Log( ... ) {}
-inline void DLog( ... ) {}
-inline void Error( ... ) {}
-
-#endif
-
-// 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; \
- }
-
-#if !defined( _X360 ) || !defined( _RETAIL )
-
-/* A couple of super-common dynamic spew messages, here for convenience */
-/* These looked at the "developer" group */
-DBG_INTERFACE void DevMsg( int level, PRINTF_FORMAT_STRING const tchar* pMsg, ... ) FMTFUNCTION( 2, 3 );
-DBG_INTERFACE void DevWarning( int level, PRINTF_FORMAT_STRING const tchar *pMsg, ... ) FMTFUNCTION( 2, 3 );
-DBG_INTERFACE void DevLog( int level, PRINTF_FORMAT_STRING const tchar *pMsg, ... ) FMTFUNCTION( 2, 3 );
-
-/* default level versions (level 1) */
-DBG_OVERLOAD void DevMsg( PRINTF_FORMAT_STRING const tchar* pMsg, ... ) FMTFUNCTION( 1, 2 );
-DBG_OVERLOAD void DevWarning( PRINTF_FORMAT_STRING const tchar *pMsg, ... ) FMTFUNCTION( 1, 2 );
-DBG_OVERLOAD void DevLog( PRINTF_FORMAT_STRING const tchar *pMsg, ... ) FMTFUNCTION( 1, 2 );
-
-/* These looked at the "console" group */
-DBG_INTERFACE void ConColorMsg( int level, const Color& clr, PRINTF_FORMAT_STRING const tchar* pMsg, ... ) FMTFUNCTION( 3, 4 );
-DBG_INTERFACE void ConMsg( int level, PRINTF_FORMAT_STRING const tchar* pMsg, ... ) FMTFUNCTION( 2, 3 );
-DBG_INTERFACE void ConWarning( int level, PRINTF_FORMAT_STRING const tchar *pMsg, ... ) FMTFUNCTION( 2, 3 );
-DBG_INTERFACE void ConLog( int level, PRINTF_FORMAT_STRING const tchar *pMsg, ... ) FMTFUNCTION( 2, 3 );
-
-/* default console version (level 1) */
-DBG_OVERLOAD void ConColorMsg( const Color& clr, PRINTF_FORMAT_STRING const tchar* pMsg, ... ) FMTFUNCTION( 2, 3 );
-DBG_OVERLOAD void ConMsg( PRINTF_FORMAT_STRING const tchar* pMsg, ... ) FMTFUNCTION( 1, 2 );
-DBG_OVERLOAD void ConWarning( PRINTF_FORMAT_STRING const tchar *pMsg, ... ) FMTFUNCTION( 1, 2 );
-DBG_OVERLOAD void ConLog( PRINTF_FORMAT_STRING const tchar *pMsg, ... ) FMTFUNCTION( 1, 2 );
-
-/* developer console version (level 2) */
-DBG_INTERFACE void ConDColorMsg( const Color& clr, PRINTF_FORMAT_STRING const tchar* pMsg, ... ) FMTFUNCTION( 2, 3 );
-DBG_INTERFACE void ConDMsg( PRINTF_FORMAT_STRING const tchar* pMsg, ... ) FMTFUNCTION( 1, 2 );
-DBG_INTERFACE void ConDWarning( PRINTF_FORMAT_STRING const tchar *pMsg, ... ) FMTFUNCTION( 1, 2 );
-DBG_INTERFACE void ConDLog( PRINTF_FORMAT_STRING const tchar *pMsg, ... ) FMTFUNCTION( 1, 2 );
-
-/* These looked at the "network" group */
-DBG_INTERFACE void NetMsg( int level, PRINTF_FORMAT_STRING const tchar* pMsg, ... ) FMTFUNCTION( 2, 3 );
-DBG_INTERFACE void NetWarning( int level, PRINTF_FORMAT_STRING const tchar *pMsg, ... ) FMTFUNCTION( 2, 3 );
-DBG_INTERFACE void NetLog( int level, PRINTF_FORMAT_STRING const tchar *pMsg, ... ) FMTFUNCTION( 2, 3 );
-
-void ValidateSpew( class CValidator &validator );
-
-#else
-
-inline void DevMsg( ... ) {}
-inline void DevWarning( ... ) {}
-inline void DevLog( ... ) {}
-inline void ConMsg( ... ) {}
-inline void ConLog( ... ) {}
-inline void NetMsg( ... ) {}
-inline void NetWarning( ... ) {}
-inline void NetLog( ... ) {}
-
-#endif
-
-DBG_INTERFACE void COM_TimestampedLog( PRINTF_FORMAT_STRING char const *fmt, ... ) FMTFUNCTION( 1, 2 );
-
-/* Code macros, debugger interface */
-
-#ifdef DBGFLAG_ASSERT
-
-#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 */
-
-//-----------------------------------------------------------------------------
-
-#ifndef _RETAIL
-class CScopeMsg
-{
-public:
- CScopeMsg( const char *pszScope )
- {
- m_pszScope = pszScope;
- Msg( "%s { ", pszScope );
- }
- ~CScopeMsg()
- {
- Msg( "} %s", m_pszScope );
- }
- const char *m_pszScope;
-};
-#define SCOPE_MSG( msg ) CScopeMsg scopeMsg( msg )
-#else
-#define SCOPE_MSG( msg )
-#endif
-
-
-//-----------------------------------------------------------------------------
-// Macro to assist in asserting constant invariants during compilation
-
-// This implementation of compile time assert has zero cost (so it can safely be
-// included in release builds) and can be used at file scope or function scope.
-// We're using an ancient version of GCC that can't quite handle some
-// of our complicated templates properly. Use some preprocessor trickery
-// to workaround this
-#ifdef __GNUC__
- #define COMPILE_TIME_ASSERT( pred ) typedef int UNIQUE_ID[ (pred) ? 1 : -1 ]
-#else
- #if _MSC_VER >= 1600
- // If available use static_assert instead of weird language tricks. This
- // leads to much more readable messages when compile time assert constraints
- // are violated.
- #define COMPILE_TIME_ASSERT( pred ) static_assert( pred, "Compile time assert constraint is not true: " #pred )
- #else
- // Due to gcc bugs this can in rare cases (some template functions) cause redeclaration
- // errors when used multiple times in one scope. Fix by adding extra scoping.
- #define COMPILE_TIME_ASSERT( pred ) typedef char compile_time_assert_type[(pred) ? 1 : -1];
- #endif
-#endif
-// ASSERT_INVARIANT used to be needed in order to allow COMPILE_TIME_ASSERTs at global
-// scope. However the new COMPILE_TIME_ASSERT macro supports that by default.
-#define ASSERT_INVARIANT( pred ) COMPILE_TIME_ASSERT( pred )
-
-
-#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.
-
-DBG_INTERFACE void _AssertValidReadPtr( void* ptr, int count = 1 );
-DBG_INTERFACE void _AssertValidWritePtr( void* ptr, int count = 1 );
-DBG_INTERFACE void _AssertValidReadWritePtr( void* ptr, int count = 1 );
-DBG_INTERFACE void AssertValidStringPtr( const tchar* ptr, int maxchar = 0xFFFFFF );
-
-#ifdef DBGFLAG_ASSERT
-
-FORCEINLINE void AssertValidReadPtr( const void* ptr, int count = 1 ) { _AssertValidReadPtr( (void*)ptr, count ); }
-FORCEINLINE void AssertValidWritePtr( const void* ptr, int count = 1 ) { _AssertValidWritePtr( (void*)ptr, count ); }
-FORCEINLINE void AssertValidReadWritePtr( const void* ptr, int count = 1 ) { _AssertValidReadWritePtr( (void*)ptr, count ); }
-
-#else
-
-FORCEINLINE void AssertValidReadPtr( const void* ptr, int count = 1 ) { }
-FORCEINLINE void AssertValidWritePtr( const void* ptr, int count = 1 ) { }
-FORCEINLINE void AssertValidReadWritePtr( const void* ptr, int count = 1 ) { }
-#define AssertValidStringPtr AssertValidReadPtr
-
-#endif
-
-#define AssertValidThis() AssertValidReadWritePtr(this,sizeof(*this))
-
-//-----------------------------------------------------------------------------
-// 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
-
-//-----------------------------------------------------------------------------
-//
-// Purpose: Inline string formatter
-//
-
-#include "tier0/valve_off.h"
-class CDbgFmtMsg
-{
-public:
- CDbgFmtMsg(PRINTF_FORMAT_STRING const tchar *pszFormat, ...) FMTFUNCTION( 2, 3 )
- {
- va_list arg_ptr;
-
- va_start(arg_ptr, pszFormat);
- _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
-
-//-----------------------------------------------------------------------------
-
-#endif /* DBG_H */
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//
+//=============================================================================//
+#ifndef DBG_H
+#define DBG_H
+
+#ifdef _WIN32
+#pragma once
+#endif
+
+#include "basetypes.h"
+#include "dbgflag.h"
+#include "platform.h"
+#include <math.h>
+#include <stdio.h>
+#include <stdarg.h>
+
+#ifdef POSIX
+#define __cdecl
+#endif
+
+//-----------------------------------------------------------------------------
+// dll export stuff
+//-----------------------------------------------------------------------------
+#ifndef STATIC_TIER0
+
+#ifdef TIER0_DLL_EXPORT
+#define DBG_INTERFACE DLL_EXPORT
+#define DBG_OVERLOAD DLL_GLOBAL_EXPORT
+#define DBG_CLASS DLL_CLASS_EXPORT
+#else
+#define DBG_INTERFACE DLL_IMPORT
+#define DBG_OVERLOAD DLL_GLOBAL_IMPORT
+#define DBG_CLASS DLL_CLASS_IMPORT
+#endif
+
+#else // BUILD_AS_DLL
+
+#define DBG_INTERFACE extern
+#define DBG_OVERLOAD
+#define DBG_CLASS
+#endif // BUILD_AS_DLL
+
+
+class Color;
+
+
+//-----------------------------------------------------------------------------
+// Usage model for the Dbg library
+//
+// 1. Spew.
+//
+// Spew can be used in a static and a dynamic mode. The static
+// mode allows us to display assertions and other messages either only
+// in debug builds, or in non-release builds. The dynamic mode allows us to
+// turn on and off certain spew messages while the application is running.
+//
+// Static Spew messages:
+//
+// Assertions are used to detect and warn about invalid states
+// Spews are used to display a particular status/warning message.
+//
+// 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).
+//
+// To use a warning, use
+//
+// Warning("Oh I feel so %s all over\n", "yummy");
+//
+// Warning will do its magic in only Debug builds. To perform spew in *all*
+// builds, use RelWarning.
+//
+// Three other spew types, Msg, Log, and Error, are compiled into all builds.
+// These error types do *not* need two sets of parenthesis.
+//
+// Msg( "Isn't this exciting %d?", 5 );
+// Error( "I'm just thrilled" );
+//
+// Dynamic Spew messages
+//
+// It is possible to dynamically turn spew on and off. Dynamic spew is
+// identified by a spew group and priority level. To turn spew on for a
+// particular spew group, use SpewActivate( "group", level ). This will
+// cause all spew in that particular group with priority levels <= the
+// level specified in the SpewActivate function to be printed. Use DSpew
+// to perform the spew:
+//
+// DWarning( "group", level, "Oh I feel even yummier!\n" );
+//
+// Priority level 0 means that the spew will *always* be printed, and group
+// '*' is the default spew group. If a DWarning is encountered using a group
+// whose priority has not been set, it will use the priority of the default
+// group. The priority of the default group is initially set to 0.
+//
+// Spew output
+//
+// The output of the spew system can be redirected to an externally-supplied
+// function which is responsible for outputting the spew. By default, the
+// spew is simply printed using printf.
+//
+// To redirect spew output, call SpewOutput.
+//
+// SpewOutputFunc( OutputFunc );
+//
+// This will cause OutputFunc to be called every time a spew message is
+// generated. OutputFunc will be passed a spew type and a message to print.
+// It must return a value indicating whether the debugger should be invoked,
+// whether the program should continue running, or whether the program
+// should abort.
+//
+// 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();
+//-----------------------------------------------------------------------------
+
+/* Various types of spew messages */
+// I'm sure you're asking yourself why SPEW_ instead of DBG_ ?
+// It's because DBG_ is used all over the place in windows.h
+// For example, DBG_CONTINUE is defined. Feh.
+enum SpewType_t
+{
+ SPEW_MESSAGE = 0,
+ SPEW_WARNING,
+ SPEW_ASSERT,
+ SPEW_ERROR,
+ SPEW_LOG,
+
+ SPEW_TYPE_COUNT
+};
+
+enum SpewRetval_t
+{
+ SPEW_DEBUGGER = 0,
+ SPEW_CONTINUE,
+ SPEW_ABORT
+};
+
+/* type of externally defined function used to display debug spew */
+typedef SpewRetval_t (*SpewOutputFunc_t)( SpewType_t spewType, const tchar *pMsg );
+
+/* Used to redirect spew output */
+DBG_INTERFACE void SpewOutputFunc( SpewOutputFunc_t func );
+
+/* Used to get the current spew output function */
+DBG_INTERFACE SpewOutputFunc_t GetSpewOutputFunc( void );
+
+/* This is the default spew fun, which is used if you don't specify one */
+DBG_INTERFACE SpewRetval_t DefaultSpewFunc( SpewType_t type, const tchar *pMsg );
+
+/* Same as the default spew func, but returns SPEW_ABORT for asserts */
+DBG_INTERFACE SpewRetval_t DefaultSpewFuncAbortOnAsserts( SpewType_t type, const tchar *pMsg );
+
+/* Should be called only inside a SpewOutputFunc_t, returns groupname, level, color */
+DBG_INTERFACE const tchar* GetSpewOutputGroup( void );
+DBG_INTERFACE int GetSpewOutputLevel( void );
+DBG_INTERFACE const Color* GetSpewOutputColor( void );
+
+/* Used to manage spew groups and subgroups */
+DBG_INTERFACE void SpewActivate( const tchar* pGroupName, int level );
+DBG_INTERFACE bool IsSpewActive( const tchar* pGroupName, int level );
+
+/* Used to display messages, should never be called directly. */
+DBG_INTERFACE void _SpewInfo( SpewType_t type, const tchar* pFile, int line );
+DBG_INTERFACE SpewRetval_t _SpewMessage( PRINTF_FORMAT_STRING const tchar* pMsg, ... ) FMTFUNCTION( 1, 2 );
+DBG_INTERFACE SpewRetval_t _DSpewMessage( const tchar *pGroupName, int level, PRINTF_FORMAT_STRING const tchar* pMsg, ... ) FMTFUNCTION( 3, 4 );
+DBG_INTERFACE SpewRetval_t ColorSpewMessage( SpewType_t type, const Color *pColor, PRINTF_FORMAT_STRING const tchar* pMsg, ... ) FMTFUNCTION( 3, 4 );
+DBG_INTERFACE void _ExitOnFatalAssert( const tchar* pFile, int line );
+DBG_INTERFACE bool ShouldUseNewAssertDialog();
+
+DBG_INTERFACE bool SetupWin32ConsoleIO();
+
+// Returns true if they want to break in the debugger.
+DBG_INTERFACE bool DoNewAssertDialog( const tchar *pFile, int line, const tchar *pExpression );
+
+// Allows the assert dialogs to be turned off from code
+DBG_INTERFACE bool AreAllAssertsDisabled();
+DBG_INTERFACE void SetAllAssertsDisabled( bool bAssertsEnabled );
+
+// Provides a callback that is called on asserts regardless of spew levels
+typedef void (*AssertFailedNotifyFunc_t)( const char *pchFile, int nLine, const char *pchMessage );
+DBG_INTERFACE void SetAssertFailedNotifyFunc( AssertFailedNotifyFunc_t func );
+DBG_INTERFACE void CallAssertFailedNotifyFunc( const char *pchFile, int nLine, const char *pchMessage );
+
+#if defined( USE_SDL )
+DBG_INTERFACE void SetAssertDialogParent( struct SDL_Window *window );
+DBG_INTERFACE struct SDL_Window * GetAssertDialogParent();
+#endif
+
+/* Used to define macros, never use these directly. */
+
+#ifdef _PREFAST_
+ // When doing /analyze builds define _AssertMsg 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.
+ // The unfortunate !! is necessary because otherwise /analyze is incapable of evaluating
+ // all of the logical expressions that the regular compiler can handle.
+ // Include _msg in the macro so that format errors in it are detected.
+ #define _AssertMsg( _exp, _msg, _executeExp, _bFatal ) do { __analysis_assume( !!(_exp) ); _msg; } while (0)
+ #define _AssertMsgOnce( _exp, _msg, _bFatal ) do { __analysis_assume( !!(_exp) ); _msg; } while (0)
+ // Force asserts on for /analyze so that we get a __analysis_assume of all of the constraints.
+ #define DBGFLAG_ASSERT
+ #define DBGFLAG_ASSERTFATAL
+ #define DBGFLAG_ASSERTDEBUG
+#else
+ #define _AssertMsg( _exp, _msg, _executeExp, _bFatal ) \
+ do { \
+ if (!(_exp)) \
+ { \
+ _SpewInfo( SPEW_ASSERT, __TFILE__, __LINE__ ); \
+ SpewRetval_t ret = _SpewMessage("%s", _msg); \
+ CallAssertFailedNotifyFunc( __TFILE__, __LINE__, _msg ); \
+ _executeExp; \
+ if ( ret == SPEW_DEBUGGER) \
+ { \
+ if ( !ShouldUseNewAssertDialog() || DoNewAssertDialog( __TFILE__, __LINE__, _msg ) ) \
+ { \
+ DebuggerBreak(); \
+ } \
+ if ( _bFatal ) \
+ { \
+ _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
+
+// 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 DbgVerify( _exp ) Assert( _exp )
+
+#define AssertMsg1( _exp, _msg, a1 ) AssertMsg( _exp, (const tchar *)(CDbgFmtMsg( _msg, a1 )) )
+#define AssertMsg2( _exp, _msg, a1, a2 ) AssertMsg( _exp, (const tchar *)(CDbgFmtMsg( _msg, a1, a2 )) )
+#define AssertMsg3( _exp, _msg, a1, a2, a3 ) AssertMsg( _exp, (const tchar *)(CDbgFmtMsg( _msg, a1, a2, a3 )) )
+#define AssertMsg4( _exp, _msg, a1, a2, a3, a4 ) AssertMsg( _exp, (const tchar *)(CDbgFmtMsg( _msg, a1, a2, a3, a4 )) )
+#define AssertMsg5( _exp, _msg, a1, a2, a3, a4, a5 ) AssertMsg( _exp, (const tchar *)(CDbgFmtMsg( _msg, a1, a2, a3, a4, a5 )) )
+#define AssertMsg6( _exp, _msg, a1, a2, a3, a4, a5, a6 ) AssertMsg( _exp, (const tchar *)(CDbgFmtMsg( _msg, a1, a2, a3, a4, a5, a6 )) )
+#define AssertMsg7( _exp, _msg, a1, a2, a3, a4, a5, a6, a7 ) AssertMsg( _exp, (const tchar *)(CDbgFmtMsg( _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( _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( _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 DbgVerify( _exp ) (_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
+
+// The Always version of the assert macros are defined even when DBGFLAG_ASSERT is not,
+// so they will be available even in release.
+#define AssertAlways( _exp ) _AssertMsg( _exp, _T("Assertion Failed: ") _T(#_exp), ((void)0), false )
+#define AssertMsgAlways( _exp, _msg ) _AssertMsg( _exp, _msg, ((void)0), false )
+
+
+#if !defined( _X360 ) || !defined( _RETAIL )
+
+/* These are always compiled in */
+DBG_INTERFACE void Msg( PRINTF_FORMAT_STRING const tchar* pMsg, ... ) FMTFUNCTION( 1, 2 );
+DBG_INTERFACE void DMsg( const tchar *pGroupName, int level, PRINTF_FORMAT_STRING const tchar *pMsg, ... ) FMTFUNCTION( 3, 4 );
+
+DBG_INTERFACE void Warning( PRINTF_FORMAT_STRING const tchar *pMsg, ... ) FMTFUNCTION( 1, 2 );
+DBG_INTERFACE void DWarning( const tchar *pGroupName, int level, PRINTF_FORMAT_STRING const tchar *pMsg, ... ) FMTFUNCTION( 3, 4 );
+
+DBG_INTERFACE void Log( PRINTF_FORMAT_STRING const tchar *pMsg, ... ) FMTFUNCTION( 1, 2 );
+DBG_INTERFACE void DLog( const tchar *pGroupName, int level, PRINTF_FORMAT_STRING const tchar *pMsg, ... ) FMTFUNCTION( 3, 4 );
+
+#ifdef Error
+// p4.cpp does a #define Error Warning and in that case the Error prototype needs to
+// be consistent with the Warning prototype.
+DBG_INTERFACE void Error( PRINTF_FORMAT_STRING const tchar *pMsg, ... ) FMTFUNCTION( 1, 2 );
+#else
+DBG_INTERFACE void NORETURN Error( PRINTF_FORMAT_STRING const tchar *pMsg, ... ) FMTFUNCTION( 1, 2 );
+#endif
+
+#else
+
+inline void Msg( ... ) {}
+inline void DMsg( ... ) {}
+inline void Warning( PRINTF_FORMAT_STRING const tchar *pMsg, ... ) {}
+inline void DWarning( ... ) {}
+inline void Log( ... ) {}
+inline void DLog( ... ) {}
+inline void Error( ... ) {}
+
+#endif
+
+// 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; \
+ }
+
+#if !defined( _X360 ) || !defined( _RETAIL )
+
+/* A couple of super-common dynamic spew messages, here for convenience */
+/* These looked at the "developer" group */
+DBG_INTERFACE void DevMsg( int level, PRINTF_FORMAT_STRING const tchar* pMsg, ... ) FMTFUNCTION( 2, 3 );
+DBG_INTERFACE void DevWarning( int level, PRINTF_FORMAT_STRING const tchar *pMsg, ... ) FMTFUNCTION( 2, 3 );
+DBG_INTERFACE void DevLog( int level, PRINTF_FORMAT_STRING const tchar *pMsg, ... ) FMTFUNCTION( 2, 3 );
+
+/* default level versions (level 1) */
+DBG_OVERLOAD void DevMsg( PRINTF_FORMAT_STRING const tchar* pMsg, ... ) FMTFUNCTION( 1, 2 );
+DBG_OVERLOAD void DevWarning( PRINTF_FORMAT_STRING const tchar *pMsg, ... ) FMTFUNCTION( 1, 2 );
+DBG_OVERLOAD void DevLog( PRINTF_FORMAT_STRING const tchar *pMsg, ... ) FMTFUNCTION( 1, 2 );
+
+/* These looked at the "console" group */
+DBG_INTERFACE void ConColorMsg( int level, const Color& clr, PRINTF_FORMAT_STRING const tchar* pMsg, ... ) FMTFUNCTION( 3, 4 );
+DBG_INTERFACE void ConMsg( int level, PRINTF_FORMAT_STRING const tchar* pMsg, ... ) FMTFUNCTION( 2, 3 );
+DBG_INTERFACE void ConWarning( int level, PRINTF_FORMAT_STRING const tchar *pMsg, ... ) FMTFUNCTION( 2, 3 );
+DBG_INTERFACE void ConLog( int level, PRINTF_FORMAT_STRING const tchar *pMsg, ... ) FMTFUNCTION( 2, 3 );
+
+/* default console version (level 1) */
+DBG_OVERLOAD void ConColorMsg( const Color& clr, PRINTF_FORMAT_STRING const tchar* pMsg, ... ) FMTFUNCTION( 2, 3 );
+DBG_OVERLOAD void ConMsg( PRINTF_FORMAT_STRING const tchar* pMsg, ... ) FMTFUNCTION( 1, 2 );
+DBG_OVERLOAD void ConWarning( PRINTF_FORMAT_STRING const tchar *pMsg, ... ) FMTFUNCTION( 1, 2 );
+DBG_OVERLOAD void ConLog( PRINTF_FORMAT_STRING const tchar *pMsg, ... ) FMTFUNCTION( 1, 2 );
+
+/* developer console version (level 2) */
+DBG_INTERFACE void ConDColorMsg( const Color& clr, PRINTF_FORMAT_STRING const tchar* pMsg, ... ) FMTFUNCTION( 2, 3 );
+DBG_INTERFACE void ConDMsg( PRINTF_FORMAT_STRING const tchar* pMsg, ... ) FMTFUNCTION( 1, 2 );
+DBG_INTERFACE void ConDWarning( PRINTF_FORMAT_STRING const tchar *pMsg, ... ) FMTFUNCTION( 1, 2 );
+DBG_INTERFACE void ConDLog( PRINTF_FORMAT_STRING const tchar *pMsg, ... ) FMTFUNCTION( 1, 2 );
+
+/* These looked at the "network" group */
+DBG_INTERFACE void NetMsg( int level, PRINTF_FORMAT_STRING const tchar* pMsg, ... ) FMTFUNCTION( 2, 3 );
+DBG_INTERFACE void NetWarning( int level, PRINTF_FORMAT_STRING const tchar *pMsg, ... ) FMTFUNCTION( 2, 3 );
+DBG_INTERFACE void NetLog( int level, PRINTF_FORMAT_STRING const tchar *pMsg, ... ) FMTFUNCTION( 2, 3 );
+
+void ValidateSpew( class CValidator &validator );
+
+#else
+
+inline void DevMsg( ... ) {}
+inline void DevWarning( ... ) {}
+inline void DevLog( ... ) {}
+inline void ConMsg( ... ) {}
+inline void ConLog( ... ) {}
+inline void NetMsg( ... ) {}
+inline void NetWarning( ... ) {}
+inline void NetLog( ... ) {}
+
+#endif
+
+DBG_INTERFACE void COM_TimestampedLog( PRINTF_FORMAT_STRING char const *fmt, ... ) FMTFUNCTION( 1, 2 );
+
+/* Code macros, debugger interface */
+
+#ifdef DBGFLAG_ASSERT
+
+#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 */
+
+//-----------------------------------------------------------------------------
+
+#ifndef _RETAIL
+class CScopeMsg
+{
+public:
+ CScopeMsg( const char *pszScope )
+ {
+ m_pszScope = pszScope;
+ Msg( "%s { ", pszScope );
+ }
+ ~CScopeMsg()
+ {
+ Msg( "} %s", m_pszScope );
+ }
+ const char *m_pszScope;
+};
+#define SCOPE_MSG( msg ) CScopeMsg scopeMsg( msg )
+#else
+#define SCOPE_MSG( msg )
+#endif
+
+
+//-----------------------------------------------------------------------------
+// Macro to assist in asserting constant invariants during compilation
+
+// This implementation of compile time assert has zero cost (so it can safely be
+// included in release builds) and can be used at file scope or function scope.
+// We're using an ancient version of GCC that can't quite handle some
+// of our complicated templates properly. Use some preprocessor trickery
+// to workaround this
+#ifdef __GNUC__
+ #define COMPILE_TIME_ASSERT( pred ) typedef int UNIQUE_ID[ (pred) ? 1 : -1 ]
+#else
+ #if _MSC_VER >= 1600
+ // If available use static_assert instead of weird language tricks. This
+ // leads to much more readable messages when compile time assert constraints
+ // are violated.
+ #define COMPILE_TIME_ASSERT( pred ) static_assert( pred, "Compile time assert constraint is not true: " #pred )
+ #else
+ // Due to gcc bugs this can in rare cases (some template functions) cause redeclaration
+ // errors when used multiple times in one scope. Fix by adding extra scoping.
+ #define COMPILE_TIME_ASSERT( pred ) typedef char compile_time_assert_type[(pred) ? 1 : -1];
+ #endif
+#endif
+// ASSERT_INVARIANT used to be needed in order to allow COMPILE_TIME_ASSERTs at global
+// scope. However the new COMPILE_TIME_ASSERT macro supports that by default.
+#define ASSERT_INVARIANT( pred ) COMPILE_TIME_ASSERT( pred )
+
+
+#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.
+
+DBG_INTERFACE void _AssertValidReadPtr( void* ptr, int count = 1 );
+DBG_INTERFACE void _AssertValidWritePtr( void* ptr, int count = 1 );
+DBG_INTERFACE void _AssertValidReadWritePtr( void* ptr, int count = 1 );
+DBG_INTERFACE void AssertValidStringPtr( const tchar* ptr, int maxchar = 0xFFFFFF );
+
+#ifdef DBGFLAG_ASSERT
+
+FORCEINLINE void AssertValidReadPtr( const void* ptr, int count = 1 ) { _AssertValidReadPtr( (void*)ptr, count ); }
+FORCEINLINE void AssertValidWritePtr( const void* ptr, int count = 1 ) { _AssertValidWritePtr( (void*)ptr, count ); }
+FORCEINLINE void AssertValidReadWritePtr( const void* ptr, int count = 1 ) { _AssertValidReadWritePtr( (void*)ptr, count ); }
+
+#else
+
+FORCEINLINE void AssertValidReadPtr( const void* ptr, int count = 1 ) { }
+FORCEINLINE void AssertValidWritePtr( const void* ptr, int count = 1 ) { }
+FORCEINLINE void AssertValidReadWritePtr( const void* ptr, int count = 1 ) { }
+#define AssertValidStringPtr AssertValidReadPtr
+
+#endif
+
+#define AssertValidThis() AssertValidReadWritePtr(this,sizeof(*this))
+
+//-----------------------------------------------------------------------------
+// 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
+
+//-----------------------------------------------------------------------------
+//
+// Purpose: Inline string formatter
+//
+
+#include "tier0/valve_off.h"
+class CDbgFmtMsg
+{
+public:
+ CDbgFmtMsg(PRINTF_FORMAT_STRING const tchar *pszFormat, ...) FMTFUNCTION( 2, 3 )
+ {
+ va_list arg_ptr;
+
+ va_start(arg_ptr, pszFormat);
+ _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
+
+//-----------------------------------------------------------------------------
+
+#endif /* DBG_H */