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