improve logging from scripts

This commit is contained in:
asrael 2025-12-03 09:41:33 -06:00
parent 3313c800a9
commit a25291e048
7 changed files with 88 additions and 34 deletions

View file

@ -21,24 +21,39 @@ function core.get_height()
return C.pxl8_gfx_get_height(core.gfx) return C.pxl8_gfx_get_height(core.gfx)
end 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) function core.info(msg)
C.pxl8_lua_info(msg) local src, line = get_caller_info()
C.pxl8_lua_log(0, src, line, msg)
end end
function core.warn(msg) function core.warn(msg)
C.pxl8_lua_warn(msg) local src, line = get_caller_info()
C.pxl8_lua_log(1, src, line, msg)
end end
function core.error(msg) function core.error(msg)
C.pxl8_lua_error(msg) local src, line = get_caller_info()
C.pxl8_lua_log(2, src, line, msg)
end end
function core.debug(msg) function core.debug(msg)
C.pxl8_lua_debug(msg) local src, line = get_caller_info()
C.pxl8_lua_log(3, src, line, msg)
end end
function core.trace(msg) function core.trace(msg)
C.pxl8_lua_trace(msg) local src, line = get_caller_info()
C.pxl8_lua_log(4, src, line, msg)
end end
function core.quit() function core.quit()

View file

@ -263,12 +263,15 @@ pxl8_result pxl8_update(pxl8* sys) {
pxl8_result result = pxl8_script_eval_repl(game->script, pxl8_repl_command_buffer(cmd)); pxl8_result result = pxl8_script_eval_repl(game->script, pxl8_repl_command_buffer(cmd));
if (result != PXL8_OK) { if (result != PXL8_OK) {
if (pxl8_script_is_incomplete_input(game->script)) { if (pxl8_script_is_incomplete_input(game->script)) {
pxl8_repl_signal_complete(sys->repl);
} else { } else {
pxl8_error("%s", pxl8_script_get_last_error(game->script)); pxl8_error("%s", pxl8_script_get_last_error(game->script));
pxl8_repl_clear_accumulator(sys->repl); pxl8_repl_clear_accumulator(sys->repl);
pxl8_repl_signal_complete(sys->repl);
} }
} else { } else {
pxl8_repl_clear_accumulator(sys->repl); pxl8_repl_clear_accumulator(sys->repl);
pxl8_repl_signal_complete(sys->repl);
} }
} }
} }

View file

@ -3,6 +3,7 @@
#include <stdarg.h> #include <stdarg.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h>
#include <string.h> #include <string.h>
#include <time.h> #include <time.h>
@ -18,6 +19,15 @@ static pxl8_log* g_log = NULL;
void pxl8_log_init(pxl8_log* log) { void pxl8_log_init(pxl8_log* log) {
g_log = log; g_log = log;
g_log->level = PXL8_LOG_LEVEL_DEBUG; 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) { void pxl8_log_set_level(pxl8_log_level level) {

View file

@ -22,6 +22,7 @@ struct pxl8_repl {
char commands[PXL8_REPL_QUEUE_SIZE][PXL8_MAX_REPL_COMMAND_SIZE]; char commands[PXL8_REPL_QUEUE_SIZE][PXL8_MAX_REPL_COMMAND_SIZE];
atomic_uint cmd_write_idx; atomic_uint cmd_write_idx;
atomic_uint cmd_read_idx; atomic_uint cmd_read_idx;
atomic_bool cmd_complete;
char logs[PXL8_REPL_QUEUE_SIZE][PXL8_MAX_REPL_COMMAND_SIZE]; char logs[PXL8_REPL_QUEUE_SIZE][PXL8_MAX_REPL_COMMAND_SIZE];
atomic_uint log_write_idx; atomic_uint log_write_idx;
@ -127,16 +128,17 @@ static void* pxl8_repl_thread(void* arg) {
if (log_read_idx != log_write_idx) { if (log_read_idx != log_write_idx) {
if (editing) { if (editing) {
linenoiseEditStop(&ls); linenoiseEditStop(&ls);
printf("\r\033[K");
editing = false; editing = false;
stopped_for_logs = true; stopped_for_logs = true;
} }
while (log_read_idx != log_write_idx) { while (log_read_idx != log_write_idx) {
printf("%s", repl->logs[log_read_idx]); printf("%s", repl->logs[log_read_idx]);
fflush(stdout);
atomic_store(&repl->log_read_idx, (log_read_idx + 1) % PXL8_REPL_QUEUE_SIZE); atomic_store(&repl->log_read_idx, (log_read_idx + 1) % PXL8_REPL_QUEUE_SIZE);
log_read_idx = atomic_load(&repl->log_read_idx); log_read_idx = atomic_load(&repl->log_read_idx);
log_write_idx = atomic_load(&repl->log_write_idx); log_write_idx = atomic_load(&repl->log_write_idx);
} }
fflush(stdout);
continue; continue;
} }
@ -197,10 +199,21 @@ static void* pxl8_repl_thread(void* arg) {
linenoiseFree(line); 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}; struct timespec ts = {.tv_sec = 0, .tv_nsec = 1000000};
nanosleep(&ts, NULL); nanosleep(&ts, NULL);
} }
atomic_store(&repl->cmd_complete, false);
} }
if (editing) linenoiseEditStop(&ls); if (editing) linenoiseEditStop(&ls);
@ -217,6 +230,7 @@ pxl8_repl* pxl8_repl_create(void) {
repl->accumulator[0] = '\0'; repl->accumulator[0] = '\0';
atomic_store(&repl->cmd_write_idx, 0); atomic_store(&repl->cmd_write_idx, 0);
atomic_store(&repl->cmd_read_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_write_idx, 0);
atomic_store(&repl->log_read_idx, 0); atomic_store(&repl->log_read_idx, 0);
atomic_store(&repl->should_quit, false); atomic_store(&repl->should_quit, false);
@ -301,3 +315,8 @@ void pxl8_repl_clear_accumulator(pxl8_repl* repl) {
if (!repl) return; if (!repl) return;
repl->accumulator[0] = '\0'; repl->accumulator[0] = '\0';
} }
void pxl8_repl_signal_complete(pxl8_repl* repl) {
if (!repl) return;
atomic_store(&repl->cmd_complete, true);
}

View file

@ -17,6 +17,7 @@ const char* pxl8_repl_command_buffer(pxl8_repl_command* cmd);
bool pxl8_repl_push_log(const char* message); bool pxl8_repl_push_log(const char* message);
void pxl8_repl_clear_accumulator(pxl8_repl* repl); void pxl8_repl_clear_accumulator(pxl8_repl* repl);
bool pxl8_repl_should_quit(pxl8_repl* repl); bool pxl8_repl_should_quit(pxl8_repl* repl);
void pxl8_repl_signal_complete(pxl8_repl* repl);
#ifdef __cplusplus #ifdef __cplusplus
} }

