00001 /************************************************************************************ 00002 00003 PublicHeader: OVR 00004 Filename : OVR_Log.h 00005 Content : Logging support 00006 Created : September 19, 2012 00007 Notes : 00008 00009 Copyright : Copyright 2012 Oculus VR, Inc. All Rights reserved. 00010 00011 Use of this software is subject to the terms of the Oculus license 00012 agreement provided at the time of installation or download, or which 00013 otherwise accompanies this software in either electronic or hard copy form. 00014 00015 ************************************************************************************/ 00016 00017 #ifndef OVR_Log_h 00018 #define OVR_Log_h 00019 00020 #include "OVR_Types.h" 00021 #include <stdarg.h> 00022 00023 namespace OVR { 00024 00025 //----------------------------------------------------------------------------------- 00026 // ***** Logging Constants 00027 00028 // LogMaskConstants defined bit mask constants that describe what log messages 00029 // should be displayed. 00030 enum LogMaskConstants 00031 { 00032 LogMask_Regular = 0x100, 00033 LogMask_Debug = 0x200, 00034 LogMask_None = 0, 00035 LogMask_All = LogMask_Regular|LogMask_Debug 00036 }; 00037 00038 00039 // LogMessageType describes the type of the log message, controls when it is 00040 // displayed and what prefix/suffix is given to it. Messages are subdivided into 00041 // regular and debug logging types. Debug logging is only generated in debug builds. 00042 // 00043 // Log_Text - General output text displayed without prefix or new-line. 00044 // Used in OVR libraries for general log flow messages 00045 // such as "Device Initialized". 00046 // 00047 // Log_Error - Error message output with "Error: %s\n", intended for 00048 // application/sample-level use only, in cases where an expected 00049 // operation failed. OVR libraries should not use this internally, 00050 // reporting status codes instead. 00051 // 00052 // Log_DebugText - Message without prefix or new lines; output in Debug build only. 00053 // 00054 // Log_Debug - Debug-build only message, formatted with "Debug: %s\n". 00055 // Intended to comment on incorrect API usage that doesn't lead 00056 // to crashes but can be avoided with proper use. 00057 // There is no Debug Error on purpose, since real errors should 00058 // be handled by API user. 00059 // 00060 // Log_Assert - Debug-build only message, formatted with "Assert: %s\n". 00061 // Intended for severe unrecoverable conditions in library 00062 // source code. Generated though OVR_ASSERT_MSG(c, "Text"). 00063 00064 enum LogMessageType 00065 { 00066 // General Logging 00067 Log_Text = LogMask_Regular | 0, 00068 Log_Error = LogMask_Regular | 1, // "Error: %s\n". 00069 00070 // Debug-only messages (not generated in release build) 00071 Log_DebugText = LogMask_Debug | 0, 00072 Log_Debug = LogMask_Debug | 1, // "Debug: %s\n". 00073 Log_Assert = LogMask_Debug | 2, // "Assert: %s\n". 00074 }; 00075 00076 00077 // LOG_VAARG_ATTRIBUTE macro, enforces printf-style fromatting for message types 00078 #ifdef __GNUC__ 00079 # define OVR_LOG_VAARG_ATTRIBUTE(a,b) __attribute__((format (printf, a, b))) 00080 #else 00081 # define OVR_LOG_VAARG_ATTRIBUTE(a,b) 00082 #endif 00083 00084 00085 //----------------------------------------------------------------------------------- 00086 // ***** Log 00087 00088 // Log defines a base class interface that can be implemented to catch both 00089 // debug and runtime messages. 00090 // Debug logging can be overridden by calling Log::SetGlobalLog. 00091 00092 class Log 00093 { 00094 friend class System; 00095 public: 00096 Log(unsigned logMask = LogMask_Debug) : LoggingMask(logMask) { } 00097 virtual ~Log(); 00098 00099 // Log formating buffer size used by default LogMessageVarg. Longer strings are truncated. 00100 enum { MaxLogBufferMessageSize = 2048 }; 00101 00102 unsigned GetLoggingMask() const { return LoggingMask; } 00103 void SetLoggingMask(unsigned logMask) { LoggingMask = logMask; } 00104 00105 // This virtual function receives all the messages, 00106 // developers should override this function in order to do custom logging 00107 virtual void LogMessageVarg(LogMessageType messageType, const char* fmt, va_list argList); 00108 00109 // Call the logging function with specific message type, with no type filtering. 00110 void LogMessage(LogMessageType messageType, 00111 const char* fmt, ...) OVR_LOG_VAARG_ATTRIBUTE(3,4); 00112 00113 00114 // Helper used by LogMessageVarg to format the log message, writing the resulting 00115 // string into buffer. It formats text based on fmt and appends prefix/new line 00116 // based on LogMessageType. 00117 static void FormatLog(char* buffer, unsigned bufferSize, LogMessageType messageType, 00118 const char* fmt, va_list argList); 00119 00120 // Default log output implementation used by by LogMessageVarg. 00121 // Debug flag may be used to re-direct output on some platforms, but doesn't 00122 // necessarily disable it in release builds; that is the job of the called. 00123 static void DefaultLogOutput(const char* textBuffer, bool debug); 00124 00125 // Determines if the specified message type is for debugging only. 00126 static bool IsDebugMessage(LogMessageType messageType) 00127 { 00128 return (messageType & LogMask_Debug) != 0; 00129 } 00130 00131 // *** Global APIs 00132 00133 // Global Log registration APIs. 00134 // - Global log is used for OVR_DEBUG messages. Set global log to null (0) 00135 // to disable all logging. 00136 static void SetGlobalLog(Log *log); 00137 static Log* GetGlobalLog(); 00138 00139 // Returns default log singleton instance. 00140 static Log* GetDefaultLog(); 00141 00142 // Applies logMask to the default log and returns a pointer to it. 00143 // By default, only Debug logging is enabled, so to avoid SDK generating console 00144 // messages in user app (those are always disabled in release build, 00145 // even if the flag is set). This function is useful in System constructor. 00146 static Log* ConfigureDefaultLog(unsigned logMask = LogMask_Debug) 00147 { 00148 Log* log = GetDefaultLog(); 00149 log->SetLoggingMask(logMask); 00150 return log; 00151 } 00152 00153 private: 00154 // Logging mask described by LogMaskConstants. 00155 unsigned LoggingMask; 00156 }; 00157 00158 00159 //----------------------------------------------------------------------------------- 00160 // ***** Global Logging Functions and Debug Macros 00161 00162 // These functions will output text to global log with semantics described by 00163 // their LogMessageType. 00164 void LogText(const char* fmt, ...) OVR_LOG_VAARG_ATTRIBUTE(1,2); 00165 void LogError(const char* fmt, ...) OVR_LOG_VAARG_ATTRIBUTE(1,2); 00166 00167 #ifdef OVR_BUILD_DEBUG 00168 00169 // Debug build only logging. 00170 void LogDebugText(const char* fmt, ...) OVR_LOG_VAARG_ATTRIBUTE(1,2); 00171 void LogDebug(const char* fmt, ...) OVR_LOG_VAARG_ATTRIBUTE(1,2); 00172 void LogAssert(const char* fmt, ...) OVR_LOG_VAARG_ATTRIBUTE(1,2); 00173 00174 // Macro to do debug logging, printf-style. 00175 // An extra set of set of parenthesis must be used around arguments, 00176 // as in: OVR_LOG_DEBUG(("Value %d", 2)). 00177 #define OVR_DEBUG_LOG(args) do { OVR::LogDebug args; } while(0) 00178 #define OVR_DEBUG_LOG_TEXT(args) do { OVR::LogDebugText args; } while(0) 00179 00180 #define OVR_ASSERT_LOG(c, args) do { if (!(c)) { OVR::LogAssert args; OVR_DEBUG_BREAK; } } while(0) 00181 00182 #else 00183 00184 // If not in debug build, macros do nothing. 00185 #define OVR_DEBUG_LOG(args) ((void)0) 00186 #define OVR_DEBUG_LOG_TEXT(args) ((void)0) 00187 #define OVR_ASSERT_LOG(c, args) ((void)0) 00188 00189 #endif 00190 00191 } // OVR 00192 00193 #endif