nuclear@3: /************************************************************************************ nuclear@3: nuclear@3: Filename : OVR_Log.cpp nuclear@3: Content : Logging support nuclear@3: Created : September 19, 2012 nuclear@3: Notes : nuclear@3: nuclear@3: Copyright : Copyright 2012 Oculus VR, Inc. All Rights reserved. nuclear@3: nuclear@3: Use of this software is subject to the terms of the Oculus license nuclear@3: agreement provided at the time of installation or download, or which nuclear@3: otherwise accompanies this software in either electronic or hard copy form. nuclear@3: nuclear@3: ************************************************************************************/ nuclear@3: nuclear@3: #include "OVR_Log.h" nuclear@3: #include "OVR_Std.h" nuclear@3: #include nuclear@3: #include nuclear@3: nuclear@3: #if defined(OVR_OS_WIN32) nuclear@3: #include nuclear@3: #elif defined(OVR_OS_ANDROID) nuclear@3: #include nuclear@3: #endif nuclear@3: nuclear@3: namespace OVR { nuclear@3: nuclear@3: // Global Log pointer. nuclear@3: Log* volatile OVR_GlobalLog = 0; nuclear@3: nuclear@3: //----------------------------------------------------------------------------------- nuclear@3: // ***** Log Implementation nuclear@3: nuclear@3: Log::~Log() nuclear@3: { nuclear@3: // Clear out global log nuclear@3: if (this == OVR_GlobalLog) nuclear@3: { nuclear@3: // TBD: perhaps we should ASSERT if this happens before system shutdown? nuclear@3: OVR_GlobalLog = 0; nuclear@3: } nuclear@3: } nuclear@3: nuclear@3: void Log::LogMessageVarg(LogMessageType messageType, const char* fmt, va_list argList) nuclear@3: { nuclear@3: if ((messageType & LoggingMask) == 0) nuclear@3: return; nuclear@3: #ifndef OVR_BUILD_DEBUG nuclear@3: if (IsDebugMessage(messageType)) nuclear@3: return; nuclear@3: #endif nuclear@3: nuclear@3: char buffer[MaxLogBufferMessageSize]; nuclear@3: FormatLog(buffer, MaxLogBufferMessageSize, messageType, fmt, argList); nuclear@3: DefaultLogOutput(buffer, IsDebugMessage(messageType)); nuclear@3: } nuclear@3: nuclear@3: void OVR::Log::LogMessage(LogMessageType messageType, const char* pfmt, ...) nuclear@3: { nuclear@3: va_list argList; nuclear@3: va_start(argList, pfmt); nuclear@3: LogMessageVarg(messageType, pfmt, argList); nuclear@3: va_end(argList); nuclear@3: } nuclear@3: nuclear@3: nuclear@3: void Log::FormatLog(char* buffer, unsigned bufferSize, LogMessageType messageType, nuclear@3: const char* fmt, va_list argList) nuclear@3: { nuclear@3: bool addNewline = true; nuclear@3: nuclear@3: switch(messageType) nuclear@3: { nuclear@3: case Log_Error: OVR_strcpy(buffer, bufferSize, "Error: "); break; nuclear@3: case Log_Debug: OVR_strcpy(buffer, bufferSize, "Debug: "); break; nuclear@3: case Log_Assert: OVR_strcpy(buffer, bufferSize, "Assert: "); break; nuclear@3: case Log_Text: buffer[0] = 0; addNewline = false; break; nuclear@3: case Log_DebugText: buffer[0] = 0; addNewline = false; break; nuclear@3: default: nuclear@3: buffer[0] = 0; nuclear@3: addNewline = false; nuclear@3: break; nuclear@3: } nuclear@3: nuclear@3: UPInt prefixLength = OVR_strlen(buffer); nuclear@3: char *buffer2 = buffer + prefixLength; nuclear@3: OVR_vsprintf(buffer2, bufferSize - prefixLength, fmt, argList); nuclear@3: nuclear@3: if (addNewline) nuclear@3: OVR_strcat(buffer, bufferSize, "\n"); nuclear@3: } nuclear@3: nuclear@3: nuclear@3: void Log::DefaultLogOutput(const char* formattedText, bool debug) nuclear@3: { nuclear@3: nuclear@3: #if defined(OVR_OS_WIN32) nuclear@3: // Under Win32, output regular messages to console if it exists; debug window otherwise. nuclear@3: static DWORD dummyMode; nuclear@3: static bool hasConsole = (GetStdHandle(STD_OUTPUT_HANDLE) != INVALID_HANDLE_VALUE) && nuclear@3: (GetConsoleMode(GetStdHandle(STD_OUTPUT_HANDLE), &dummyMode)); nuclear@3: nuclear@3: if (!hasConsole || debug) nuclear@3: { nuclear@3: ::OutputDebugStringA(formattedText); nuclear@3: } nuclear@3: else nuclear@3: { nuclear@3: fputs(formattedText, stdout); nuclear@3: } nuclear@3: nuclear@3: #elif defined(OVR_OS_ANDROID) nuclear@3: __android_log_write(ANDROID_LOG_INFO, "OVR", formattedText); nuclear@3: nuclear@3: #else nuclear@3: fputs(formattedText, stdout); nuclear@3: nuclear@3: #endif nuclear@3: nuclear@3: // Just in case. nuclear@3: OVR_UNUSED2(formattedText, debug); nuclear@3: } nuclear@3: nuclear@3: nuclear@3: //static nuclear@3: void Log::SetGlobalLog(Log *log) nuclear@3: { nuclear@3: OVR_GlobalLog = log; nuclear@3: } nuclear@3: //static nuclear@3: Log* Log::GetGlobalLog() nuclear@3: { nuclear@3: // No global log by default? nuclear@3: // if (!OVR_GlobalLog) nuclear@3: // OVR_GlobalLog = GetDefaultLog(); nuclear@3: return OVR_GlobalLog; nuclear@3: } nuclear@3: nuclear@3: //static nuclear@3: Log* Log::GetDefaultLog() nuclear@3: { nuclear@3: // Create default log pointer statically so that it can be used nuclear@3: // even during startup. nuclear@3: static Log defaultLog; nuclear@3: return &defaultLog; nuclear@3: } nuclear@3: nuclear@3: nuclear@3: //----------------------------------------------------------------------------------- nuclear@3: // ***** Global Logging functions nuclear@3: nuclear@3: #define OVR_LOG_FUNCTION_IMPL(Name) \ nuclear@3: void Log##Name(const char* fmt, ...) \ nuclear@3: { \ nuclear@3: if (OVR_GlobalLog) \ nuclear@3: { \ nuclear@3: va_list argList; va_start(argList, fmt); \ nuclear@3: OVR_GlobalLog->LogMessageVarg(Log_##Name, fmt, argList); \ nuclear@3: va_end(argList); \ nuclear@3: } \ nuclear@3: } nuclear@3: nuclear@3: OVR_LOG_FUNCTION_IMPL(Text) nuclear@3: OVR_LOG_FUNCTION_IMPL(Error) nuclear@3: nuclear@3: #ifdef OVR_BUILD_DEBUG nuclear@3: OVR_LOG_FUNCTION_IMPL(DebugText) nuclear@3: OVR_LOG_FUNCTION_IMPL(Debug) nuclear@3: OVR_LOG_FUNCTION_IMPL(Assert) nuclear@3: #endif nuclear@3: nuclear@3: } // OVR