View file

@ -25,6 +25,7 @@ struct pxl8_script {
char main_path[PXL8_MAX_PATH]; char main_path[PXL8_MAX_PATH];
char watch_dir[PXL8_MAX_PATH]; char watch_dir[PXL8_MAX_PATH];
time_t latest_mod_time; time_t latest_mod_time;
int repl_env_ref;
bool repl_mode; 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_cursor(pxl8* sys, pxl8_cursor cursor);\n"
"void pxl8_set_relative_mouse_mode(pxl8* sys, bool enabled);\n" "void pxl8_set_relative_mouse_mode(pxl8* sys, bool enabled);\n"
"void pxl8_set_running(pxl8* sys, bool running);\n" "void pxl8_set_running(pxl8* sys, bool running);\n"
"void pxl8_lua_debug(const char* msg);\n" "void pxl8_lua_log(int level, const char* file, int line, 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"
"typedef u32 pxl8_tile;\n" "typedef u32 pxl8_tile;\n"
"typedef struct pxl8_tilemap pxl8_tilemap;\n" "typedef struct pxl8_tilemap pxl8_tilemap;\n"
"typedef struct pxl8_tilesheet pxl8_tilesheet;\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" "i32 pxl8_save_delete(pxl8_save* save, u8 slot);\n"
"const char* pxl8_save_get_directory(pxl8_save* save);\n"; "const char* pxl8_save_get_directory(pxl8_save* save);\n";
void pxl8_lua_info(const char* msg) { void pxl8_lua_log(int level, const char* file, int line, const char* msg) {
pxl8_info("%s", 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;
} }
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);
} }
static void pxl8_script_set_error(pxl8_script* script, const char* error) { 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->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; return script;
} }
void pxl8_script_destroy(pxl8_script* script) { void pxl8_script_destroy(pxl8_script* script) {
if (!script) return; if (!script) return;
if (script->L) { if (script->L) {
if (script->repl_env_ref != LUA_NOREF) {
luaL_unref(script->L, LUA_REGISTRYINDEX, script->repl_env_ref);
}
lua_close(script->L); lua_close(script->L);
} }
free(script); 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_pushstring(script->L, code);
lua_newtable(script->L); lua_newtable(script->L);
lua_pushstring(script->L, "useMetadata");
lua_pushboolean(script->L, true); 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) { if (lua_pcall(script->L, 2, 1, 0) != 0) {
const char* error = lua_tostring(script->L, -1); const char* error = lua_tostring(script->L, -1);

View file

@ -4,7 +4,7 @@
#include "pxl8_tilesheet.h" #include "pxl8_tilesheet.h"
#include "pxl8_types.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_WIDTH 256
#define PXL8_MAX_TILEMAP_HEIGHT 256 #define PXL8_MAX_TILEMAP_HEIGHT 256
#define PXL8_MAX_TILE_LAYERS 4 #define PXL8_MAX_TILE_LAYERS 4