Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- //===== Copyright © 1996-2005, 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 _LINUX
- #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 );
- /* 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( const tchar* pMsg, ... );
- DBG_INTERFACE SpewRetval_t _DSpewMessage( const tchar *pGroupName, int level, const tchar* pMsg, ... );
- DBG_INTERFACE SpewRetval_t ColorSpewMessage( SpewType_t type, const Color *pColor, const tchar* pMsg, ... );
- 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 );
- /* Used to define macros, never use these directly. */
- #define _AssertMsg( _exp, _msg, _executeExp, _bFatal ) \
- do { \
- if (!(_exp)) \
- { \
- _SpewInfo( SPEW_ASSERT, __TFILE__, __LINE__ ); \
- SpewRetval_t ret = _SpewMessage("%s", _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)
- /* 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 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 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
- #if !defined( _X360 ) || !defined( _RETAIL )
- /* These are always compiled in */
- DBG_INTERFACE void Msg( const tchar* pMsg, ... );
- DBG_INTERFACE void DMsg( const tchar *pGroupName, int level, const tchar *pMsg, ... );
- DBG_INTERFACE void Warning( const tchar *pMsg, ... );
- DBG_INTERFACE void DWarning( const tchar *pGroupName, int level, const tchar *pMsg, ... );
- DBG_INTERFACE void Log( const tchar *pMsg, ... );
- DBG_INTERFACE void DLog( const tchar *pGroupName, int level, const tchar *pMsg, ... );
- DBG_INTERFACE void Error( const tchar *pMsg, ... );
- #else
- inline void Msg( ... ) {}
- inline void DMsg( ... ) {}
- inline void Warning( 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, const tchar* pMsg, ... );
- DBG_INTERFACE void DevWarning( int level, const tchar *pMsg, ... );
- DBG_INTERFACE void DevLog( int level, const tchar *pMsg, ... );
- /* default level versions (level 1) */
- DBG_OVERLOAD void DevMsg( const tchar* pMsg, ... );
- DBG_OVERLOAD void DevWarning( const tchar *pMsg, ... );
- DBG_OVERLOAD void DevLog( const tchar *pMsg, ... );
- /* These looked at the "console" group */
- DBG_INTERFACE void ConColorMsg( int level, const Color& clr, const tchar* pMsg, ... );
- DBG_INTERFACE void ConMsg( int level, const tchar* pMsg, ... );
- DBG_INTERFACE void ConWarning( int level, const tchar *pMsg, ... );
- DBG_INTERFACE void ConLog( int level, const tchar *pMsg, ... );
- /* default console version (level 1) */
- DBG_OVERLOAD void ConColorMsg( const Color& clr, const tchar* pMsg, ... );
- DBG_OVERLOAD void ConMsg( const tchar* pMsg, ... );
- DBG_OVERLOAD void ConWarning( const tchar *pMsg, ... );
- DBG_OVERLOAD void ConLog( const tchar *pMsg, ... );
- /* developer console version (level 2) */
- DBG_INTERFACE void ConDColorMsg( const Color& clr, const tchar* pMsg, ... );
- DBG_INTERFACE void ConDMsg( const tchar* pMsg, ... );
- DBG_INTERFACE void ConDWarning( const tchar *pMsg, ... );
- DBG_INTERFACE void ConDLog( const tchar *pMsg, ... );
- /* These looked at the "network" group */
- DBG_INTERFACE void NetMsg( int level, const tchar* pMsg, ... );
- DBG_INTERFACE void NetWarning( int level, const tchar *pMsg, ... );
- DBG_INTERFACE void NetLog( int level, const tchar *pMsg, ... );
- 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( char const *fmt, ... );
- /* 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 */
- //-----------------------------------------------------------------------------
- #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
- #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.
- 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 );
- 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))
- //-----------------------------------------------------------------------------
- // 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(const tchar *pszFormat, ...)
- {
- 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 */
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement