mirror of
https://github.com/bjornbytes/lovr.git
synced 2024-07-04 13:33:34 +00:00
Merge pull request #116 from bjornbytes/headset-render-error
Refactor asynchronous headset render errors;
This commit is contained in:
commit
0927df8246
|
@ -78,17 +78,16 @@ static void renderHelper(void* userdata) {
|
||||||
HeadsetRenderData* renderData = userdata;
|
HeadsetRenderData* renderData = userdata;
|
||||||
lua_State* L = renderData->L;
|
lua_State* L = renderData->L;
|
||||||
#ifdef LOVR_HEADSET_HELPER_USES_REGISTRY
|
#ifdef LOVR_HEADSET_HELPER_USES_REGISTRY
|
||||||
lua_getglobal(L, "_lovrHeadsetRenderError");
|
luax_geterror(L);
|
||||||
bool noError = lua_isnil(L, -1);
|
if (lua_isnil(L, -1)) {
|
||||||
lua_pop(L, 1);
|
|
||||||
if (noError) { // Skip if there's already an error waiting to show
|
|
||||||
lua_pushcfunction(L, luax_getstack);
|
lua_pushcfunction(L, luax_getstack);
|
||||||
lua_rawgeti(L, LUA_REGISTRYINDEX, renderData->ref);
|
lua_rawgeti(L, LUA_REGISTRYINDEX, renderData->ref);
|
||||||
if (lua_pcall(L, 0, 0, -2)) {
|
if (lua_pcall(L, 0, 0, -2)) {
|
||||||
lua_setglobal(L, "_lovrHeadsetRenderError");
|
luax_seterror(L);
|
||||||
}
|
}
|
||||||
lua_pop(L, 1); // pop luax_getstack
|
lua_pop(L, 1); // pop luax_getstack
|
||||||
}
|
}
|
||||||
|
lua_pop(L, 1);
|
||||||
#else
|
#else
|
||||||
lua_call(L, 0, 0);
|
lua_call(L, 0, 0);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -262,7 +262,7 @@ bool lovrPlatformHasWindow() {
|
||||||
extern unsigned char boot_lua[];
|
extern unsigned char boot_lua[];
|
||||||
extern unsigned int boot_lua_len;
|
extern unsigned int boot_lua_len;
|
||||||
|
|
||||||
static lua_State *L, *Lcoroutine;
|
static lua_State *L, *T;
|
||||||
static int coroutineRef = LUA_NOREF;
|
static int coroutineRef = LUA_NOREF;
|
||||||
static int coroutineStartFunctionRef = LUA_NOREF;
|
static int coroutineStartFunctionRef = LUA_NOREF;
|
||||||
|
|
||||||
|
@ -358,8 +358,8 @@ static void bridgeLovrInitState() {
|
||||||
}
|
}
|
||||||
|
|
||||||
coroutineStartFunctionRef = luaL_ref(L, LUA_REGISTRYINDEX); // Value returned by boot.lua
|
coroutineStartFunctionRef = luaL_ref(L, LUA_REGISTRYINDEX); // Value returned by boot.lua
|
||||||
Lcoroutine = lua_newthread(L); // Leave L clear to be used by the draw function
|
T = lua_newthread(L); // Leave L clear to be used by the draw function
|
||||||
lua_atpanic(Lcoroutine, luax_custom_atpanic);
|
lua_atpanic(T, luax_custom_atpanic);
|
||||||
coroutineRef = luaL_ref(L, LUA_REGISTRYINDEX); // Hold on to the Lua-side coroutine object so it isn't GC'd
|
coroutineRef = luaL_ref(L, LUA_REGISTRYINDEX); // Hold on to the Lua-side coroutine object so it isn't GC'd
|
||||||
|
|
||||||
lovrLog("\n STATE INIT COMPLETE\n");
|
lovrLog("\n STATE INIT COMPLETE\n");
|
||||||
|
@ -401,13 +401,15 @@ void bridgeLovrUpdate(BridgeLovrUpdateData *updateData) {
|
||||||
|
|
||||||
// Go
|
// Go
|
||||||
if (coroutineStartFunctionRef != LUA_NOREF) {
|
if (coroutineStartFunctionRef != LUA_NOREF) {
|
||||||
lua_rawgeti(Lcoroutine, LUA_REGISTRYINDEX, coroutineStartFunctionRef);
|
lua_rawgeti(T, LUA_REGISTRYINDEX, coroutineStartFunctionRef);
|
||||||
luaL_unref (Lcoroutine, LUA_REGISTRYINDEX, coroutineStartFunctionRef);
|
luaL_unref (T, LUA_REGISTRYINDEX, coroutineStartFunctionRef);
|
||||||
coroutineStartFunctionRef = LUA_NOREF; // No longer needed
|
coroutineStartFunctionRef = LUA_NOREF; // No longer needed
|
||||||
}
|
}
|
||||||
int coroutineArgs = luax_pushLovrHeadsetRenderError(Lcoroutine);
|
|
||||||
if (lua_resume(Lcoroutine, coroutineArgs) != LUA_YIELD) {
|
luax_geterror(T);
|
||||||
if (lua_type(Lcoroutine, -1) == LUA_TSTRING && !strcmp(lua_tostring(Lcoroutine, -1), "restart")) {
|
luax_clearerror(T);
|
||||||
|
if (lua_resume(T, 1) != LUA_YIELD) {
|
||||||
|
if (lua_type(T, -1) == LUA_TSTRING && !strcmp(lua_tostring(T, -1), "restart")) {
|
||||||
lua_close(L);
|
lua_close(L);
|
||||||
bridgeLovrInitState();
|
bridgeLovrInitState();
|
||||||
} else {
|
} else {
|
||||||
|
|
12
src/luax.c
12
src/luax.c
|
@ -289,18 +289,6 @@ Color luax_checkcolor(lua_State* L, int index) {
|
||||||
return color;
|
return color;
|
||||||
}
|
}
|
||||||
|
|
||||||
int luax_pushLovrHeadsetRenderError(lua_State *L) {
|
|
||||||
lua_getglobal(L, "_lovrHeadsetRenderError"); // renderCallback failed
|
|
||||||
bool haveRenderError = !lua_isnil(L, -1);
|
|
||||||
if (haveRenderError) {
|
|
||||||
lua_pushnil(L); // Now the error is on the stack remove it from globals
|
|
||||||
lua_setglobal(L, "_lovrHeadsetRenderError");
|
|
||||||
} else {
|
|
||||||
lua_pop(L, 1); // pop stray nil
|
|
||||||
}
|
|
||||||
return haveRenderError;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if LUA_VERSION_NUM < 502
|
#if LUA_VERSION_NUM < 502
|
||||||
void luax_setmainthread(lua_State *L) {
|
void luax_setmainthread(lua_State *L) {
|
||||||
lua_pushthread(L);
|
lua_pushthread(L);
|
||||||
|
|
|
@ -10,6 +10,9 @@
|
||||||
#define luax_checktype(L, i, T) ((T*) _luax_checktype(L, i, #T))
|
#define luax_checktype(L, i, T) ((T*) _luax_checktype(L, i, #T))
|
||||||
#define luax_checkfloat(L, i) (float) luaL_checknumber(L, i)
|
#define luax_checkfloat(L, i) (float) luaL_checknumber(L, i)
|
||||||
#define luax_optfloat(L, i, x) (float) luaL_optnumber(L, i, x)
|
#define luax_optfloat(L, i, x) (float) luaL_optnumber(L, i, x)
|
||||||
|
#define luax_geterror(L) lua_getfield(L, LUA_REGISTRYINDEX, "_lovrerror")
|
||||||
|
#define luax_seterror(L) lua_setfield(L, LUA_REGISTRYINDEX, "_lovrerror")
|
||||||
|
#define luax_clearerror(L) lua_pushnil(L), luax_seterror(L)
|
||||||
typedef void (*luax_destructor)(void);
|
typedef void (*luax_destructor)(void);
|
||||||
|
|
||||||
int luax_print(lua_State* L);
|
int luax_print(lua_State* L);
|
||||||
|
@ -27,7 +30,6 @@ int luax_getstack_panic(lua_State *L);
|
||||||
void luax_pushconf(lua_State* L);
|
void luax_pushconf(lua_State* L);
|
||||||
int luax_setconf(lua_State* L);
|
int luax_setconf(lua_State* L);
|
||||||
Color luax_checkcolor(lua_State* L, int index);
|
Color luax_checkcolor(lua_State* L, int index);
|
||||||
int luax_pushLovrHeadsetRenderError(lua_State *L);
|
|
||||||
|
|
||||||
#if LUA_VERSION_NUM < 502
|
#if LUA_VERSION_NUM < 502
|
||||||
#define LUA_RIDX_MAINTHREAD 1
|
#define LUA_RIDX_MAINTHREAD 1
|
||||||
|
|
16
src/main.c
16
src/main.c
|
@ -34,17 +34,13 @@ void lovrDestroy(void* arg) {
|
||||||
|
|
||||||
static void emscriptenLoop(void* arg) {
|
static void emscriptenLoop(void* arg) {
|
||||||
lovrEmscriptenContext* context = arg;
|
lovrEmscriptenContext* context = arg;
|
||||||
lua_getglobal(context->L, "_lovrHeadsetRenderError"); // webvr.c renderCallback failed
|
lua_State* T = context->T;
|
||||||
bool haveRenderError = !lua_isnil(context->L, -1);
|
|
||||||
if (!haveRenderError) {
|
|
||||||
lua_pop(context->L, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
int coroutineArgs = luax_pushLovrHeadsetRenderError(context->T);
|
luax_geterror(T);
|
||||||
|
luax_clearerror(T);
|
||||||
if (lua_resume(context->T, coroutineArgs) != LUA_YIELD) {
|
if (lua_resume(T, 1) != LUA_YIELD) {
|
||||||
bool restart = lua_type(context->T, -1) == LUA_TSTRING && !strcmp(lua_tostring(context->T, -1), "restart");
|
bool restart = lua_type(T, -1) == LUA_TSTRING && !strcmp(lua_tostring(T, -1), "restart");
|
||||||
int status = lua_tonumber(context->T, -1);
|
int status = lua_tonumber(T, -1);
|
||||||
|
|
||||||
lua_close(context->L);
|
lua_close(context->L);
|
||||||
emscripten_cancel_main_loop();
|
emscripten_cancel_main_loop();
|
||||||
|
|
Loading…
Reference in a new issue