#include "Log.h" #include "bx/handlealloc.h" #include "bx/hash.h" #include "bx/timer.h" #include #define WIN32_LEAN_AND_MEAN #include "Windows.h" #include "Instance.h" #define ESC "\x1B[" #define YELLOW ESC "33m" #define RED ESC "31m" #define END ESC "39m" namespace { char LineBuffer[LogInternal::MaxLineSize]{0}; char OutBuffer[LogInternal::MaxLineSize]{0}; char OutBufferUI[LogInternal::MaxLineSize]{0}; bx::HandleHashMapT<1024> OnceMap; LogHistory History; constexpr char LogFormat[]{"%s\n"}; constexpr char WarnFormat[]{YELLOW "%s" END "\n"}; constexpr char ErrorFormat[]{RED "%s" END "\n"}; } // namespace void Log(ELogType logType, const char* file, uint32_t line, const char* format, ...) { const char* LineFormat = LogFormat; if (logType == ELogType::Warn) LineFormat = WarnFormat; if (logType == ELogType::Error) LineFormat = ErrorFormat; va_list args; va_start(args, format); bx::snprintf(LineBuffer, sizeof(LineBuffer), LineFormat, format); bx::vprintf(LineBuffer, args); bx::vsnprintf(OutBuffer, sizeof(OutBuffer), LineBuffer, args); bx::vsnprintf(OutBufferUI, sizeof(OutBufferUI), format, args); va_end(args); OutputDebugStringA(OutBuffer); bx::strCopy(&History.LogBuffer[History.WriteIdx * LogInternal::MaxLineSize], LogInternal::MaxLineSize, OutBufferUI); History.WriteTime[History.WriteIdx] = bx::getHPCounter(); History.WriteType[History.WriteIdx] = logType; bx::strCopy(&History.FileBuffer[History.WriteIdx * LogInternal::MaxLineSize], LogInternal::MaxLineSize, file); History.LineBuffer[History.WriteIdx] = line; ++History.WriteIdx; if (History.WriteIdx >= LogInternal::LogHistorySize) History.WriteIdx = 0; } bool WasLogged(ELogType logType, const char* file, uint32_t line, const char* format) { bx::HashCrc32 hasher; hasher.begin(); hasher.add(file); hasher.add(line); hasher.add(logType); hasher.add(format); uint32_t hash = hasher.end(); if (OnceMap.find(hash) != bx::kInvalidHandle) return true; OnceMap.insert(hash, {}); return false; } LogHistory& GetLogHistory() { return History; }