Merge pull request #116 from bjornbytes/headset-render-error

Refactor asynchronous headset render errors;
This commit is contained in:
Bjorn Swenson 2019-03-07 01:24:09 -08:00 committed by GitHub
commit 0927df8246
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 23 additions and 36 deletions

View File

@ -78,17 +78,16 @@ static void renderHelper(void* userdata) {
HeadsetRenderData* renderData = userdata;
lua_State* L = renderData->L;
#ifdef LOVR_HEADSET_HELPER_USES_REGISTRY
lua_getglobal(L, "_lovrHeadsetRenderError");
bool noError = lua_isnil(L, -1);
lua_pop(L, 1);
if (noError) { // Skip if there's already an error waiting to show
luax_geterror(L);
if (lua_isnil(L, -1)) {
lua_pushcfunction(L, luax_getstack);
lua_rawgeti(L, LUA_REGISTRYINDEX, renderData->ref);
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);
#else
lua_call(L, 0, 0);
#endif

View File

@ -262,7 +262,7 @@ bool lovrPlatformHasWindow() {
extern unsigned char boot_lua[];
extern unsigned int boot_lua_len;
static lua_State *L, *Lcoroutine;
static lua_State *L, *T;
static int coroutineRef = 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
Lcoroutine = lua_newthread(L); // Leave L clear to be used by the draw function
lua_atpanic(Lcoroutine, luax_custom_atpanic);
T = lua_newthread(L); // Leave L clear to be used by the draw function
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
lovrLog("\n STATE INIT COMPLETE\n");
@ -401,13 +401,15 @@ void bridgeLovrUpdate(BridgeLovrUpdateData *updateData) {
// Go
if (coroutineStartFunctionRef != LUA_NOREF) {
lua_rawgeti(Lcoroutine, LUA_REGISTRYINDEX, coroutineStartFunctionRef);
luaL_unref (Lcoroutine, LUA_REGISTRYINDEX, coroutineStartFunctionRef);
lua_rawgeti(T, LUA_REGISTRYINDEX, coroutineStartFunctionRef);
luaL_unref (T, LUA_REGISTRYINDEX, coroutineStartFunctionRef);
coroutineStartFunctionRef = LUA_NOREF; // No longer needed
}
int coroutineArgs = luax_pushLovrHeadsetRenderError(Lcoroutine);
if (lua_resume(Lcoroutine, coroutineArgs) != LUA_YIELD) {
if (lua_type(Lcoroutine, -1) == LUA_TSTRING && !strcmp(lua_tostring(Lcoroutine, -1), "restart")) {
luax_geterror(T);
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);
bridgeLovrInitState();
} else {

View File

@ -289,18 +289,6 @@ Color luax_checkcolor(lua_State* L, int index) {
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
void luax_setmainthread(lua_State *L) {
lua_pushthread(L);

View File

@ -10,6 +10,9 @@
#define luax_checktype(L, i, T) ((T*) _luax_checktype(L, i, #T))
#define luax_checkfloat(L, i) (float) luaL_checknumber(L, i)
#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);
int luax_print(lua_State* L);
@ -27,7 +30,6 @@ int luax_getstack_panic(lua_State *L);
void luax_pushconf(lua_State* L);
int luax_setconf(lua_State* L);
Color luax_checkcolor(lua_State* L, int index);
int luax_pushLovrHeadsetRenderError(lua_State *L);
#if LUA_VERSION_NUM < 502
#define LUA_RIDX_MAINTHREAD 1

View File

@ -34,17 +34,13 @@ void lovrDestroy(void* arg) {
static void emscriptenLoop(void* arg) {
lovrEmscriptenContext* context = arg;
lua_getglobal(context->L, "_lovrHeadsetRenderError"); // webvr.c renderCallback failed
bool haveRenderError = !lua_isnil(context->L, -1);
if (!haveRenderError) {
lua_pop(context->L, 1);
}
lua_State* T = context->T;
int coroutineArgs = luax_pushLovrHeadsetRenderError(context->T);
if (lua_resume(context->T, coroutineArgs) != LUA_YIELD) {
bool restart = lua_type(context->T, -1) == LUA_TSTRING && !strcmp(lua_tostring(context->T, -1), "restart");
int status = lua_tonumber(context->T, -1);
luax_geterror(T);
luax_clearerror(T);
if (lua_resume(T, 1) != LUA_YIELD) {
bool restart = lua_type(T, -1) == LUA_TSTRING && !strcmp(lua_tostring(T, -1), "restart");
int status = lua_tonumber(T, -1);
lua_close(context->L);
emscripten_cancel_main_loop();