From 148a2bdb457441f6d79e69cafb92366de22177b8 Mon Sep 17 00:00:00 2001 From: bjorn Date: Wed, 26 Sep 2018 10:39:17 -0700 Subject: [PATCH] Error system no longer relies on Lua; --- src/api/thread.c | 3 ++- src/lovr.c | 4 +++- src/luax.c | 6 ++++++ src/luax.h | 1 + src/util.c | 33 ++++++++++++++++++++++----------- src/util.h | 6 +++++- 6 files changed, 39 insertions(+), 14 deletions(-) diff --git a/src/api/thread.c b/src/api/thread.c index d4a994d4..96858eef 100644 --- a/src/api/thread.c +++ b/src/api/thread.c @@ -12,8 +12,9 @@ static int threadRunner(void* data) { mtx_unlock(&thread->lock); // Lua state - lua_State* L = lovrErrorContext = luaL_newstate(); + lua_State* L = luaL_newstate(); luaL_openlibs(L); + lovrSetErrorCallback((lovrErrorHandler) luax_vthrow, L); l_lovrInit(L); lua_setglobal(L, "lovr"); diff --git a/src/lovr.c b/src/lovr.c index b0f2834a..948b42a3 100644 --- a/src/lovr.c +++ b/src/lovr.c @@ -82,9 +82,11 @@ void lovrDestroy() { } bool lovrRun(int argc, char** argv, int* status) { - lua_State* L = lovrErrorContext = luaL_newstate(); + lua_State* L = luaL_newstate(); luaL_openlibs(L); + lovrSetErrorCallback((lovrErrorHandler) luax_vthrow, L); + glfwSetErrorCallback(onGlfwError); lovrAssert(glfwInit(), "Error initializing GLFW"); glfwSetTime(0); diff --git a/src/luax.c b/src/luax.c index dda6aa4f..ec9e83ad 100644 --- a/src/luax.c +++ b/src/luax.c @@ -1,6 +1,7 @@ #include "luax.h" #include "util.h" #include +#include static int luax_meta__tostring(lua_State* L) { lua_getfield(L, -1, "name"); @@ -163,6 +164,11 @@ void luax_pushobject(lua_State* L, void* object) { lua_remove(L, -2); } +void luax_vthrow(lua_State* L, const char* format, va_list args) { + lua_pushvfstring(L, format, args); + lua_error(L); +} + int luax_getstack(lua_State* L) { const char* message = luaL_checkstring(L, -1); lua_getglobal(L, "debug"); diff --git a/src/luax.h b/src/luax.h index e5356394..8a2c6f1e 100644 --- a/src/luax.h +++ b/src/luax.h @@ -16,6 +16,7 @@ void luax_extendtype(lua_State* L, const char* base, const char* name, const lua void* _luax_totype(lua_State* L, int index, const char* type); void* _luax_checktype(lua_State* L, int index, const char* type); void luax_pushobject(lua_State* L, void* object); +void luax_vthrow(lua_State* L, const char* format, va_list args); int luax_getstack(lua_State* L); void luax_pushconf(lua_State* L); int luax_setconf(lua_State* L); diff --git a/src/util.c b/src/util.c index 10da349f..d59ea37a 100644 --- a/src/util.c +++ b/src/util.c @@ -1,9 +1,6 @@ #include "util.h" -#include -#include -#include -#include #include +#include #ifdef _WIN32 #include #else @@ -11,15 +8,29 @@ #include #endif -_Thread_local void* lovrErrorContext = NULL; +_Thread_local lovrErrorHandler lovrErrorCallback = NULL; +_Thread_local void* lovrErrorUserdata = NULL; + +void lovrSetErrorCallback(lovrErrorHandler callback, void* userdata) { + lovrErrorCallback = callback; + lovrErrorUserdata = userdata; +} void lovrThrow(const char* format, ...) { - lua_State* L = (lua_State*) lovrErrorContext; - va_list args; - va_start(args, format); - lua_pushvfstring(L, format, args); - lua_error(L); - va_end(args); + if (lovrErrorCallback) { + va_list args; + va_start(args, format); + lovrErrorCallback(lovrErrorUserdata, format, args); + va_end(args); + } else { + va_list args; + va_start(args, format); + fprintf(stderr, "Error: "); + vfprintf(stderr, format, args); + fprintf(stderr, "\n"); + va_end(args); + exit(EXIT_FAILURE); + } } void lovrSleep(double seconds) { diff --git a/src/util.h b/src/util.h index 7f8219c0..b6c0b33a 100644 --- a/src/util.h +++ b/src/util.h @@ -2,6 +2,7 @@ #include "lib/tinycthread/tinycthread.h" #include #include +#include #pragma once @@ -20,8 +21,11 @@ typedef struct { float r, g, b, a; } Color; -extern _Thread_local void* lovrErrorContext; +typedef void (*lovrErrorHandler)(void* userdata, const char* format, va_list args); +extern _Thread_local lovrErrorHandler lovrErrorCallback; +extern _Thread_local void* lovrErrorUserdata; +void lovrSetErrorCallback(lovrErrorHandler callback, void* context); void lovrThrow(const char* format, ...); void lovrSleep(double seconds); void* _lovrAlloc(const char* type, size_t size, void (*destructor)(void*));