From a25291e048000d7e514f6b9dccd1b8b0b769178d Mon Sep 17 00:00:00 2001 From: asrael Date: Wed, 3 Dec 2025 09:41:33 -0600 Subject: [PATCH] improve logging from scripts --- src/lua/pxl8/core.lua | 25 +++++++++++++++---- src/pxl8.c | 3 +++ src/pxl8_log.c | 10 ++++++++ src/pxl8_repl.c | 23 +++++++++++++++-- src/pxl8_repl.h | 1 + src/pxl8_script.c | 58 ++++++++++++++++++++++++------------------- src/pxl8_tilemap.h | 2 +- 7 files changed, 88 insertions(+), 34 deletions(-) diff --git a/src/lua/pxl8/core.lua b/src/lua/pxl8/core.lua index 1ca9d9e..348943d 100644 --- a/src/lua/pxl8/core.lua +++ b/src/lua/pxl8/core.lua @@ -21,24 +21,39 @@ function core.get_height() return C.pxl8_gfx_get_height(core.gfx) end +local function get_caller_info() + local info = debug.getinfo(3, "Sl") + if info then + local src = info.short_src or "?" + local line = info.currentline or 0 + return src, line + end + return nil, 0 +end + function core.info(msg) - C.pxl8_lua_info(msg) + local src, line = get_caller_info() + C.pxl8_lua_log(0, src, line, msg) end function core.warn(msg) - C.pxl8_lua_warn(msg) + local src, line = get_caller_info() + C.pxl8_lua_log(1, src, line, msg) end function core.error(msg) - C.pxl8_lua_error(msg) + local src, line = get_caller_info() + C.pxl8_lua_log(2, src, line, msg) end function core.debug(msg) - C.pxl8_lua_debug(msg) + local src, line = get_caller_info() + C.pxl8_lua_log(3, src, line, msg) end function core.trace(msg) - C.pxl8_lua_trace(msg) + local src, line = get_caller_info() + C.pxl8_lua_log(4, src, line, msg) end function core.quit() diff --git a/src/pxl8.c b/src/pxl8.c index a7e0259..d8f47e4 100644 --- a/src/pxl8.c +++ b/src/pxl8.c @@ -263,12 +263,15 @@ pxl8_result pxl8_update(pxl8* sys) { pxl8_result result = pxl8_script_eval_repl(game->script, pxl8_repl_command_buffer(cmd)); if (result != PXL8_OK) { if (pxl8_script_is_incomplete_input(game->script)) { + pxl8_repl_signal_complete(sys->repl); } else { pxl8_error("%s", pxl8_script_get_last_error(game->script)); pxl8_repl_clear_accumulator(sys->repl); + pxl8_repl_signal_complete(sys->repl); } } else { pxl8_repl_clear_accumulator(sys->repl); + pxl8_repl_signal_complete(sys->repl); } } } diff --git a/src/pxl8_log.c b/src/pxl8_log.c index 7611f4f..d897000 100644 --- a/src/pxl8_log.c +++ b/src/pxl8_log.c @@ -3,6 +3,7 @@ #include #include +#include #include #include @@ -18,6 +19,15 @@ static pxl8_log* g_log = NULL; void pxl8_log_init(pxl8_log* log) { g_log = log; g_log->level = PXL8_LOG_LEVEL_DEBUG; + + const char* env_level = getenv("PXL8_LOG_LEVEL"); + if (env_level) { + if (strcmp(env_level, "trace") == 0) g_log->level = PXL8_LOG_LEVEL_TRACE; + else if (strcmp(env_level, "debug") == 0) g_log->level = PXL8_LOG_LEVEL_DEBUG; + else if (strcmp(env_level, "info") == 0) g_log->level = PXL8_LOG_LEVEL_INFO; + else if (strcmp(env_level, "warn") == 0) g_log->level = PXL8_LOG_LEVEL_WARN; + else if (strcmp(env_level, "error") == 0) g_log->level = PXL8_LOG_LEVEL_ERROR; + } } void pxl8_log_set_level(pxl8_log_level level) { diff --git a/src/pxl8_repl.c b/src/pxl8_repl.c index 75ace26..aea7ce7 100644 --- a/src/pxl8_repl.c +++ b/src/pxl8_repl.c @@ -22,6 +22,7 @@ struct pxl8_repl { char commands[PXL8_REPL_QUEUE_SIZE][PXL8_MAX_REPL_COMMAND_SIZE]; atomic_uint cmd_write_idx; atomic_uint cmd_read_idx; + atomic_bool cmd_complete; char logs[PXL8_REPL_QUEUE_SIZE][PXL8_MAX_REPL_COMMAND_SIZE]; atomic_uint log_write_idx; @@ -127,16 +128,17 @@ static void* pxl8_repl_thread(void* arg) { if (log_read_idx != log_write_idx) { if (editing) { linenoiseEditStop(&ls); + printf("\r\033[K"); editing = false; stopped_for_logs = true; } while (log_read_idx != log_write_idx) { printf("%s", repl->logs[log_read_idx]); - fflush(stdout); atomic_store(&repl->log_read_idx, (log_read_idx + 1) % PXL8_REPL_QUEUE_SIZE); log_read_idx = atomic_load(&repl->log_read_idx); log_write_idx = atomic_load(&repl->log_write_idx); } + fflush(stdout); continue; } @@ -197,10 +199,21 @@ static void* pxl8_repl_thread(void* arg) { linenoiseFree(line); - while (atomic_load(&repl->cmd_write_idx) != atomic_load(&repl->cmd_read_idx)) { + while (atomic_load(&repl->cmd_write_idx) != atomic_load(&repl->cmd_read_idx) || + !atomic_load(&repl->cmd_complete)) { + u32 lr = atomic_load(&repl->log_read_idx); + u32 lw = atomic_load(&repl->log_write_idx); + while (lr != lw) { + printf("%s", repl->logs[lr]); + atomic_store(&repl->log_read_idx, (lr + 1) % PXL8_REPL_QUEUE_SIZE); + lr = atomic_load(&repl->log_read_idx); + lw = atomic_load(&repl->log_write_idx); + } + fflush(stdout); struct timespec ts = {.tv_sec = 0, .tv_nsec = 1000000}; nanosleep(&ts, NULL); } + atomic_store(&repl->cmd_complete, false); } if (editing) linenoiseEditStop(&ls); @@ -217,6 +230,7 @@ pxl8_repl* pxl8_repl_create(void) { repl->accumulator[0] = '\0'; atomic_store(&repl->cmd_write_idx, 0); atomic_store(&repl->cmd_read_idx, 0); + atomic_store(&repl->cmd_complete, true); atomic_store(&repl->log_write_idx, 0); atomic_store(&repl->log_read_idx, 0); atomic_store(&repl->should_quit, false); @@ -301,3 +315,8 @@ void pxl8_repl_clear_accumulator(pxl8_repl* repl) { if (!repl) return; repl->accumulator[0] = '\0'; } + +void pxl8_repl_signal_complete(pxl8_repl* repl) { + if (!repl) return; + atomic_store(&repl->cmd_complete, true); +} diff --git a/src/pxl8_repl.h b/src/pxl8_repl.h index ee815e2..53a5d6f 100644 --- a/src/pxl8_repl.h +++ b/src/pxl8_repl.h @@ -17,6 +17,7 @@ const char* pxl8_repl_command_buffer(pxl8_repl_command* cmd); bool pxl8_repl_push_log(const char* message); void pxl8_repl_clear_accumulator(pxl8_repl* repl); bool pxl8_repl_should_quit(pxl8_repl* repl); +void pxl8_repl_signal_complete(pxl8_repl* repl); #ifdef __cplusplus } diff --git a/src/pxl8_script.c b/src/pxl8_script.c index 94b2df1..3a767cf 100644 --- a/src/pxl8_script.c +++ b/src/pxl8_script.c @@ -25,6 +25,7 @@ struct pxl8_script { char main_path[PXL8_MAX_PATH]; char watch_dir[PXL8_MAX_PATH]; time_t latest_mod_time; + int repl_env_ref; bool repl_mode; }; @@ -210,12 +211,7 @@ static const char* pxl8_ffi_cdefs = "void pxl8_set_cursor(pxl8* sys, pxl8_cursor cursor);\n" "void pxl8_set_relative_mouse_mode(pxl8* sys, bool enabled);\n" "void pxl8_set_running(pxl8* sys, bool running);\n" -"void pxl8_lua_debug(const char* msg);\n" -"void pxl8_lua_error(const char* msg);\n" -"void pxl8_lua_info(const char* msg);\n" -"void pxl8_lua_trace(const char* msg);\n" -"void pxl8_lua_warn(const char* msg);\n" -"\n" +"void pxl8_lua_log(int level, const char* file, int line, const char* msg);\n" "typedef u32 pxl8_tile;\n" "typedef struct pxl8_tilemap pxl8_tilemap;\n" "typedef struct pxl8_tilesheet pxl8_tilesheet;\n" @@ -423,24 +419,14 @@ static const char* pxl8_ffi_cdefs = "i32 pxl8_save_delete(pxl8_save* save, u8 slot);\n" "const char* pxl8_save_get_directory(pxl8_save* save);\n"; -void pxl8_lua_info(const char* msg) { - pxl8_info("%s", msg); -} - -void pxl8_lua_warn(const char* msg) { - pxl8_warn("%s", msg); -} - -void pxl8_lua_error(const char* msg) { - pxl8_error("%s", msg); -} - -void pxl8_lua_debug(const char* msg) { - pxl8_debug("%s", msg); -} - -void pxl8_lua_trace(const char* msg) { - pxl8_trace("%s", msg); +void pxl8_lua_log(int level, const char* file, int line, const char* msg) { + switch (level) { + case 0: pxl8_log_write_info("%s", msg); break; + case 1: pxl8_log_write_warn(file, line, "%s", msg); break; + case 2: pxl8_log_write_error(file, line, "%s", msg); break; + case 3: pxl8_log_write_debug(file, line, "%s", msg); break; + case 4: pxl8_log_write_trace(file, line, "%s", msg); break; + } } static void pxl8_script_set_error(pxl8_script* script, const char* error) { @@ -573,12 +559,26 @@ pxl8_script* pxl8_script_create(bool repl_mode) { } script->last_error[0] = '\0'; + script->repl_env_ref = LUA_NOREF; + + if (script->repl_mode) { + lua_newtable(script->L); + lua_newtable(script->L); + lua_getglobal(script->L, "_G"); + lua_setfield(script->L, -2, "__index"); + lua_setmetatable(script->L, -2); + script->repl_env_ref = luaL_ref(script->L, LUA_REGISTRYINDEX); + } + return script; } void pxl8_script_destroy(pxl8_script* script) { if (!script) return; if (script->L) { + if (script->repl_env_ref != LUA_NOREF) { + luaL_unref(script->L, LUA_REGISTRYINDEX, script->repl_env_ref); + } lua_close(script->L); } free(script); @@ -771,9 +771,15 @@ static pxl8_result pxl8_script_eval_internal(pxl8_script* script, const char* co lua_pushstring(script->L, code); lua_newtable(script->L); - lua_pushstring(script->L, "useMetadata"); lua_pushboolean(script->L, true); - lua_settable(script->L, -3); + lua_setfield(script->L, -2, "useMetadata"); + + if (repl_mode && script->repl_env_ref != LUA_NOREF) { + lua_rawgeti(script->L, LUA_REGISTRYINDEX, script->repl_env_ref); + lua_setfield(script->L, -2, "env"); + lua_pushboolean(script->L, false); + lua_setfield(script->L, -2, "allowedGlobals"); + } if (lua_pcall(script->L, 2, 1, 0) != 0) { const char* error = lua_tostring(script->L, -1); diff --git a/src/pxl8_tilemap.h b/src/pxl8_tilemap.h index ca7962c..e96bcd3 100644 --- a/src/pxl8_tilemap.h +++ b/src/pxl8_tilemap.h @@ -4,7 +4,7 @@ #include "pxl8_tilesheet.h" #include "pxl8_types.h" -#define PXL8_TILE_SIZE 16 +#define PXL8_TILE_SIZE 8 #define PXL8_MAX_TILEMAP_WIDTH 256 #define PXL8_MAX_TILEMAP_HEIGHT 256 #define PXL8_MAX_TILE_LAYERS 4