OVR_Log.h 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252
  1. /************************************************************************************
  2. PublicHeader: OVR
  3. Filename : OVR_Log.h
  4. Content : Logging support
  5. Created : September 19, 2012
  6. Notes :
  7. Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved.
  8. Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License");
  9. you may not use the Oculus VR Rift SDK except in compliance with the License,
  10. which is provided at the time of installation or download, or which
  11. otherwise accompanies this software in either electronic or hard copy form.
  12. You may obtain a copy of the License at
  13. http://www.oculusvr.com/licenses/LICENSE-3.2
  14. Unless required by applicable law or agreed to in writing, the Oculus VR SDK
  15. distributed under the License is distributed on an "AS IS" BASIS,
  16. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  17. See the License for the specific language governing permissions and
  18. limitations under the License.
  19. ************************************************************************************/
  20. #ifndef OVR_Log_h
  21. #define OVR_Log_h
  22. #include "OVR_Types.h"
  23. #include "OVR_Delegates.h"
  24. #include "OVR_Callbacks.h"
  25. #include <stdarg.h>
  26. namespace OVR {
  27. //-----------------------------------------------------------------------------------
  28. // ***** Logging Constants
  29. // LogMaskConstants defined bit mask constants that describe what log messages
  30. // should be displayed.
  31. enum LogMaskConstants
  32. {
  33. LogMask_Regular = 0x100,
  34. LogMask_Debug = 0x200,
  35. LogMask_None = 0,
  36. LogMask_All = LogMask_Regular|LogMask_Debug
  37. };
  38. // LogLevel should match the CAPI ovrLogLevel enum, values are passed back to ovrLogCallback
  39. enum LogLevel
  40. {
  41. LogLevel_Debug = 0,
  42. LogLevel_Info = 1,
  43. LogLevel_Error = 2
  44. };
  45. // System log channel name to use. In Windows this will be the Application Event origin name.
  46. #ifndef OVR_SYSLOG_NAME
  47. #define OVR_SYSLOG_NAME L"OculusVR"
  48. #endif // OVR_SYSLOG_NAME
  49. // LogMessageType describes the type of the log message, controls when it is
  50. // displayed and what prefix/suffix is given to it. Messages are subdivided into
  51. // regular and debug logging types. Debug logging is only generated in debug builds.
  52. //
  53. // Log_Text - General output text displayed without prefix or new-line.
  54. // Used in OVR libraries for general log flow messages
  55. // such as "Device Initialized".
  56. //
  57. // Log_Error - Error message output with "Error: %s\n", intended for
  58. // application/sample-level use only, in cases where an expected
  59. // operation failed. OVR libraries should not use this internally,
  60. // reporting status codes instead.
  61. //
  62. // Log_DebugText - Message without prefix or new lines; output in Debug build only.
  63. //
  64. // Log_Debug - Debug-build only message, formatted with "Debug: %s\n".
  65. // Intended to comment on incorrect API usage that doesn't lead
  66. // to crashes but can be avoided with proper use.
  67. // There is no Debug Error on purpose, since real errors should
  68. // be handled by API user.
  69. //
  70. // Log_Assert - Debug-build only message, formatted with "Assert: %s\n".
  71. // Intended for severe unrecoverable conditions in library
  72. // source code. Generated though OVR_ASSERT_MSG(c, "Text").
  73. enum LogMessageType
  74. {
  75. // General Logging
  76. Log_Text = LogMask_Regular | 0,
  77. Log_Error = LogMask_Regular | 1, // "Error: %s\n".
  78. // Debug-only messages (not generated in release build)
  79. Log_DebugText = LogMask_Debug | 0,
  80. Log_Debug = LogMask_Debug | 1, // "Debug: %s\n".
  81. Log_Assert = LogMask_Debug | 2, // "Assert: %s\n".
  82. };
  83. // LOG_VAARG_ATTRIBUTE macro, enforces printf-style formatting for message types
  84. #ifdef __GNUC__
  85. # define OVR_LOG_VAARG_ATTRIBUTE(a,b) __attribute__((format (printf, a, b)))
  86. #else
  87. # define OVR_LOG_VAARG_ATTRIBUTE(a,b)
  88. #endif
  89. //-----------------------------------------------------------------------------------
  90. // ***** Log
  91. // Log defines a base class interface that can be implemented to catch both
  92. // debug and runtime messages.
  93. // Debug logging can be overridden by calling Log::SetGlobalLog.
  94. class Log
  95. {
  96. friend class System;
  97. #ifdef OVR_OS_WIN32
  98. void* hEventSource;
  99. #endif
  100. public:
  101. Log(unsigned logMask = LogMask_Debug, bool defaultLogEnabled = true);
  102. virtual ~Log();
  103. typedef Delegate2<void, const char*, LogMessageType> LogHandler;
  104. // The following is deprecated, as there is no longer a max log buffer message size.
  105. enum { MaxLogBufferMessageSize = 4096 };
  106. unsigned GetLoggingMask() const { return LoggingMask; }
  107. void SetLoggingMask(unsigned logMask) { LoggingMask = logMask; }
  108. bool GetDefaultLogEnabled() const { return DefaultLogEnabled; }
  109. void SetDefaultLogEnabled(bool defaultLogEnabled) { DefaultLogEnabled = defaultLogEnabled; }
  110. static void AddLogObserver(CallbackListener<LogHandler>* listener);
  111. // This is the same callback signature as in the CAPI.
  112. typedef void (*CAPICallback)(uintptr_t userData, int level, const char* message);
  113. // This function should be called before OVR::Initialize()
  114. static void SetCAPICallback(CAPICallback callback, uintptr_t userData);
  115. // Internal
  116. // Invokes observers, then calls LogMessageVarg()
  117. static void LogMessageVargInt(LogMessageType messageType, const char* fmt, va_list argList);
  118. // This virtual function receives all the messages,
  119. // developers should override this function in order to do custom logging
  120. virtual void LogMessageVarg(LogMessageType messageType, const char* fmt, va_list argList);
  121. // Call the logging function with specific message type, with no type filtering.
  122. void LogMessage(LogMessageType messageType,
  123. const char* fmt, ...) OVR_LOG_VAARG_ATTRIBUTE(3,4);
  124. // Helper used by LogMessageVarg to format the log message, writing the resulting
  125. // string into buffer. It formats text based on fmt and appends prefix/new line
  126. // based on LogMessageType. Return behavior is the same as ISO C vsnprintf: returns the
  127. // required strlen of buffer (which will be >= bufferSize if bufferSize is insufficient)
  128. // or returns a negative value because the input was bad.
  129. static int FormatLog(char* buffer, size_t bufferSize, LogMessageType messageType,
  130. const char* fmt, va_list argList);
  131. // Default log output implementation used by by LogMessageVarg.
  132. // Debug flag may be used to re-direct output on some platforms, but doesn't
  133. // necessarily disable it in release builds; that is the job of the called.
  134. void DefaultLogOutput(const char* textBuffer, LogMessageType messageType, int bufferSize = -1);
  135. // Determines if the specified message type is for debugging only.
  136. static bool IsDebugMessage(LogMessageType messageType)
  137. {
  138. return (messageType & LogMask_Debug) != 0;
  139. }
  140. // *** Global APIs
  141. // Global Log registration APIs.
  142. // - Global log is used for OVR_DEBUG messages. Set global log to null (0)
  143. // to disable all logging.
  144. static void SetGlobalLog(Log *log);
  145. static Log* GetGlobalLog();
  146. // Returns default log singleton instance.
  147. static Log* GetDefaultLog();
  148. // Applies logMask to the default log and returns a pointer to it.
  149. // By default, only Debug logging is enabled, so to avoid SDK generating console
  150. // messages in user app (those are always disabled in release build,
  151. // even if the flag is set). This function is useful in System constructor.
  152. static Log* ConfigureDefaultLog(unsigned logMask = LogMask_Debug, bool defaultLogEnabled = true)
  153. {
  154. Log* log = GetDefaultLog();
  155. log->SetLoggingMask(logMask);
  156. log->SetDefaultLogEnabled(defaultLogEnabled);
  157. return log;
  158. }
  159. private:
  160. // Logging mask described by LogMaskConstants.
  161. unsigned LoggingMask;
  162. // If true then LogMessageVarg writes to stdout, else it writes nothing. LogMessageVargInt is unaffected.
  163. bool DefaultLogEnabled;
  164. };
  165. //-----------------------------------------------------------------------------------
  166. // ***** Global Logging Functions and Debug Macros
  167. // These functions will output text to global log with semantics described by
  168. // their LogMessageType.
  169. void LogText(const char* fmt, ...) OVR_LOG_VAARG_ATTRIBUTE(1,2);
  170. void LogError(const char* fmt, ...) OVR_LOG_VAARG_ATTRIBUTE(1,2);
  171. #ifdef OVR_BUILD_DEBUG
  172. // Debug build only logging.
  173. void LogDebugText(const char* fmt, ...) OVR_LOG_VAARG_ATTRIBUTE(1,2);
  174. void LogDebug(const char* fmt, ...) OVR_LOG_VAARG_ATTRIBUTE(1,2);
  175. void LogAssert(const char* fmt, ...) OVR_LOG_VAARG_ATTRIBUTE(1,2);
  176. // Macro to do debug logging, printf-style.
  177. // An extra set of set of parenthesis must be used around arguments,
  178. // as in: OVR_DEBUG_LOG(("Value %d", 2)).
  179. #define OVR_DEBUG_LOG(args) do { OVR::LogDebug args; } while(0)
  180. #define OVR_DEBUG_LOG_TEXT(args) do { OVR::LogDebugText args; } while(0)
  181. // Conditional logging. It logs when the condition 'c' is true.
  182. #define OVR_DEBUG_LOG_COND(c, args) do { if ((c)) { OVR::LogDebug args; } } while(0)
  183. #define OVR_DEBUG_LOG_TEXT_COND(c, args) do { if ((c)) { OVR::LogDebugText args; } } while(0)
  184. // Conditional logging & asserting. It asserts/logs when the condition 'c' is NOT true.
  185. #define OVR_ASSERT_LOG(c, args) do { if (!(c)) { OVR::LogAssert args; OVR_DEBUG_BREAK; } } while(0)
  186. #else
  187. // If not in debug build, macros do nothing.
  188. #define OVR_DEBUG_LOG(args) ((void)0)
  189. #define OVR_DEBUG_LOG_TEXT(args) ((void)0)
  190. #define OVR_DEBUG_LOG_COND(c, args) ((void)0)
  191. #define OVR_DEBUG_LOG_TEXT_COND(args) ((void)0)
  192. #define OVR_ASSERT_LOG(c, args) ((void)0)
  193. #endif
  194. } // OVR
  195. #endif