mirror of https://github.com/bjornbytes/lovr.git
Change the way modules are destroyed;
They are now destroyed explicitly after tearing down the Lua state instead of relying on finalizers. It's definitely annoying to make it coordinated in a centralized way like this instead of being distributed, but there's not really any reliabel way to ensure that graphics objects are destroyed before the graphics module/device is destroyed, which is a problem.
This commit is contained in:
parent
aa4fce2842
commit
019814e2c1
|
@ -28,6 +28,17 @@ LOVR_EXPORT int luaopen_lovr_system(lua_State* L);
|
|||
LOVR_EXPORT int luaopen_lovr_thread(lua_State* L);
|
||||
LOVR_EXPORT int luaopen_lovr_timer(lua_State* L);
|
||||
|
||||
void lovrAudioDestroy(void);
|
||||
void lovrEventDestroy(void);
|
||||
void lovrFilesystemDestroy(void);
|
||||
void lovrGraphicsDestroy(void);
|
||||
void lovrHeadsetDestroy(void);
|
||||
void lovrMathDestroy(void);
|
||||
void lovrPhysicsDestroy(void);
|
||||
void lovrSystemDestroy(void);
|
||||
void lovrThreadModuleDestroy(void);
|
||||
void lovrTimerDestroy(void);
|
||||
|
||||
// Object names are lightuserdata because Variants need a non-Lua string due to threads.
|
||||
static int luax_meta__tostring(lua_State* L) {
|
||||
lua_getfield(L, -1, "__info");
|
||||
|
@ -116,6 +127,40 @@ void luax_preload(lua_State* L) {
|
|||
lua_pop(L, 2);
|
||||
}
|
||||
|
||||
// Destroys modules in a specific order
|
||||
void luax_unload(lua_State* L) {
|
||||
#ifndef LOVR_DISABLE_TIMER
|
||||
lovrTimerDestroy();
|
||||
#endif
|
||||
#ifndef LOVR_DISABLE_MATH
|
||||
lovrMathDestroy();
|
||||
#endif
|
||||
#ifndef LOVR_DISABLE_EVENT
|
||||
lovrEventDestroy();
|
||||
#endif
|
||||
#ifndef LOVR_DISABLE_THREAD
|
||||
lovrThreadModuleDestroy();
|
||||
#endif
|
||||
#ifndef LOVR_DISABLE_PHYSICS
|
||||
lovrPhysicsDestroy();
|
||||
#endif
|
||||
#ifndef LOVR_DISABLE_AUDIO
|
||||
lovrAudioDestroy();
|
||||
#endif
|
||||
#ifndef LOVR_DISABLE_HEADSET
|
||||
lovrHeadsetDestroy();
|
||||
#endif
|
||||
#ifndef LOVR_DISABLE_GRAPHICS
|
||||
lovrGraphicsDestroy();
|
||||
#endif
|
||||
#ifndef LOVR_DISABLE_SYSTEM
|
||||
lovrSystemDestroy();
|
||||
#endif
|
||||
#ifndef LOVR_DISABLE_FILESYSTEM
|
||||
lovrFilesystemDestroy();
|
||||
#endif
|
||||
}
|
||||
|
||||
void _luax_registertype(lua_State* L, const char* name, const luaL_Reg* functions, destructorFn* destructor) {
|
||||
|
||||
// Push metatable
|
||||
|
|
|
@ -111,6 +111,7 @@ typedef struct {
|
|||
#define luax_clearerror(L) lua_pushnil(L), luax_seterror(L)
|
||||
|
||||
void luax_preload(struct lua_State* L);
|
||||
void luax_unload(struct lua_State* L);
|
||||
void _luax_registertype(struct lua_State* L, const char* name, const struct luaL_Reg* functions, void (*destructor)(void*));
|
||||
void* _luax_totype(struct lua_State* L, int index, uint64_t hash);
|
||||
void* _luax_checktype(struct lua_State* L, int index, uint64_t hash, const char* debug);
|
||||
|
|
|
@ -331,7 +331,6 @@ int luaopen_lovr_audio(lua_State* L) {
|
|||
lua_pop(L, 1);
|
||||
|
||||
if (lovrAudioInit(spatializer, sampleRate)) {
|
||||
luax_atexit(L, lovrAudioDestroy);
|
||||
if (start) {
|
||||
lovrAudioSetDevice(AUDIO_PLAYBACK, NULL, 0, NULL, AUDIO_SHARED);
|
||||
lovrAudioStart(AUDIO_PLAYBACK);
|
||||
|
|
|
@ -214,9 +214,6 @@ int luaopen_lovr_event(lua_State* L) {
|
|||
lua_pushcfunction(L, nextEvent);
|
||||
pollRef = luaL_ref(L, LUA_REGISTRYINDEX);
|
||||
|
||||
if (lovrEventInit()) {
|
||||
luax_atexit(L, lovrEventDestroy);
|
||||
}
|
||||
|
||||
lovrEventInit();
|
||||
return 1;
|
||||
}
|
||||
|
|
|
@ -516,9 +516,7 @@ int luaopen_lovr_filesystem(lua_State* L) {
|
|||
}
|
||||
lua_pop(L, 1);
|
||||
|
||||
if (lovrFilesystemInit(archive)) {
|
||||
luax_atexit(L, lovrFilesystemDestroy);
|
||||
}
|
||||
lovrFilesystemInit(archive);
|
||||
|
||||
lua_newtable(L);
|
||||
luax_register(L, lovrFilesystem);
|
||||
|
|
|
@ -658,17 +658,10 @@ static int l_lovrGraphicsInit(lua_State* L) {
|
|||
|
||||
if (shaderCache) {
|
||||
config.cacheData = luax_readfile(".lovrshadercache", &config.cacheSize);
|
||||
luax_atexit(L, luax_writeshadercache);
|
||||
}
|
||||
|
||||
if (lovrGraphicsInit(&config)) {
|
||||
luax_atexit(L, lovrGraphicsDestroy);
|
||||
|
||||
// Finalizers run in the opposite order they were added, so this has to go last
|
||||
if (shaderCache) {
|
||||
luax_atexit(L, luax_writeshadercache);
|
||||
}
|
||||
}
|
||||
|
||||
lovrGraphicsInit(&config);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -672,7 +672,6 @@ int luaopen_lovr_headset(lua_State* L) {
|
|||
}
|
||||
lua_pop(L, 1);
|
||||
|
||||
luax_atexit(L, lovrHeadsetDestroy);
|
||||
lovrHeadsetInit(&config);
|
||||
return 1;
|
||||
}
|
||||
|
|
|
@ -389,9 +389,7 @@ int luaopen_lovr_math(lua_State* L) {
|
|||
lua_pop(L, 1);
|
||||
|
||||
// Module
|
||||
if (lovrMathInit()) {
|
||||
luax_atexit(L, lovrMathDestroy);
|
||||
}
|
||||
lovrMathInit();
|
||||
|
||||
// Each Lua state gets its own thread-local Pool
|
||||
pool = lovrPoolCreate();
|
||||
|
|
|
@ -169,8 +169,6 @@ int luaopen_lovr_physics(lua_State* L) {
|
|||
luax_registertype(L, CapsuleShape);
|
||||
luax_registertype(L, CylinderShape);
|
||||
luax_registertype(L, MeshShape);
|
||||
if (lovrPhysicsInit()) {
|
||||
luax_atexit(L, lovrPhysicsDestroy);
|
||||
}
|
||||
lovrPhysicsInit();
|
||||
return 1;
|
||||
}
|
||||
|
|
|
@ -205,8 +205,6 @@ static const luaL_Reg lovrSystem[] = {
|
|||
int luaopen_lovr_system(lua_State* L) {
|
||||
lua_newtable(L);
|
||||
luax_register(L, lovrSystem);
|
||||
if (lovrSystemInit()) {
|
||||
luax_atexit(L, lovrSystemDestroy);
|
||||
}
|
||||
lovrSystemInit();
|
||||
return 1;
|
||||
}
|
||||
|
|
|
@ -110,8 +110,6 @@ int luaopen_lovr_thread(lua_State* L) {
|
|||
luax_register(L, lovrThreadModule);
|
||||
luax_registertype(L, Thread);
|
||||
luax_registertype(L, Channel);
|
||||
if (lovrThreadModuleInit()) {
|
||||
luax_atexit(L, lovrThreadModuleDestroy);
|
||||
}
|
||||
lovrThreadModuleInit();
|
||||
return 1;
|
||||
}
|
||||
|
|
|
@ -47,8 +47,7 @@ static const luaL_Reg lovrTimer[] = {
|
|||
int luaopen_lovr_timer(lua_State* L) {
|
||||
lua_newtable(L);
|
||||
luax_register(L, lovrTimer);
|
||||
if (lovrTimerInit()) {
|
||||
luax_atexit(L, lovrTimerDestroy);
|
||||
}
|
||||
lovrTimerInit();
|
||||
luax_atexit(L, lovrTimerDestroy);
|
||||
return 1;
|
||||
}
|
||||
|
|
|
@ -132,6 +132,7 @@ int main(int argc, char** argv) {
|
|||
memset(&cookie.value, 0, sizeof(cookie.value));
|
||||
}
|
||||
lua_close(L);
|
||||
luax_unload(L);
|
||||
} while (restart);
|
||||
|
||||
os_destroy();
|
||||
|
@ -147,6 +148,7 @@ void lovrDestroy(void* arg) {
|
|||
lua_State* L = context->L;
|
||||
emscripten_cancel_main_loop();
|
||||
lua_close(L);
|
||||
luax_unload(L);
|
||||
os_destroy();
|
||||
}
|
||||
}
|
||||
|
@ -165,6 +167,7 @@ static void emscriptenLoop(void* arg) {
|
|||
}
|
||||
|
||||
lua_close(context->L);
|
||||
luax_unload(L);
|
||||
emscripten_cancel_main_loop();
|
||||
|
||||
if (restart) {
|
||||
|
|
Loading…
Reference in New Issue