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