//////////////////////////////////////////////////////////// //~ Log event types //- Event Struct(P_LogEvent) { /* Msg lifetime is only as long as callback duration */ String msg; i32 level; P_DateTime datetime; i64 time_ns; /* These will be zeroed if P_IncludeLogSourceLocation is disabled */ String file; i32 line; }; //- Callback #define P_LogEventCallbackFuncDef(name, log_event_arg) void name(P_LogEvent log_event_arg) typedef P_LogEventCallbackFuncDef(P_LogEventCallbackFunc, log_event); Struct(LogEventCallback) { P_LogEventCallbackFunc *func; LogEventCallback *next; i32 level; }; //////////////////////////////////////////////////////////// //~ Logging levels #define P_LogLevel(l) (l <= P_LogLevel_CompTime) /* Log level configuration */ #ifndef P_LogLevel_CompTime # if RtcIsEnabled || ProfilingIsEnabled # define P_LogLevel_CompTime P_LogLevel_Debug # else # define P_LogLevel_CompTime P_LogLevel_Info # endif #endif /* Source location configuration */ #ifndef P_IncludeLogSourceLocation # define P_IncludeLogSourceLocation (DebinfoEnabled) #endif #define P_LogLevel_None -1 #define P_LogLevel_Critical 0 #define P_LogLevel_Error 1 #define P_LogLevel_Warning 2 #define P_LogLevel_Success 3 #define P_LogLevel_Info 4 #define P_LogLevel_Debug 5 #define P_LogLevel_Count 6 //////////////////////////////////////////////////////////// //~ State types Struct(P_SharedLogState) { Atomic32 initialized; Mutex callbacks_mutex; Arena *callbacks_arena; LogEventCallback *first_callback; LogEventCallback *last_callback; P_File file; b32 file_valid; } P_shared_log_state; //////////////////////////////////////////////////////////// //~ Log level types Struct(P_LogLevelSettings) { String shorthand; u32 color; }; Global Readonly P_LogLevelSettings P_log_settings[P_LogLevel_Count] = { [P_LogLevel_Critical] = { LitNoCast("CRITICAL"), Color_Purple }, [P_LogLevel_Error] = { LitNoCast("ERROR"), Color_Red }, [P_LogLevel_Warning] = { LitNoCast("WARNING"), Color_Yellow }, [P_LogLevel_Success] = { LitNoCast("SUCCESS"), Color_Green }, [P_LogLevel_Info] = { LitNoCast("INFO"), Color_White }, [P_LogLevel_Debug] = { LitNoCast("DEBUG"), Color_Blue } }; //////////////////////////////////////////////////////////// //~ Startup void P_StartupLog(void); //////////////////////////////////////////////////////////// //~ Logging macros #if P_LogLevel(P_LogLevel_Critical) # if P_IncludeLogSourceLocation # define P_LogCritical(msg) P_Log_(P_LogLevel_Critical, Lit(__FILE__), __LINE__, msg) # define P_LogCriticalF(fmt_lit, ...) P_LogF_(P_LogLevel_Critical, Lit(__FILE__), __LINE__, Lit(fmt_lit) , ## __VA_ARGS__, FmtEnd) # else # define P_LogCritical(msg) P_Log_(P_LogLevel_Critical, msg) # define P_LogCriticalF(fmt_lit, ...) P_LogF_(P_LogLevel_Critical, Lit(fmt_lit) , ## __VA_ARGS__, FmtEnd) # endif #else # define P_LogCritical(msg) # define P_LogCriticalF(...) #endif #if P_LogLevel(P_LogLevel_Error) # if P_IncludeLogSourceLocation # define P_LogError(msg) P_Log_(P_LogLevel_Error, Lit(__FILE__), __LINE__, msg) # define P_LogErrorF(fmt_lit, ...) P_LogF_(P_LogLevel_Error, Lit(__FILE__), __LINE__, Lit(fmt_lit) , ## __VA_ARGS__, FmtEnd) # else # define P_LogError(msg) P_Log_(P_LogLevel_Error, msg) # define P_LogErrorF(fmt_lit, ...) P_LogF_(P_LogLevel_Error, Lit(fmt_lit) , ## __VA_ARGS__, FmtEnd) # endif #else # define P_LogError(msg) # define P_LogErrorF(...) #endif #if P_LogLevel(P_LogLevel_Warning) # if P_IncludeLogSourceLocation # define P_LogWarning(msg) P_Log_(P_LogLevel_Warning, Lit(__FILE__), __LINE__, msg) # define P_LogWarningF(fmt_lit, ...) P_LogF_(P_LogLevel_Warning, Lit(__FILE__), __LINE__, Lit(fmt_lit) , ## __VA_ARGS__, FmtEnd) # else # define P_LogWarning(msg) P_Log_(P_LogLevel_Warning, msg) # define P_LogWarningF(fmt_lit, ...) P_LogF_(P_LogLevel_Warning, Lit(fmt_lit) , ## __VA_ARGS__, FmtEnd) # endif #else # define P_LogWarning(msg) # define P_LogWarningF(...) #endif #if P_LogLevel(P_LogLevel_Success) # if P_IncludeLogSourceLocation # define P_LogSuccess(msg) P_Log_(P_LogLevel_Success, Lit(__FILE__), __LINE__, msg) # define P_LogSuccessF(fmt_lit, ...) P_LogF_(P_LogLevel_Success, Lit(__FILE__), __LINE__, Lit(fmt_lit) , ## __VA_ARGS__, FmtEnd) # else # define P_LogSuccess(msg) P_Log_(P_LogLevel_Success, msg) # define P_LogSuccessF(fmt_lit, ...) P_LogF_(P_LogLevel_Success, Lit(fmt_lit) , ## __VA_ARGS__, FmtEnd) # endif #else # define P_LogSuccess(msg) # define P_LogSuccessF(...) #endif #if P_LogLevel(P_LogLevel_Info) # if P_IncludeLogSourceLocation # define P_LogInfo(msg) P_Log_(P_LogLevel_Info, Lit(__FILE__), __LINE__, msg) # define P_LogInfoF(fmt_lit, ...) P_LogF_(P_LogLevel_Info, Lit(__FILE__), __LINE__, Lit(fmt_lit) , ## __VA_ARGS__, FmtEnd) # else # define P_LogInfo(msg) P_Log_(P_LogLevel_Info, msg) # define P_LogInfoF(fmt_lit, ...) P_LogF_(P_LogLevel_Info, Lit(fmt_lit) , ## __VA_ARGS__, FmtEnd) # endif #else # define P_LogInfo(msg) # define P_LogInfoF(...) #endif #if P_LogLevel(P_LogLevel_Debug) # if P_IncludeLogSourceLocation # define P_LogDebug(msg) P_Log_(P_LogLevel_Debug, Lit(__FILE__), __LINE__, msg) # define P_LogDebugF(fmt_lit, ...) P_LogF_(P_LogLevel_Debug, Lit(__FILE__), __LINE__, Lit(fmt_lit) , ## __VA_ARGS__, FmtEnd) # else # define P_LogDebug(msg) P_Log_(P_LogLevel_Debug, msg) # define P_LogDebugF(fmt_lit, ...) P_LogF_(P_LogLevel_Debug, Lit(fmt_lit) , ## __VA_ARGS__, FmtEnd) # endif #else # define P_LogDebug(msg) # define P_LogDebugF(...) #endif //////////////////////////////////////////////////////////// //~ Callback registration void P_RegisterLogCallback(P_LogEventCallbackFunc *func, i32 level); //////////////////////////////////////////////////////////// //~ Raw log operations /* NOTE: Calling these functions rather than using the logging macros may result in logs that are compiled regardless of log level. */ void P_LogAppend_(String msg); void P_LogPanic_(String msg); #if P_IncludeLogSourceLocation void P_LogFV_(i32 level, String file, u32 line, String fmt, va_list args); #else void P_LogFV_(i32 level, String fmt, va_list args); #endif #if P_IncludeLogSourceLocation void P_LogF_(i32 level, String file, u32 line, String fmt, ...); #else void P_LogF_(i32 level, String fmt, ...); #endif #if P_IncludeLogSourceLocation void P_Log_(i32 level, String file, u32 line, String msg); #else void P_Log_(i32 level, String msg); #endif