From 9fc7445e6b7f01f5cae2ee6f114cedffd59441e7 Mon Sep 17 00:00:00 2001 From: jacob Date: Sun, 2 Nov 2025 19:31:49 -0600 Subject: [PATCH] move logging to base layer --- src/app/app.c | 28 +-- src/asset_cache/asset_cache.c | 2 +- src/base/base_file.h | 35 +++ src/base/base_inc.h | 2 + src/base/base_log.h | 145 ++++++++++++ src/base/base_time.h | 19 ++ src/base/base_win32/base_win32.c | 7 +- src/base/base_win32/base_win32_file.c | 163 +++++++++++++ src/base/base_win32/base_win32_inc.h | 3 + src/base/base_win32/base_win32_job.c | 4 +- src/base/base_win32/base_win32_log.c | 151 ++++++++++++ src/base/base_win32/base_win32_log.h | 21 ++ src/base/base_win32/base_win32_time.c | 20 ++ src/font/font.c | 4 +- src/net/net.c | 6 +- src/platform/platform.h | 26 +-- src/platform/platform.lay | 5 - src/platform/platform_log.c | 232 ------------------- src/platform/platform_log.h | 230 ------------------ src/platform/platform_win32/platform_win32.c | 34 +-- src/platform/platform_win32/platform_win32.h | 2 +- src/pp/pp.c | 127 ++++------ src/pp/pp.h | 11 +- src/pp/pp_step.c | 12 +- src/sound/sound.c | 6 +- src/window/window_win32/window_win32.c | 2 +- 26 files changed, 660 insertions(+), 637 deletions(-) create mode 100644 src/base/base_file.h create mode 100644 src/base/base_log.h create mode 100644 src/base/base_time.h create mode 100644 src/base/base_win32/base_win32_file.c create mode 100644 src/base/base_win32/base_win32_log.c create mode 100644 src/base/base_win32/base_win32_log.h create mode 100644 src/base/base_win32/base_win32_time.c delete mode 100644 src/platform/platform_log.c delete mode 100644 src/platform/platform_log.h diff --git a/src/app/app.c b/src/app/app.c index 9d90e640..a88d8006 100644 --- a/src/app/app.c +++ b/src/app/app.c @@ -201,14 +201,14 @@ void Startup(void) String logfile_path = CatString(temp.arena, logfile_dir, logfile_name); P_MkDir(logfile_dir); - P_LogStartup(logfile_path); - P_LogInfoF("Start of logs"); + LogStartup(logfile_path); + LogInfoF("Start of logs"); EndTempArena(temp); } - P_LogInfoF("App started with args \"%F\" (%F parsed)", FmtString(args_str), FmtUint(args.count)); + LogInfoF("App started with args \"%F\" (%F parsed)", FmtString(args_str), FmtUint(args.count)); for (AppArg *arg = args.first; arg; arg = arg->next) { - P_LogInfoF("Parsed arg: key = \"%F\", value = \"%F\"", FmtString(arg->key), FmtString(arg->value)); + LogInfoF("Parsed arg: key = \"%F\", value = \"%F\"", FmtString(arg->key), FmtString(arg->value)); } #endif @@ -219,19 +219,19 @@ void Startup(void) P_WindowSettings window_settings = ZI; String settings_path = CatAppWritePath(temp.arena, settings_file_name); - P_LogInfoF("Looking for settings file \"%F\"", FmtString(settings_path)); + LogInfoF("Looking for settings file \"%F\"", FmtString(settings_path)); if (P_IsFile(settings_path)) { - P_LogInfoF("Settings file found"); + LogInfoF("Settings file found"); P_File settings_file = P_OpenFileRead(settings_path); String file_data = P_ReadFile(temp.arena, settings_file); P_CloseFile(settings_file); - P_LogInfoF("Deserializing settings file data: %F", FmtString(file_data)); + LogInfoF("Deserializing settings file data: %F", FmtString(file_data)); String error = ZI; P_WindowSettings *deser = SETTINGS_WindowSettingsFromString(temp.arena, file_data, &error); if (error.len > 0) { - P_LogInfoF("Failed to load settings file with error - %F", FmtString(error)); + LogInfoF("Failed to load settings file with error - %F", FmtString(error)); String msg = StringF(temp.arena, "Failed to loading settings file \"%F\":\n" "------------\n" @@ -242,12 +242,12 @@ void Startup(void) FmtString(error)); Panic(msg); } - P_LogInfoF("Settings file loaded successfully"); + LogInfoF("Settings file loaded successfully"); window_settings = *deser; } else { - P_LogInfoF("Settings file not found, loading default"); + LogInfoF("Settings file not found, loading default"); window_settings = GetDefaultAppWindowSettings(window); } PushStringToBuff(StringFromArray(window_settings.title), Lit(WINDOW_TITLE)); @@ -287,13 +287,13 @@ void Startup(void) P_WindowSettings settings = P_GetWindowSettings(window); String str = SETTINGS_StringFromWindowSettings(temp.arena, &settings); - P_LogInfoF("Serialized window settings: %F", FmtString(str)); + LogInfoF("Serialized window settings: %F", FmtString(str)); - P_LogInfoF("Writing settings file to path \"%F\"", FmtString(window_settings_path)); + LogInfoF("Writing settings file to path \"%F\"", FmtString(window_settings_path)); P_File settings_file = P_OpenFileWrite(window_settings_path); P_WriteFile(settings_file, str); P_CloseFile(settings_file); - P_LogInfoF("Finished writing settings file"); + LogInfoF("Finished writing settings file"); EndTempArena(temp); } @@ -303,6 +303,6 @@ void Startup(void) P_ReleaseWindow(window); #endif - //P_LogInfoF("Program exited normally"); + //LogInfoF("Program exited normally"); EndScratch(scratch); } diff --git a/src/asset_cache/asset_cache.c b/src/asset_cache/asset_cache.c index 453769a5..e97abeca 100644 --- a/src/asset_cache/asset_cache.c +++ b/src/asset_cache/asset_cache.c @@ -129,7 +129,7 @@ AC_Asset *AC_TouchCache(String key, u64 hash, b32 *is_first_touch) AC_CloseStore(&store); } /* Initialize asset data */ - P_LogInfoF("Inserting asset cache entry for \"%F\"", FmtString(key)); + LogInfoF("Inserting asset cache entry for \"%F\"", FmtString(key)); *asset = (AC_Asset) { .status = ASSET_STATUS_UNINITIALIZED, .hash = hash, diff --git a/src/base/base_file.h b/src/base/base_file.h new file mode 100644 index 00000000..98558a92 --- /dev/null +++ b/src/base/base_file.h @@ -0,0 +1,35 @@ +//////////////////////////////////////////////////////////// +//~ File types + +Enum(OS_FileFlag) +{ + OS_FileFlag_None = 0, + OS_FileFlag_Read = (1 << 0), + OS_FileFlag_Write = (1 << 1), + OS_FileFlag_Create = (1 << 2), +}; + +Struct(OS_File) +{ + u64 handle; +}; + +//////////////////////////////////////////////////////////// +//~ @hookdecl File system operations + +OS_File OS_OpenFile(String path, OS_FileFlag flags, i64 timeout_ns); +void OS_CloseFile(OS_File file); +String OS_ReadEntireFile(Arena *arena, OS_File file); +void OS_ClearWriteFile(OS_File file, String data); +void OS_DirContentsFromFullPath(Arena *arena, StringList *list, String path); +String OS_GetFullPath(Arena *arena, String path); +u64 OS_LastWriteTimestampFromPath(String path); + +//////////////////////////////////////////////////////////// +//~ @hookdecl Directory helpers + +b32 OS_FileOrDirExists(String path); +b32 OS_FileExists(String path); +b32 OS_DirExists(String path); +void OS_Mkdir(String path); +void OS_Rm(String path); diff --git a/src/base/base_inc.h b/src/base/base_inc.h index cfb356b4..c30846dc 100644 --- a/src/base/base_inc.h +++ b/src/base/base_inc.h @@ -11,6 +11,8 @@ # include "base_futex.h" # include "base_snc.h" # include "base_job.h" +# include "base_time.h" +# include "base_log.h" # include "base_uid.h" # include "base_string.h" # include "base_uni.h" diff --git a/src/base/base_log.h b/src/base/base_log.h new file mode 100644 index 00000000..a4f3b474 --- /dev/null +++ b/src/base/base_log.h @@ -0,0 +1,145 @@ +//////////////////////////////////////////////////////////// +//~ Log event types + +Struct(LogEvent) +{ + u64 id; + u64 level_id; + + DateTime datetime; + i64 time_ns; + + String msg; + i32 level; + + i32 thread_id; + i32 fiber_id; +}; + +Struct(LogEventsArray) +{ + u64 count; + LogEvent *logs; +}; + +//////////////////////////////////////////////////////////// +//~ Logging levels + +#define LogLevel(l) (l <= LogLevel_CompTime) + +/* Log level configuration */ +#ifndef LogLevel_CompTime +# if RtcIsEnabled || ProfilingIsEnabled +# define LogLevel_CompTime LogLevel_Debug +# else +# define LogLevel_CompTime LogLevel_Info +# endif +#endif + +#define LogLevel_None -1 +#define LogLevel_Critical 0 +#define LogLevel_Error 1 +#define LogLevel_Warning 2 +#define LogLevel_Success 3 +#define LogLevel_Info 4 +#define LogLevel_Debug 5 +#define LogLevel_Count 6 + +//////////////////////////////////////////////////////////// +//~ Log level types + +Struct(LogLevelSettings) +{ + String shorthand; +}; + +Global Readonly LogLevelSettings log_settings[LogLevel_Count] = { + [LogLevel_Critical] = { + LitNoCast("CRITICAL"), + }, + + [LogLevel_Error] = { + LitNoCast("ERROR"), + }, + + [LogLevel_Warning] = { + LitNoCast("WARNING"), + }, + + [LogLevel_Success] = { + LitNoCast("SUCCESS"), + }, + + [LogLevel_Info] = { + LitNoCast("INFO"), + }, + + [LogLevel_Debug] = { + LitNoCast("DEBUG"), + } +}; + +//////////////////////////////////////////////////////////// +//~ Compile-time logging macros + +#if LogLevel(LogLevel_Critical) +# define LogCritical(msg) Log_(LogLevel_Critical, msg) +# define LogCriticalF(fmt_lit, ...) LogF_(LogLevel_Critical, Lit(fmt_lit) , ## __VA_ARGS__, FmtEnd) +#else +# define LogCritical(msg) +# define LogCriticalF(...) +#endif + +#if LogLevel(LogLevel_Error) +# define LogError(msg) Log_(LogLevel_Error, msg) +# define LogErrorF(fmt_lit, ...) LogF_(LogLevel_Error, Lit(fmt_lit) , ## __VA_ARGS__, FmtEnd) +#else +# define LogError(msg) +# define LogErrorF(...) +#endif + +#if LogLevel(LogLevel_Warning) +# define LogWarning(msg) Log_(LogLevel_Warning, msg) +# define LogWarningF(fmt_lit, ...) LogF_(LogLevel_Warning, Lit(fmt_lit) , ## __VA_ARGS__, FmtEnd) +#else +# define LogWarning(msg) +# define LogWarningF(...) +#endif + +#if LogLevel(LogLevel_Success) +# define LogSuccess(msg) Log_(LogLevel_Success, msg) +# define LogSuccessF(fmt_lit, ...) LogF_(LogLevel_Success, Lit(fmt_lit) , ## __VA_ARGS__, FmtEnd) +#else +# define LogSuccess(msg) +# define LogSuccessF(...) +#endif + +#if LogLevel(LogLevel_Info) +# define LogInfo(msg) Log_(LogLevel_Info, msg) +# define LogInfoF(fmt_lit, ...) LogF_(LogLevel_Info, Lit(fmt_lit) , ## __VA_ARGS__, FmtEnd) +#else +# define LogInfo(msg) +# define LogInfoF(...) +#endif + +#if LogLevel(LogLevel_Debug) +# define LogDebug(msg) Log_(LogLevel_Debug, msg) +# define LogDebugF(fmt_lit, ...) LogF_(LogLevel_Debug, Lit(fmt_lit) , ## __VA_ARGS__, FmtEnd) +#else +# define LogDebug(msg) +# define LogDebugF(...) +#endif + +//////////////////////////////////////////////////////////// +//~ @hookdecl Init hooks + +void InitLogSystem(String logfile_path); + +//////////////////////////////////////////////////////////// +//~ @hookdecl Log hooks + +/* NOTE: Calling these functions rather than using the logging macros may result in logs that are compiled regardless of log level. */ + +void LogPanic(String msg); +void LogF_(i32 level, String fmt, ...); +LogEventsArray GetLogEvents(void); diff --git a/src/base/base_time.h b/src/base/base_time.h new file mode 100644 index 00000000..af550b38 --- /dev/null +++ b/src/base/base_time.h @@ -0,0 +1,19 @@ +//////////////////////////////////////////////////////////// +//~ Datetime types + +Struct(DateTime) +{ + u32 year; + u32 month; + u32 day_of_week; + u32 day; + u32 hour; + u32 minute; + u32 second; + u32 milliseconds; +}; + +//////////////////////////////////////////////////////////// +//~ @hookdecl DateTime hooks + +DateTime LocalDateTime(void); diff --git a/src/base/base_win32/base_win32.c b/src/base/base_win32/base_win32.c index c34b60ee..2a453f8b 100644 --- a/src/base/base_win32/base_win32.c +++ b/src/base/base_win32/base_win32.c @@ -63,6 +63,7 @@ void Echo(String msg) b32 Panic(String msg) { + LogPanic(msg); char msg_cstr[4096]; CstrFromStringToBuff(StringFromArray(msg_cstr), msg); { @@ -110,7 +111,7 @@ void TrueRand(String buffer) } //////////////////////////////////////////////////////////// -//~ Swap hooks +//~ @hookdef Swap hooks b32 IsSwappedIn(void) { @@ -335,6 +336,10 @@ i32 W32_Main(void) /* Init futex system */ InitFutexSystem(); + /* Init log system */ + /* FIXME: Remove hardcoded log path */ + InitLogSystem(Lit("log.log")); + /* Init resources */ { W32_FindEmbeddedDataCtx ctx = ZI; diff --git a/src/base/base_win32/base_win32_file.c b/src/base/base_win32/base_win32_file.c new file mode 100644 index 00000000..153e9627 --- /dev/null +++ b/src/base/base_win32/base_win32_file.c @@ -0,0 +1,163 @@ +//////////////////////////////////////////////////////////// +//~ @hookdef File system hooks + +OS_File OS_OpenFile(String path, OS_FileFlag flags, i64 timeout_ns) +{ + TempArena scratch = BeginScratchNoConflict(); + OS_File result = ZI; + wchar_t *path_wstr = WstrFromString(scratch.arena, path); + u32 share_mode = FILE_SHARE_READ; + u32 create_mode = OPEN_EXISTING; + u32 access_flags = 0; + if (flags & OS_FileFlag_Read) access_flags |= GENERIC_READ; + if (flags & OS_FileFlag_Write) access_flags |= GENERIC_WRITE; + if (flags & OS_FileFlag_Create) create_mode = OPEN_ALWAYS; + i32 timeout_ms = timeout_ns / 1000000; + i32 elapsed_ms = 0; + i32 delay_ms = 1; + HANDLE handle = INVALID_HANDLE_VALUE; + for (;;) + { + handle = CreateFileW(path_wstr, access_flags, share_mode, 0, create_mode, FILE_ATTRIBUTE_NORMAL, 0); + if (handle == INVALID_HANDLE_VALUE && elapsed_ms < timeout_ms && GetLastError() == ERROR_SHARING_VIOLATION) + { + Sleep(delay_ms); + elapsed_ms += delay_ms; + delay_ms = MinI32(delay_ms * 2, 1024); + } + else + { + break; + } + } + EndScratch(scratch); + result.handle = (u64)handle; + return result; +} + +void OS_CloseFile(OS_File file) +{ + HANDLE handle = (HANDLE)file.handle; + CloseHandle(handle); +} + +String OS_ReadEntireFile(Arena *arena, OS_File file) +{ + String result = ZI; + HANDLE handle = (HANDLE)file.handle; + u32 chunk_size = Kibi(64); + result.text = PushDry(arena, u8); + for (;;) + { + u8 *chunk = PushStructsNoZero(arena, u8, chunk_size); + u32 chunk_bytes_read = 0; + ReadFile(handle, chunk, chunk_size, &chunk_bytes_read, 0); + result.len += chunk_bytes_read; + if (chunk_bytes_read < chunk_size) + { + PopStructsNoCopy(arena, u8, chunk_size - chunk_bytes_read); + break; + } + } + return result; +} + +void OS_ClearWriteFile(OS_File file, String data) +{ + HANDLE handle = (HANDLE)file.handle; + SetFilePointer(handle, 0, 0, FILE_BEGIN); + SetEndOfFile(handle); + WriteFile(handle, data.text, data.len, 0, 0); +} + +void OS_DirContentsFromFullPath(Arena *arena, StringList *list, String path) +{ + TempArena scratch = BeginScratch(arena); + WIN32_FIND_DATAW find_data = ZI; + String filter = StringF(scratch.arena, "%F\\*", FmtString(path)); + wchar_t *filter_wstr = WstrFromString(scratch.arena, filter); + HANDLE find_handle = FindFirstFileExW(filter_wstr, FindExInfoStandard, &find_data, FindExSearchNameMatch, 0, FIND_FIRST_EX_CASE_SENSITIVE | FIND_FIRST_EX_LARGE_FETCH); + b32 found = find_handle && find_handle != INVALID_HANDLE_VALUE; + while (found) + { + String file_name = StringFromWstrNoLimit(arena, find_data.cFileName); + if (!EqString(file_name, Lit(".")) && !EqString(file_name, Lit(".."))) + { + PushStringToList(arena, list, file_name); + } + found = FindNextFileW(find_handle, &find_data); + } + EndScratch(scratch); +} + +String OS_GetFullPath(Arena *arena, String path) +{ + TempArena scratch = BeginScratch(arena); + wchar_t *rel_path_wstr = WstrFromString(scratch.arena, path); + wchar_t full_path_wstr_buff[4096]; + GetFullPathNameW(rel_path_wstr, countof(full_path_wstr_buff), full_path_wstr_buff, 0); + String res = StringFromWstr(arena, full_path_wstr_buff, countof(full_path_wstr_buff)); + EndScratch(scratch); + return res; +} + +u64 OS_LastWriteTimestampFromPath(String path) +{ + TempArena scratch = BeginScratchNoConflict(); + u64 result = 0; + WIN32_FILE_ATTRIBUTE_DATA a = ZI; + wchar_t *path_wstr = WstrFromString(scratch.arena, path); + if (GetFileAttributesExW(path_wstr, GetFileExInfoStandard, &a)) + { + result = ((ULONGLONG)a.ftLastWriteTime.dwHighDateTime << 32) | + (ULONGLONG)a.ftLastWriteTime.dwLowDateTime; + } + EndScratch(scratch); + return result; +} + +//////////////////////////////////////////////////////////// +//~ @hookdef Directory helper hooks + +b32 OS_FileOrDirExists(String path) +{ + TempArena scratch = BeginScratchNoConflict(); + wchar_t *path_wstr = WstrFromString(scratch.arena, path); + DWORD attributes = GetFileAttributesW(path_wstr); + EndScratch(scratch); + return attributes != INVALID_FILE_ATTRIBUTES; +} + +b32 OS_FileExists(String path) +{ + TempArena scratch = BeginScratchNoConflict(); + wchar_t *path_wstr = WstrFromString(scratch.arena, path); + DWORD attributes = GetFileAttributesW(path_wstr); + EndScratch(scratch); + return attributes != INVALID_FILE_ATTRIBUTES && !(attributes & FILE_ATTRIBUTE_DIRECTORY); +} + +b32 OS_DirExists(String path) +{ + TempArena scratch = BeginScratchNoConflict(); + wchar_t *path_wstr = WstrFromString(scratch.arena, path); + DWORD attributes = GetFileAttributesW(path_wstr); + EndScratch(scratch); + return attributes != INVALID_FILE_ATTRIBUTES && (attributes & FILE_ATTRIBUTE_DIRECTORY); +} + +void OS_Mkdir(String path) +{ + TempArena scratch = BeginScratchNoConflict(); + wchar_t *path_wstr = WstrFromString(scratch.arena, path); + CreateDirectoryW(path_wstr, 0); + EndScratch(scratch); +} + +void OS_Rm(String path) +{ + TempArena scratch = BeginScratchNoConflict(); + wchar_t *path_wstr = WstrFromString(scratch.arena, path); + DeleteFile(path_wstr); + EndScratch(scratch); +} diff --git a/src/base/base_win32/base_win32_inc.h b/src/base/base_win32/base_win32_inc.h index c2aaa4ac..2b2d181a 100644 --- a/src/base/base_win32/base_win32_inc.h +++ b/src/base/base_win32/base_win32_inc.h @@ -1,7 +1,10 @@ //- Api #include "base_win32.h" #include "base_win32_job.h" +#include "base_win32_log.h" //- Impl #include "base_win32.c" #include "base_win32_job.c" +#include "base_win32_time.c" +#include "base_win32_log.c" diff --git a/src/base/base_win32/base_win32_job.c b/src/base/base_win32/base_win32_job.c index 4c0a0680..fcf8ba39 100644 --- a/src/base/base_win32/base_win32_job.c +++ b/src/base/base_win32/base_win32_job.c @@ -47,7 +47,7 @@ DWORD WINAPI W32_Win32ThreadProc(LPVOID vt) /* Set thread name */ SetThreadDescription(GetCurrentThread(), thread_name_desc_wstr); - //P_LogInfoF("New thread \"%F\" created with ID %F", FmtString(StringFromCstrNoLimit(t->thread_name_cstr)), FmtUint(ThreadId())); + //LogInfoF("New thread \"%F\" created with ID %F", FmtString(StringFromCstrNoLimit(t->thread_name_cstr)), FmtUint(ThreadId())); /* Enter thread entry point */ t->entry_point(t->thread_udata); @@ -65,7 +65,7 @@ W32_Thread *W32_StartThread(W32_ThreadFunc *entry_point, void *thread_udata, Str TempArena scratch = BeginScratchNoConflict(); Arena *perm = PermArena(); Assert(entry_point != 0); - //P_LogInfoF("Creating thread \"%F\"", FmtString(thread_name)); + //LogInfoF("Creating thread \"%F\"", FmtString(thread_name)); W32_Thread *t = PushStruct(perm, W32_Thread); t->thread_name = PushString(perm, thread_name); diff --git a/src/base/base_win32/base_win32_log.c b/src/base/base_win32/base_win32_log.c new file mode 100644 index 00000000..1a7afbfe --- /dev/null +++ b/src/base/base_win32/base_win32_log.c @@ -0,0 +1,151 @@ +W32_SharedLogState W32_shared_log_state = ZI; + +//////////////////////////////////////////////////////////// +//~ @hookdef Init hooks + +void InitLogSystem(String logfile_path) +{ + __prof; + W32_SharedLogState *g = &W32_shared_log_state; + g->logs_arena = AcquireArena(Gibi(64)); + g->log_msgs_arena = AcquireArena(Gibi(64)); + g->readable_log_events = PushDry(g->logs_arena, LogEvent); + if (logfile_path.len > 0) + { + TempArena scratch = BeginScratchNoConflict(); + { + wchar_t *path_wstr = WstrFromString(scratch.arena, logfile_path); + g->logfile = CreateFileW(path_wstr, + FILE_APPEND_DATA, + FILE_SHARE_READ | FILE_SHARE_WRITE, + 0, + CREATE_ALWAYS, + FILE_ATTRIBUTE_NORMAL, + 0); + } + EndScratch(scratch); + } + Atomic32Set(&g->initialized, 1); +} + +//////////////////////////////////////////////////////////// +//~ Log + +void W32_Log(i32 level, String msg) +{ + __prof; + W32_SharedLogState *g = &W32_shared_log_state; + TempArena scratch = BeginScratchNoConflict(); + if (Atomic32Fetch(&g->initialized)) + { + LogLevelSettings settings = log_settings[level]; + if (level < 0 || level >= LogLevel_Count) + { + Panic(Lit("Invalid log level")); + } + __profmsg((char *)msg.text, msg.len, settings.color); + + /* FIXME: Log actual thread & fiber id */ + DateTime datetime = LocalDateTime(); + i64 now_ns = TimeNs(); + i32 thread_id = GetCurrentThreadId(); + i32 fiber_id = FiberId(); + + + //- Log message to file + /* TODO: Log asynchronously */ + { + String shorthand = settings.shorthand; + String msg_formatted = StringF( + scratch.arena, + "[%F:%F:%F.%F] |%F| <%F> [%F] %F\n", + + /* Time */ + FmtUintZ(datetime.hour, 2), + FmtUintZ(datetime.minute, 2), + FmtUintZ(datetime.second, 2), + FmtUintZ(datetime.milliseconds, 3), + + /* Thread id */ + FmtUintZ(thread_id, 5), + + /* Fiber id */ + FmtUintZ(fiber_id, 5), + + /* Level */ + FmtString(shorthand), + + /* Message */ + FmtString(msg) + ); + + WriteFile(g->logfile, msg_formatted.text, msg_formatted.len, 0, 0); + } + + //- Log message to queue + /* TODO: Log asynchronously */ + LockTicketMutex(&g->logs_tm); + { + /* Get staged data */ + LogEvent *ev = PushStruct(g->logs_arena, LogEvent); + ev->msg = PushString(g->log_msgs_arena, msg); + ev->datetime = datetime; + ev->time_ns = now_ns; + ev->level = level; + ev->thread_id = thread_id; + ev->fiber_id = fiber_id; + ev->id = g->logs_count++; + ev->level_id = g->log_level_counts[level]++; + Atomic64Set(&g->readable_logs_count, g->logs_count); + } + UnlockTicketMutex(&g->logs_tm); + } + EndScratch(scratch); +} + +//////////////////////////////////////////////////////////// +//~ @hookdef Log hooks + +/* Panic log function is separate to enforce zero side effects other than + * immediately writing to log file. */ +void LogPanic(String msg) +{ + W32_SharedLogState *g = &W32_shared_log_state; + if (Atomic32Fetch(&g->initialized)) + { + String beg = Lit("******** PANICKING ********\n"); + String end = Lit("\n***************************\n"); + WriteFile(g->logfile, beg.text, beg.len, 0, 0); + WriteFile(g->logfile, msg.text, msg.len, 0, 0); + WriteFile(g->logfile, end.text, end.len, 0, 0); + } +} + +void LogF_(i32 level, String fmt, ...) +{ + W32_SharedLogState *g = &W32_shared_log_state; + if (Atomic32Fetch(&g->initialized)) + { + TempArena scratch = BeginScratchNoConflict(); + va_list args; + va_start(args, fmt); + { + String msg = FormatStringV(scratch.arena, fmt, args); + W32_Log(level, msg); + } + va_end(args); + EndScratch(scratch); + } +} + +LogEventsArray GetLogEvents(void) +{ + W32_SharedLogState *g = &W32_shared_log_state; + LogEventsArray result = ZI; + result.count = Atomic64Fetch(&g->readable_logs_count); + if (result.count > 0) + { + result.logs = g->readable_log_events; + } + return result; +} diff --git a/src/base/base_win32/base_win32_log.h b/src/base/base_win32/base_win32_log.h new file mode 100644 index 00000000..ece434b9 --- /dev/null +++ b/src/base/base_win32/base_win32_log.h @@ -0,0 +1,21 @@ +//////////////////////////////////////////////////////////// +//~ State types + +Struct(W32_SharedLogState) +{ + HANDLE logfile; + Atomic32 initialized; + + TicketMutex logs_tm; + Arena *log_msgs_arena; + Arena *logs_arena; + u64 logs_count; + u64 log_level_counts[LogLevel_Count]; + LogEvent *readable_log_events; + Atomic64 readable_logs_count; +} extern W32_shared_log_state; + +//////////////////////////////////////////////////////////// +//~ Log + +void W32_Log(i32 level, String msg); diff --git a/src/base/base_win32/base_win32_time.c b/src/base/base_win32/base_win32_time.c new file mode 100644 index 00000000..890cfd8c --- /dev/null +++ b/src/base/base_win32/base_win32_time.c @@ -0,0 +1,20 @@ +//////////////////////////////////////////////////////////// +//~ @hookdef DateTime hooks + +DateTime LocalDateTime(void) +{ + DateTime result = ZI; + { + SYSTEMTIME lt; + GetLocalTime(<); + result.year = lt.wYear; + result.month = lt.wMonth; + result.day_of_week = lt.wDayOfWeek; + result.day = lt.wDay; + result.hour = lt.wHour; + result.minute = lt.wMinute; + result.second = lt.wSecond; + result.milliseconds = lt.wMilliseconds; + } + return result; +} diff --git a/src/font/font.c b/src/font/font.c index a2ce0986..4fdd1854 100644 --- a/src/font/font.c +++ b/src/font/font.c @@ -30,7 +30,7 @@ JobDef(F_Load, sig, _) f32 point_size = sig->point_size; AC_Asset *asset = sig->asset; - P_LogInfoF("Loading font \"%F\" (point size %F)", FmtString(name), FmtFloat((f64)point_size)); + LogInfoF("Loading font \"%F\" (point size %F)", FmtString(name), FmtFloat((f64)point_size)); i64 start_ns = TimeNs(); Assert(StringEndsWith(name, Lit(".ttf"))); @@ -153,7 +153,7 @@ JobDef(F_Load, sig, _) font->lookup[codepoint] = decoded.cache_indices[i]; } - P_LogSuccessF("Loaded font \"%F\" (point size %F) in %F seconds", FmtString(name), FmtFloat((f64)point_size), FmtFloat(SecondsFromNs(TimeNs() - start_ns))); + LogSuccessF("Loaded font \"%F\" (point size %F) in %F seconds", FmtString(name), FmtFloat((f64)point_size), FmtFloat(SecondsFromNs(TimeNs() - start_ns))); AC_MarkReady(asset, font); EndScratch(scratch); diff --git a/src/net/net.c b/src/net/net.c index b6239bd7..79a57b54 100644 --- a/src/net/net.c +++ b/src/net/net.c @@ -632,7 +632,7 @@ N_EventList N_BeginUpdate(Arena *arena, N_Host *host) /* A foreign host is trying to connect to us */ if (!channel->valid) { - P_LogInfoF("Host received conection attempt from %F", FmtString(P_StringFromAddress(scratch.arena, address))); + LogInfoF("Host received conection attempt from %F", FmtString(P_StringFromAddress(scratch.arena, address))); /* TODO: Verify that some per-host uuid isn't present in a rolling window to prevent reconnects right after a disconnect? */ channel = N_AcquireChannel(host, address); } @@ -646,7 +646,7 @@ N_EventList N_BeginUpdate(Arena *arena, N_Host *host) /* We successfully connected to a foreign host and they are ready to receive messages */ if (channel->valid && !channel->connected) { - P_LogInfoF("Host received connection from %F", FmtString(P_StringFromAddress(scratch.arena, address))); + LogInfoF("Host received connection from %F", FmtString(P_StringFromAddress(scratch.arena, address))); N_Event *event = N_PushEvent(arena, &events); event->kind = N_EventKind_ChannelOpened; event->channel_id = channel->id; @@ -659,7 +659,7 @@ N_EventList N_BeginUpdate(Arena *arena, N_Host *host) /* A foreign host disconnected from us */ if (channel->valid) { - P_LogInfoF("Host received disconnection from %F", FmtString(P_StringFromAddress(scratch.arena, address))); + LogInfoF("Host received disconnection from %F", FmtString(P_StringFromAddress(scratch.arena, address))); N_Event *event = N_PushEvent(arena, &events); event->kind = N_EventKind_ChannelClosed; event->channel_id = channel->id; diff --git a/src/platform/platform.h b/src/platform/platform.h index 8edd8beb..eadf2531 100644 --- a/src/platform/platform.h +++ b/src/platform/platform.h @@ -5,21 +5,6 @@ Struct(P_Watch); Struct(P_Window); Struct(P_Sock); -//////////////////////////////////////////////////////////// -//~ Time types - -Struct(P_DateTime) -{ - u32 year; - u32 month; - u32 day_of_week; - u32 day; - u32 hour; - u32 minute; - u32 second; - u32 milliseconds; -}; - //////////////////////////////////////////////////////////// //~ File system types @@ -31,9 +16,9 @@ Struct(P_File) Struct(P_FileTime) { - P_DateTime created; - P_DateTime accessed; - P_DateTime modified; + DateTime created; + DateTime accessed; + DateTime modified; }; Struct(P_FileMap) @@ -278,11 +263,6 @@ Enum(P_MessageBoxKind) void P_Startup(void); -//////////////////////////////////////////////////////////// -//~ @hookdecl Time helper hooks - -P_DateTime P_LocalTime(void); - //////////////////////////////////////////////////////////// //~ @hookdecl File system hooks diff --git a/src/platform/platform.lay b/src/platform/platform.lay index d0c1e5dd..a4ed6edf 100644 --- a/src/platform/platform.lay +++ b/src/platform/platform.lay @@ -2,14 +2,9 @@ //- Api @IncludeC platform.h -@IncludeC platform_log.h - -//- Impl -@IncludeC platform_log.c //- Win32 impl @DefaultWindowsImpl platform_win32 //- Startup @Startup P_Startup -@Startup P_StartupLog diff --git a/src/platform/platform_log.c b/src/platform/platform_log.c deleted file mode 100644 index cd86a0d4..00000000 --- a/src/platform/platform_log.c +++ /dev/null @@ -1,232 +0,0 @@ -P_SharedLogState P_shared_log_state = ZI; - -//////////////////////////////////////////////////////////// -//~ Startup - -void P_StartupLog(void) -{ - __prof; - /* FIXME: Remove hardcode */ - String logfile_path = Lit("log.log"); - P_SharedLogState *ctx = &P_shared_log_state; - ctx->callbacks_arena = AcquireArena(Mebi(8)); - if (logfile_path.len > 0) - { - /* Create / wipe log file */ - P_CloseFile(P_OpenFileWrite(logfile_path)); - /* Keep log file open for appending */ - if (P_IsFile(logfile_path)) - { - ctx->file = P_OpenFileAppend(logfile_path); - ctx->file_valid = 1; - } - } - Atomic32Set(&ctx->initialized, 1); -} - -//////////////////////////////////////////////////////////// -//~ Callback registration - -void P_RegisterLogCallback(P_LogEventCallbackFunc *func, i32 level) -{ - P_SharedLogState *ctx = &P_shared_log_state; - if (!Atomic32Fetch(&ctx->initialized)) { return; } - Lock lock = LockE(&ctx->callbacks_mutex); - { - LogEventCallback *callback = PushStruct(ctx->callbacks_arena, LogEventCallback); - callback->func = func; - callback->level = level; - if (ctx->last_callback) - { - ctx->last_callback->next = callback; - } - else - { - ctx->first_callback = callback; - } - ctx->last_callback = callback; - } - Unlock(&lock); -} - -//////////////////////////////////////////////////////////// -//~ Append - -void P_LogAppend_(String msg) -{ - __prof; - P_SharedLogState *ctx = &P_shared_log_state; - if (!Atomic32Fetch(&ctx->initialized)) { return; } - - if (ctx->file_valid) - { - TempArena scratch = BeginScratchNoConflict(); - String msg_line = CatString(scratch.arena, msg, Lit("\n")); - P_WriteFile(ctx->file, msg_line); - EndScratch(scratch); - } -} - -//////////////////////////////////////////////////////////// -//~ Panic - -/* Panic log function is separate to enforce zero side effects other than - * writing to log file. */ -void P_LogPanic_(String msg) -{ - P_SharedLogState *ctx = &P_shared_log_state; - if (!Atomic32Fetch(&ctx->initialized)) { return; } - - if (ctx->file_valid) - { - P_WriteFile(ctx->file, Lit("******** PANICKING ********\n")); - P_WriteFile(ctx->file, msg); - P_WriteFile(ctx->file, Lit("\n***************************\n")); - } -} - -//////////////////////////////////////////////////////////// -//~ Logfv - -#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 -{ - P_SharedLogState *ctx = &P_shared_log_state; - if (!Atomic32Fetch(&ctx->initialized)) { return; } - TempArena scratch = BeginScratchNoConflict(); - String msg = FormatStringV(scratch.arena, fmt, args); -#if P_IncludeLogSourceLocation - P_Log_(level, file, line, msg); -#else - P_Log_(level, msg); -#endif - EndScratch(scratch); -} - -//////////////////////////////////////////////////////////// -//~ Logf - -#if P_IncludeLogSourceLocation -void P_LogF_(i32 level, String file, u32 line, String fmt, ...) -#else -void P_LogF_(i32 level, String fmt, ...) -#endif -{ - P_SharedLogState *ctx = &P_shared_log_state; - if (!Atomic32Fetch(&ctx->initialized)) { return; } - va_list args; - va_start(args, fmt); -#if P_IncludeLogSourceLocation - P_LogFV_(level, file, line, fmt, args); -#else - P_LogFV_(level, fmt, args); -#endif - va_end(args); -} - -//////////////////////////////////////////////////////////// -//~ Log - -#if P_IncludeLogSourceLocation -void P_Log_(i32 level, String file, u32 line, String msg) -#else -void P_Log_(i32 level, String msg) -#endif -{ - __prof; - P_SharedLogState *ctx = &P_shared_log_state; - if (!Atomic32Fetch(&ctx->initialized)) { return; } - TempArena scratch = BeginScratchNoConflict(); - - P_LogLevelSettings settings = P_log_settings[level]; - if (level < 0 || level >= P_LogLevel_Count) - { - Panic(Lit("Invalid log level")); - } - - /* FIXME: Log actual thread & fiber id */ - // u32 tid = ThreadId(); - u32 tid = 0; - - //- Format message - P_DateTime datetime = P_LocalTime(); - i64 time_ns = TimeNs(); - String shorthand = settings.shorthand; - -#if P_IncludeLogSourceLocation - String msg_formatted = StringF( - scratch.arena, - "[%F:%F:%F.%F] |%F| [%F] <%F:%F> %F", - - /* Time */ - FmtUintZ(datetime.hour, 2), - FmtUintZ(datetime.minute, 2), - FmtUintZ(datetime.second, 2), - FmtUintZ(datetime.milliseconds, 3), - - /* TID */ - FmtUintZ(tid, 5), - - /* Level */ - FmtString(shorthand), - - /* Source location */ - FmtString(file), - FmtSint(line), - - /* Message */ - FmtString(msg) - ); -#else - String msg_formatted = StringF( - scratch.arena, - "[%F:%F:%F.%F] |%F| [%F] %F", - - /* Time */ - FmtUintZ(datetime.hour, 2), - FmtUintZ(datetime.minute, 2), - FmtUintZ(datetime.second, 2), - FmtUintZ(datetime.milliseconds, 3), - - /* TID */ - FmtUintZ(tid, 5), - - /* Level */ - FmtString(shorthand), - - /* Message */ - FmtString(msg) - ); -#endif - - __profmsg((char *)msg.text, msg.len, settings.color); - P_LogAppend_(msg_formatted); - - //- Run callbacks - P_LogEvent event = ZI; - event.level = level; - event.msg = msg; - event.datetime = datetime; - event.time_ns = time_ns; -#if P_IncludeLogSourceLocation - event.file = file; - event.line = line; -#endif - { - Lock lock = LockS(&ctx->callbacks_mutex); - for (LogEventCallback *callback = ctx->first_callback; callback; callback = callback->next) - { - if (level <= callback->level) - { - __profn("Run log callback"); - callback->func(event); - } - } - Unlock(&lock); - } - - EndScratch(scratch); -} diff --git a/src/platform/platform_log.h b/src/platform/platform_log.h deleted file mode 100644 index 0aa5de90..00000000 --- a/src/platform/platform_log.h +++ /dev/null @@ -1,230 +0,0 @@ -//////////////////////////////////////////////////////////// -//~ 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 diff --git a/src/platform/platform_win32/platform_win32.c b/src/platform/platform_win32/platform_win32.c index 8feae9a5..229ec71e 100644 --- a/src/platform/platform_win32/platform_win32.c +++ b/src/platform/platform_win32/platform_win32.c @@ -22,18 +22,18 @@ void P_Startup(void) //////////////////////////////////////////////////////////// //~ Win32 time -P_DateTime P_W32_DateTimeFromWin32SystemTime(SYSTEMTIME st) +DateTime P_W32_DateTimeFromWin32SystemTime(SYSTEMTIME st) { - return (P_DateTime) + return (DateTime) { .year = st.wYear, - .month = st.wMonth, - .day_of_week = st.wDayOfWeek, - .day = st.wDay, - .hour = st.wHour, - .minute = st.wMinute, - .second = st.wSecond, - .milliseconds = st.wMilliseconds + .month = st.wMonth, + .day_of_week = st.wDayOfWeek, + .day = st.wDay, + .hour = st.wHour, + .minute = st.wMinute, + .second = st.wSecond, + .milliseconds = st.wMilliseconds }; } @@ -219,16 +219,6 @@ JobDef(P_W32_StartTimerSync, _, __) } } -//////////////////////////////////////////////////////////// -//~ @hookdef Time hooks - -P_DateTime P_LocalTime(void) -{ - SYSTEMTIME lt; - GetLocalTime(<); - return P_W32_DateTimeFromWin32SystemTime(lt); -} - //////////////////////////////////////////////////////////// //~ @hookdef File system hooks @@ -513,8 +503,8 @@ P_FileTime P_GetFileTime(P_File file) return (P_FileTime) { .created = P_W32_DateTimeFromWin32SystemTime(st_created), - .accessed = P_W32_DateTimeFromWin32SystemTime(st_accessed), - .modified = P_W32_DateTimeFromWin32SystemTime(st_modified) + .accessed = P_W32_DateTimeFromWin32SystemTime(st_accessed), + .modified = P_W32_DateTimeFromWin32SystemTime(st_modified) }; } else @@ -942,7 +932,7 @@ void P_MessageBox(P_MessageBoxKind kind, String message) } break; } - P_LogDebugF("Showing message box kind %F with text \"%F\"", FmtSint(kind), FmtString(message)); + LogDebugF("Showing message box kind %F with text \"%F\"", FmtSint(kind), FmtString(message)); MessageBoxExW(0, message_wstr, title, mbox_type, 0); EndScratch(scratch); diff --git a/src/platform/platform_win32/platform_win32.h b/src/platform/platform_win32/platform_win32.h index cf0f956a..eaa4f7d3 100644 --- a/src/platform/platform_win32/platform_win32.h +++ b/src/platform/platform_win32/platform_win32.h @@ -86,7 +86,7 @@ Struct(P_W32_SharedState) //////////////////////////////////////////////////////////// //~ Time operations -P_DateTime P_W32_DateTimeFromWin32SystemTime(SYSTEMTIME st); +DateTime P_W32_DateTimeFromWin32SystemTime(SYSTEMTIME st); //////////////////////////////////////////////////////////// //~ File system operations diff --git a/src/pp/pp.c b/src/pp/pp.c index 81871da8..72ffa73b 100644 --- a/src/pp/pp.c +++ b/src/pp/pp.c @@ -53,10 +53,6 @@ void PP_StartupUser(void) EndScratch(scratch); } - g->console_logs_arena = AcquireArena(Gibi(64)); - //P_RegisterLogCallback(PP_ConsoleLogCallback, P_LogLevel_Success); - P_RegisterLogCallback(PP_ConsoleLogCallback, P_LogLevel_Debug); - /* Create job pools */ JobPoolId user_pool = InitJobPool(1, Lit("User"), JobPoolPriority_Graphics); JobPoolId sim_pool = InitJobPool(1, Lit("Simulation"), JobPoolPriority_Simulation); @@ -106,7 +102,7 @@ void PP_PushGameUiStyle(void) // UI_Push(FontSize, 24); // UI_Push(Font, ResourceKeyFromStore(&PP_Resources, Lit("font/roboto-med.ttf"))); - // UI_Push(Font, ResourceKeyFromStore(&PP_Resources, Lit("font/fixedsys.ttf"))); + UI_Push(Font, ResourceKeyFromStore(&PP_Resources, Lit("font/fixedsys.ttf"))); UI_Push(FontSize, 12); UI_Push(Rounding, 0); @@ -298,37 +294,6 @@ String PP_DebugStringFromEnt(Arena *arena, PP_Ent *ent) //////////////////////////////////////////////////////////// //~ Console -//- Console log callback -P_LogEventCallbackFuncDef(PP_ConsoleLogCallback, log) -{ - __prof; - PP_SharedUserState *g = &PP_shared_user_state; - Lock lock = LockE(&g->console_logs_mutex); - { - PP_ConsoleLog *clog = PushStruct(g->console_logs_arena, PP_ConsoleLog); - clog->level = log.level; - clog->msg = PushString(g->console_logs_arena, log.msg); - clog->datetime = log.datetime; - clog->time_ns = log.time_ns; - - if (g->last_console_log) - { - g->last_console_log->next = clog; - clog->prev = g->last_console_log; - /* Alternating color index between logs of same level */ - i32 *color_index = &g->console_log_color_indices[log.level]; - clog->color_index = *color_index; - *color_index = 1 - *color_index; - } - else - { - g->first_console_log = clog; - } - g->last_console_log = clog; - } - Unlock(&lock); -} - //- Draw console void PP_DrawDebugConsole(b32 minimized) { @@ -337,16 +302,26 @@ void PP_DrawDebugConsole(b32 minimized) PP_SharedUserState *g = &PP_shared_user_state; TempArena scratch = BeginScratchNoConflict(); - // i32 console_level = minimized ? P_LogLevel_Success : P_LogLevel_Debug; - i32 console_level = P_LogLevel_Debug; + // i32 console_level = minimized ? LogLevel_Success : LogLevel_Debug; + i32 console_level = LogLevel_Debug; - u32 colors[P_LogLevel_Count][2] = ZI; + u32 colors[LogLevel_Count][2] = ZI; SetBytes(colors, 0xFF, sizeof(colors)); - colors[P_LogLevel_Debug][0] = Rgb32F(0.4, 0.1, 0.4); colors[P_LogLevel_Debug][1] = Rgb32F(0.5, 0.2, 0.5); - colors[P_LogLevel_Info][0] = Rgb32F(0.4, 0.4, 0.4); colors[P_LogLevel_Info][1] = Rgb32F(0.5, 0.5, 0.5); - colors[P_LogLevel_Success][0] = Rgb32F(0.1, 0.3, 0.1); colors[P_LogLevel_Success][1] = Rgb32F(0.2, 0.4, 0.2); - colors[P_LogLevel_Warning][0] = Rgb32F(0.4, 0.4, 0.1); colors[P_LogLevel_Warning][1] = Rgb32F(0.5, 0.5, 0.2); - colors[P_LogLevel_Error][0] = Rgb32F(0.4, 0.1, 0.1); colors[P_LogLevel_Error][1] = Rgb32F(0.5, 0.2, 0.2); + /* Debug colors */ + colors[LogLevel_Debug][0] = Rgb32F(0.4, 0.1, 0.4); + colors[LogLevel_Debug][1] = Rgb32F(0.5, 0.2, 0.5); + /* Info colors */ + colors[LogLevel_Info][0] = Rgb32F(0.4, 0.4, 0.4); + colors[LogLevel_Info][1] = Rgb32F(0.5, 0.5, 0.5); + /* Success colors */ + colors[LogLevel_Success][0] = Rgb32F(0.1, 0.3, 0.1); + colors[LogLevel_Success][1] = Rgb32F(0.2, 0.4, 0.2); + /* Warning colors */ + colors[LogLevel_Warning][0] = Rgb32F(0.4, 0.4, 0.1); + colors[LogLevel_Warning][1] = Rgb32F(0.5, 0.5, 0.2); + /* Error colors */ + colors[LogLevel_Error][0] = Rgb32F(0.4, 0.1, 0.1); + colors[LogLevel_Error][1] = Rgb32F(0.5, 0.2, 0.2); i64 max_time_ns = I64Max; i64 fade_time_ns = max_time_ns; @@ -364,11 +339,7 @@ void PP_DrawDebugConsole(b32 minimized) { { UI_SetNext(LayoutAxis, Axis_Y); - // UI_SetNext(Tint, 0); - // UI_SetNext(BorderColor, Rgba32F(1, 1, 1, 0.25)); UI_SetNext(Border, 0); - // UI_SetNext(Width, UI_FIT(1)); - // UI_ForceNext(BackgroundColor, Color_Purple); if (minimized) { UI_SetNext(BackgroundColor, 0); @@ -385,30 +356,26 @@ void PP_DrawDebugConsole(b32 minimized) UI_Box *console_box = UI_BuildBox(0, UI_NilKey); UI_Push(Parent, console_box); } - // UI_Push(Width, UI_TXT(0)); - // UI_Push(Width, UI_FIT(1)); - // UI_Push(Height, UI_FIT(1)); - // UI_Push(BorderColor, Rgba32F(0.25, 0.25, 0.25, 1)); - // UI_Push(Rounding, 0); - Lock lock = LockE(&g->console_logs_mutex); { /* Gather display logs */ u64 max = 20; u64 display_count = 0; - PP_ConsoleLog **display_logs = PushStructs(scratch.arena, PP_ConsoleLog *, max); + LogEvent *display_logs = PushStructs(scratch.arena, LogEvent, max); { b32 done = 0; if (minimized) { max = 5; } - for (PP_ConsoleLog *log = g->last_console_log; log && display_count < max && !done; log = log->prev) + LogEventsArray logs = GetLogEvents(); + for (u64 i = logs.count; i-- > 0 && display_count < max && !done;) { - if (log->time_ns > (now_ns - max_time_ns)) + LogEvent ev = logs.logs[i]; + if (ev.time_ns > (now_ns - max_time_ns)) { - if (log->level <= console_level) + if (ev.level <= console_level) { - display_logs[display_count] = log; + display_logs[display_count] = ev; ++display_count; } } @@ -418,18 +385,17 @@ void PP_DrawDebugConsole(b32 minimized) } } } - /* Display logs in reverse */ for (u64 i = display_count; i-- > 0;) { - PP_ConsoleLog *log = display_logs[i]; + LogEvent log = display_logs[i]; f32 opacity = 0.75; - f32 lin = 1.0 - ClampF64((f64)(now_ns - log->time_ns) / (f64)fade_time_ns, 0, 1); + f32 lin = 1.0 - ClampF64((f64)(now_ns - log.time_ns) / (f64)fade_time_ns, 0, 1); opacity *= PowF32(lin, fade_curve); - String text = log->msg; + String text = log.msg; if (!minimized) { - P_DateTime datetime = log->datetime; + DateTime datetime = log.datetime; text = StringF( scratch.arena, "[%F:%F:%F.%F] %F", @@ -443,7 +409,7 @@ void PP_DrawDebugConsole(b32 minimized) { UI_Push(Tint, Alpha32F(0xFFFFFFFF, opacity)); { - u32 color = colors[log->level][log->color_index]; + u32 color = colors[log.level][log.level_id % 2]; UI_SetNext(BackgroundColor, color); UI_SetNext(LayoutAxis, Axis_X); UI_SetNext(Width, UI_FILL(1, 0)); @@ -467,7 +433,6 @@ void PP_DrawDebugConsole(b32 minimized) UI_PopCheckpoint(); } } - Unlock(&lock); } UI_PopCheckpoint(); EndScratch(scratch); @@ -847,7 +812,7 @@ void PP_UpdateUser(void) if (g->bind_states[PP_BindKind_DebugToggleTopmost].num_presses > 0) { WND_PushCmd(window_frame, .kind = WND_CmdKind_SetForcedTop, .v = !window_frame.forced_top); - P_LogSuccessF("Toggle topmost"); + LogSuccessF("Toggle topmost"); } if (g->bind_states[PP_BindKind_DebugConsole].num_presses > 0) @@ -2996,20 +2961,20 @@ JobDef(PP_UpdateSim, UNUSED sig, UNUSED key) #if 0 DEBUGBREAKABLE; - P_LogDebugF("*************************************************"); - P_LogDebugF("local_client->last_tick: %F", FmtUint(local_client->last_tick)); - P_LogDebugF("master_sim_predicted_time_ns: %F", FmtSint(master_sim_predicted_time_ns)); - P_LogDebugF("tick_progress: %F", FmtFloat(tick_progress)); - P_LogDebugF("sim_publish_timescale: %F", FmtFloat(sim_publish_timescale)); - P_LogDebugF("last_tick_from_master_received_at_ns: %F", FmtSint(last_tick_from_master_received_at_ns)); - P_LogDebugF("average_master_receive_dt_ns: %F", FmtSint(average_master_receive_dt_ns)); - P_LogDebugF("next_tick_expected_ns: %F", FmtSint(next_tick_expected_ns)); - P_LogDebugF("master_blend_time_target_ns: %F", FmtSint(master_blend_time_target_ns)); - P_LogDebugF("blend_time_target_diff_ns: %F", FmtSint(blend_time_target_diff_ns)); - P_LogDebugF("master_blend_time_ns: %F", FmtSint(master_blend_time_ns)); - P_LogDebugF("left_snapshot->tick: %F", FmtUint(left_snapshot->tick)); - P_LogDebugF("right_snapshot->tick: %F", FmtUint(right_snapshot->tick)); - P_LogDebugF("master_ss->tick: %F", FmtUint(master_ss->tick)); + LogDebugF("*************************************************"); + LogDebugF("local_client->last_tick: %F", FmtUint(local_client->last_tick)); + LogDebugF("master_sim_predicted_time_ns: %F", FmtSint(master_sim_predicted_time_ns)); + LogDebugF("tick_progress: %F", FmtFloat(tick_progress)); + LogDebugF("sim_publish_timescale: %F", FmtFloat(sim_publish_timescale)); + LogDebugF("last_tick_from_master_received_at_ns: %F", FmtSint(last_tick_from_master_received_at_ns)); + LogDebugF("average_master_receive_dt_ns: %F", FmtSint(average_master_receive_dt_ns)); + LogDebugF("next_tick_expected_ns: %F", FmtSint(next_tick_expected_ns)); + LogDebugF("master_blend_time_target_ns: %F", FmtSint(master_blend_time_target_ns)); + LogDebugF("blend_time_target_diff_ns: %F", FmtSint(blend_time_target_diff_ns)); + LogDebugF("master_blend_time_ns: %F", FmtSint(master_blend_time_ns)); + LogDebugF("left_snapshot->tick: %F", FmtUint(left_snapshot->tick)); + LogDebugF("right_snapshot->tick: %F", FmtUint(right_snapshot->tick)); + LogDebugF("master_ss->tick: %F", FmtUint(master_ss->tick)); #endif } diff --git a/src/pp/pp.h b/src/pp/pp.h index 1ced15e7..016805f7 100644 --- a/src/pp/pp.h +++ b/src/pp/pp.h @@ -113,8 +113,7 @@ Struct(PP_ConsoleLog) String msg; i32 level; i32 color_index; - P_DateTime datetime; - i64 time_ns; + DateTime datetime; PP_ConsoleLog *prev; PP_ConsoleLog *next; }; @@ -197,13 +196,6 @@ Struct(PP_SharedUserState) //- Bind state PP_BindState bind_states[PP_BindKind_Count]; - //- Debug console - Mutex console_logs_mutex; - Arena *console_logs_arena; - PP_ConsoleLog *first_console_log; - PP_ConsoleLog *last_console_log; - i32 console_log_color_indices[P_LogLevel_Count]; - //- Window -> user Mutex sys_window_events_mutex; Arena *sys_window_events_arena; @@ -313,7 +305,6 @@ String PP_DebugStringFromEnt(Arena *arena, PP_Ent *ent); //////////////////////////////////////////////////////////// //~ Console draw operations -P_LogEventCallbackFuncDef(PP_ConsoleLogCallback, log); void PP_DrawDebugConsole(b32 minimized); //////////////////////////////////////////////////////////// diff --git a/src/pp/pp_step.c b/src/pp/pp_step.c index fb38baaf..54169f19 100644 --- a/src/pp/pp_step.c +++ b/src/pp/pp_step.c @@ -929,7 +929,7 @@ void PP_StepSim(PP_SimStepCtx *ctx) player->owner = player->key; PP_EnableProp(player, PP_Prop_IsMaster); } - P_LogInfoF("Created player with key %F for sim client %F. is_master: %F", FmtUid(player->key.uid), FmtHandle(client->key), FmtUint(PP_HasProp(player, PP_Prop_IsMaster))); + LogInfoF("Created player with key %F for sim client %F. is_master: %F", FmtUid(player->key.uid), FmtHandle(client->key), FmtUint(PP_HasProp(player, PP_Prop_IsMaster))); } /* Update rtt */ @@ -1096,7 +1096,7 @@ void PP_StepSim(PP_SimStepCtx *ctx) } if (flags & PP_ControlFlag_SpawnTest1) { - P_LogDebugF("Spawn test 1"); + LogDebugF("Spawn test 1"); u32 count = 1; f32 spread = 0; for (u32 j = 0; j < count; ++j) @@ -1108,7 +1108,7 @@ void PP_StepSim(PP_SimStepCtx *ctx) } if (flags & PP_ControlFlag_SpawnTest2) { - P_LogDebugF("Spawn test 2"); + LogDebugF("Spawn test 2"); u32 count = 1; f32 spread = 0; for (u32 j = 0; j < count; ++j) @@ -1120,7 +1120,7 @@ void PP_StepSim(PP_SimStepCtx *ctx) } if (flags & PP_ControlFlag_SpawnTest3) { - P_LogDebugF("Spawn test 3"); + LogDebugF("Spawn test 3"); u32 count = 1; f32 spread = 0; for (u32 j = 0; j < count; ++j) @@ -1132,7 +1132,7 @@ void PP_StepSim(PP_SimStepCtx *ctx) } if (flags & PP_ControlFlag_SpawnTest4) { - P_LogDebugF("Spawn test 4"); + LogDebugF("Spawn test 4"); u32 count = 1; f32 spread = 0; for (u32 j = 0; j < count; ++j) @@ -1148,7 +1148,7 @@ void PP_StepSim(PP_SimStepCtx *ctx) } if (flags & PP_ControlFlag_TestExplode) { - P_LogDebugF("Explosion test"); + LogDebugF("Explosion test"); PP_SpawnTestExplosion(root, player->player_cursor_pos, 100, 2); } } diff --git a/src/sound/sound.c b/src/sound/sound.c index c7e20770..6789872d 100644 --- a/src/sound/sound.c +++ b/src/sound/sound.c @@ -10,7 +10,7 @@ JobDef(SND_Load, sig, UNUSED id) AC_Asset *asset = sig->asset; SND_SoundFlag flags = sig->flags; - P_LogInfoF("Loading sound \"%F\"", FmtString(name)); + LogInfoF("Loading sound \"%F\"", FmtString(name)); i64 start_ns = TimeNs(); String error_msg = Lit("Unknown error"); @@ -56,12 +56,12 @@ JobDef(SND_Load, sig, UNUSED id) sound->samples = samples; CopyBytes(sound->samples, decoded.samples, decoded.samples_count * sizeof(*decoded.samples)); - P_LogSuccessF("Loaded sound \"%F\" in %F seconds", FmtString(name), FmtFloat(SecondsFromNs(TimeNs() - start_ns))); + LogSuccessF("Loaded sound \"%F\" in %F seconds", FmtString(name), FmtFloat(SecondsFromNs(TimeNs() - start_ns))); AC_MarkReady(asset, sound); } else { - P_LogErrorF("Error loading sound \"%F\": %F", FmtString(name), FmtString(error_msg)); + LogErrorF("Error loading sound \"%F\": %F", FmtString(name), FmtString(error_msg)); /* Store */ SND_Sound *sound = 0; diff --git a/src/window/window_win32/window_win32.c b/src/window/window_win32/window_win32.c index e1464b9e..ea83a158 100644 --- a/src/window/window_win32/window_win32.c +++ b/src/window/window_win32/window_win32.c @@ -360,7 +360,7 @@ LRESULT CALLBACK WND_W32_WindowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM l u8 *buff = PushStructs(scratch.arena, u8, buff_size); if (GetRawInputData((HRAWINPUT)lparam, RID_INPUT, buff, &buff_size, sizeof(RAWINPUTHEADER)) != buff_size) { - P_LogErrorF("GetRawInputData did not return correct size"); + LogErrorF("GetRawInputData did not return correct size"); break; } RAWINPUT raw = ZI;