mirror of
https://github.com/alliedmodders/hl2sdk.git
synced 2024-12-23 01:59:43 +08:00
Added support for the new logging system (bug 5017, r=ds).
This commit is contained in:
parent
b7472ee95e
commit
7c12e79993
@ -15,6 +15,7 @@
|
||||
#include "basetypes.h"
|
||||
#include "dbgflag.h"
|
||||
#include "platform.h"
|
||||
#include "logging.h"
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
@ -52,17 +53,9 @@ 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:
|
||||
// 1. Assertions.
|
||||
//
|
||||
// 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
|
||||
//
|
||||
@ -79,51 +72,6 @@ class Color;
|
||||
// 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:
|
||||
@ -153,55 +101,6 @@ class Color;
|
||||
// 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
|
||||
};
|
||||
|
||||
#if 0
|
||||
/* 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, ... );
|
||||
#endif
|
||||
|
||||
DBG_INTERFACE int LoggingSystem_LogAssert( const tchar *pMsg, ... );
|
||||
DBG_INTERFACE void _ExitOnFatalAssert( const tchar* pFile, int line );
|
||||
DBG_INTERFACE bool ShouldUseNewAssertDialog();
|
||||
|
||||
@ -216,9 +115,9 @@ DBG_INTERFACE bool DoNewAssertDialog( const tchar *pFile, int line, const tchar
|
||||
do { \
|
||||
if (!(_exp)) \
|
||||
{ \
|
||||
int ret = LoggingSystem_LogAssert("%s", _msg); \
|
||||
LoggingResponse_t ret = Log_Assert( "%s (%d) : %s\n", __TFILE__, __LINE__, _msg ); \
|
||||
_executeExp; \
|
||||
if ( ret ) \
|
||||
if ( ret == LR_DEBUGGER ) \
|
||||
{ \
|
||||
if ( !ShouldUseNewAssertDialog() || DoNewAssertDialog( __TFILE__, __LINE__, _msg ) ) \
|
||||
DebuggerBreak(); \
|
||||
@ -234,7 +133,7 @@ DBG_INTERFACE bool DoNewAssertDialog( const tchar *pFile, int line, const tchar
|
||||
if (!fAsserted ) \
|
||||
{ \
|
||||
_AssertMsg( _exp, _msg, (fAsserted = true), _bFatal ); \
|
||||
} \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
/* Spew macros... */
|
||||
@ -343,21 +242,54 @@ DBG_INTERFACE bool DoNewAssertDialog( const tchar *pFile, int line, const tchar
|
||||
|
||||
#endif // DBGFLAG_ASSERT
|
||||
|
||||
#define FILE_LINE_FUNCTION_STRINGIFY(x) #x
|
||||
#define FILE_LINE_FUNCTION_TOSTRING(x) FILE_LINE_FUNCTION_STRINGIFY(x)
|
||||
#define FILE_LINE_FUNCTION_STRING __FILE__ "(" FILE_LINE_FUNCTION_TOSTRING(__LINE__) "):" __FUNCTION__ ":"
|
||||
|
||||
#if !defined( _X360 ) || !defined( _RETAIL )
|
||||
#define FILE_LINE_STRINGIFY(x) #x
|
||||
#define FILE_LINE_TOSTRING(x) FILE_LINE_STRINGIFY(x)
|
||||
#define FILE_LINE_STRING __FILE__ "(" FILE_LINE_TOSTRING(__LINE__) "):"
|
||||
|
||||
#define FUNCTION_LINE_STRINGIFY(x) #x
|
||||
#define FUNCTION_LINE_TOSTRING(x) FUNCTION_LINE_STRINGIFY(x)
|
||||
#define FUNCTION_LINE_STRING __FUNCTION__ "(" FUNCTION_LINE_TOSTRING(__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
|
||||
|
||||
/* These are always compiled in */
|
||||
DBG_INTERFACE void Msg( const tchar* pMsg, ... );
|
||||
DBG_INTERFACE void Warning( const tchar *pMsg, ... );
|
||||
DBG_INTERFACE void Error( const tchar *pMsg, ... );
|
||||
DBG_INTERFACE void Warning( const tchar *pMsg, ... ) FMTFUNCTION( 1, 2 );
|
||||
DBG_INTERFACE void Error( const tchar *pMsg, ... ) FMTFUNCTION( 1, 2 );
|
||||
|
||||
#else
|
||||
// @TODO: these callstack spew functions are currently disabled in the new logging system. Need to add support for these if desired.
|
||||
DBG_INTERFACE void _Warning_AlwaysSpewCallStack_Enable( bool bEnable );
|
||||
DBG_INTERFACE void _Warning_AlwaysSpewCallStack_Length( int iMaxCallStackLength );
|
||||
|
||||
inline void Msg( ... ) {}
|
||||
inline void Warning( const tchar *pMsg, ... ) {}
|
||||
inline void Error( ... ) {}
|
||||
DBG_INTERFACE void _Error_AlwaysSpewCallStack_Enable( bool bEnable );
|
||||
DBG_INTERFACE void _Error_AlwaysSpewCallStack_Length( int iMaxCallStackLength );
|
||||
|
||||
#endif
|
||||
DBG_INTERFACE void DevMsg( int level, const tchar* pMsg, ... ) FMTFUNCTION( 2, 3 );
|
||||
DBG_INTERFACE void DevWarning( int level, const tchar *pMsg, ... ) FMTFUNCTION( 2, 3 );
|
||||
|
||||
DBG_INTERFACE void ConDMsg( const tchar* pMsg, ... ) FMTFUNCTION( 1, 2 );
|
||||
|
||||
// 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
|
||||
@ -400,7 +332,7 @@ inline void ConDMsg( ... ) {}
|
||||
|
||||
#endif
|
||||
|
||||
DBG_INTERFACE void COM_TimestampedLog( char const *fmt, ... );
|
||||
DBG_INTERFACE void COM_TimestampedLog( char const *fmt, ... ) FMTFUNCTION( 1, 2 );
|
||||
|
||||
/* Code macros, debugger interface */
|
||||
|
||||
@ -689,6 +621,77 @@ private:
|
||||
|
||||
#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,
|
||||
};
|
||||
|
||||
DBG_INTERFACE HardwareBreakpointHandle_t SetHardwareBreakpoint( EHardwareBreakpointType eType, EHardwareBreakpointSize eSize, const void *pvLocation );
|
||||
DBG_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( "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 */
|
||||
|
695
public/tier0/logging.h
Normal file
695
public/tier0/logging.h
Normal file
@ -0,0 +1,695 @@
|
||||
//============ 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
|
||||
|
||||
/*
|
||||
---- 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;
|
||||
|
||||
#if defined(_WIN32) && !defined(THREAD_PROFILER)
|
||||
class CThreadFastMutex;
|
||||
#else
|
||||
class CThreadMutex;
|
||||
typedef CThreadMutex CThreadFastMutex;
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// 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.
|
||||
//-----------------------------------------------------------------------------
|
||||
static 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.
|
||||
//-----------------------------------------------------------------------------
|
||||
static 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
|
||||
{
|
||||
#ifndef _CERT
|
||||
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 )
|
||||
{
|
||||
DebuggerBreak();
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// 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 will spew at the given severity level.
|
||||
//-----------------------------------------------------------------------------
|
||||
bool IsChannelEnabled( LoggingChannelID_t channelID, LoggingSeverity_t severity ) const { return 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 );
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Returns whether the specified logging listener is registered.
|
||||
//-----------------------------------------------------------------------------
|
||||
bool IsListenerRegistered( ILoggingListener *pListener ) const;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// 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.
|
||||
//-----------------------------------------------------------------------------
|
||||
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; }
|
||||
|
||||
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.
|
||||
#define InternalMsg( Channel, Severity, /* [Color], Message, */ ... ) do { if ( LoggingSystem_IsChannelEnabled( Channel, Severity ) ) LoggingSystem_Log( Channel, Severity, /* [Color], Message, */ ##__VA_ARGS__ ); } while( 0 )
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// 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__ )
|
||||
#define Log_Assert( Message, ... ) LoggingSystem_LogAssert( Message, ##__VA_ARGS__ )
|
||||
|
||||
|
||||
#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_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 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 );
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// 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
|
@ -311,6 +311,12 @@ typedef void * HINSTANCE;
|
||||
#define SELECTANY static
|
||||
#endif
|
||||
|
||||
#ifdef GNUC
|
||||
#define FMTFUNCTION( fmtargnumber, firstvarargnumber ) __attribute__ (( format( printf, fmtargnumber, firstvarargnumber )))
|
||||
#else
|
||||
#define FMTFUNCTION( a, b )
|
||||
#endif
|
||||
|
||||
#if defined( _WIN32 )
|
||||
|
||||
// Used for dll exporting and importing
|
||||
|
Loading…
Reference in New Issue
Block a user