diff --git a/src/api/audio.c b/src/api/audio.c index 5ccf70d6..bd9985e9 100644 --- a/src/api/audio.c +++ b/src/api/audio.c @@ -223,9 +223,10 @@ static const luaL_Reg lovrAudio[] = { int luaopen_lovr_audio(lua_State* L) { lua_newtable(L); luaL_register(L, NULL, lovrAudio); - luax_atexit(L, lovrAudioDestroy); luax_registertype(L, "Microphone", lovrMicrophone); luax_registertype(L, "Source", lovrSource); - lovrAudioInit(); + if (lovrAudioInit()) { + luax_atexit(L, lovrAudioDestroy); + } return 1; } diff --git a/src/api/event.c b/src/api/event.c index ec8b2a33..6e07f334 100644 --- a/src/api/event.c +++ b/src/api/event.c @@ -178,12 +178,14 @@ static const luaL_Reg lovrEvent[] = { int luaopen_lovr_event(lua_State* L) { lua_newtable(L); luaL_register(L, NULL, lovrEvent); - luax_atexit(L, lovrEventDestroy); // Store nextEvent in the registry to avoid creating a closure every time we poll for events. lua_pushcfunction(L, nextEvent); pollRef = luaL_ref(L, LUA_REGISTRYINDEX); - lovrEventInit(); + if (lovrEventInit()) { + luax_atexit(L, lovrEventDestroy); + } + return 1; } diff --git a/src/api/filesystem.c b/src/api/filesystem.c index 4007b57d..06f6ec47 100644 --- a/src/api/filesystem.c +++ b/src/api/filesystem.c @@ -360,10 +360,6 @@ static const luaL_Reg lovrFilesystem[] = { }; int luaopen_lovr_filesystem(lua_State* L) { - lua_newtable(L); - luaL_register(L, NULL, lovrFilesystem); - luax_atexit(L, lovrFilesystemDestroy); - lua_getglobal(L, "arg"); if (lua_istable(L, -1)) { lua_getfield(L, -1, "exe"); @@ -372,13 +368,19 @@ int luaopen_lovr_filesystem(lua_State* L) { const char* argGame = lua_tostring(L, -1); lua_getfield(L, -3, "root"); const char* argRoot = luaL_optstring(L, -1, NULL); - lovrFilesystemInit(argExe, argGame, argRoot); + if (lovrFilesystemInit(argExe, argGame, argRoot)) { + luax_atexit(L, lovrFilesystemDestroy); + } lua_pop(L, 4); } else { lua_pop(L, 1); - lovrFilesystemInit(NULL, NULL, NULL); + if (lovrFilesystemInit(NULL, NULL, NULL)) { + luax_atexit(L, lovrFilesystemDestroy); + } } + lua_newtable(L); + luaL_register(L, NULL, lovrFilesystem); luax_registerloader(L, moduleLoader, 2); luax_registerloader(L, libraryLoader, 3); return 1; diff --git a/src/api/graphics.c b/src/api/graphics.c index f706147e..38c57fef 100644 --- a/src/api/graphics.c +++ b/src/api/graphics.c @@ -299,6 +299,7 @@ static int l_lovrGraphicsSetWindow(lua_State* L) { lua_pop(L, 1); lovrGraphicsSetWindow(&flags); + luax_atexit(L, lovrGraphicsDestroy); // The lua_State that creates the window shall be the one to destroy it lovrRelease(textureData); return 0; } @@ -1390,7 +1391,6 @@ static const luaL_Reg lovrGraphics[] = { int luaopen_lovr_graphics(lua_State* L) { lua_newtable(L); luaL_register(L, NULL, lovrGraphics); - luax_atexit(L, lovrGraphicsDestroy); luax_registertype(L, "Animator", lovrAnimator); luax_registertype(L, "Font", lovrFont); luax_registertype(L, "Material", lovrMaterial); diff --git a/src/api/headset.c b/src/api/headset.c index a9f093fd..4cc3dd62 100644 --- a/src/api/headset.c +++ b/src/api/headset.c @@ -349,7 +349,6 @@ static const luaL_Reg lovrHeadset[] = { int luaopen_lovr_headset(lua_State* L) { lua_newtable(L); luaL_register(L, NULL, lovrHeadset); - luax_atexit(L, lovrHeadsetDestroy); luax_registertype(L, "Controller", lovrController); luax_pushconf(L); @@ -391,7 +390,10 @@ int luaopen_lovr_headset(lua_State* L) { lua_pop(L, 1); } - lovrHeadsetInit(drivers.data, drivers.length, offset, msaa); + if (lovrHeadsetInit(drivers.data, drivers.length, offset, msaa)) { + luax_atexit(L, lovrHeadsetDestroy); + } + lovrHeadsetDriver->setMirrored(mirror, mirrorEye); vec_deinit(&drivers); diff --git a/src/api/math.c b/src/api/math.c index 5b2e3962..45d6ff0e 100644 --- a/src/api/math.c +++ b/src/api/math.c @@ -181,10 +181,11 @@ static const luaL_Reg lovrMath[] = { int luaopen_lovr_math(lua_State* L) { lua_newtable(L); luaL_register(L, NULL, lovrMath); - luax_atexit(L, lovrMathDestroy); luax_registertype(L, "Curve", lovrCurve); luax_registertype(L, "RandomGenerator", lovrRandomGenerator); luax_registertype(L, "Transform", lovrTransform); - lovrMathInit(); + if (lovrMathInit()) { + luax_atexit(L, lovrMathDestroy); + } return 1; } diff --git a/src/api/physics.c b/src/api/physics.c index 72875605..625a51b2 100644 --- a/src/api/physics.c +++ b/src/api/physics.c @@ -150,7 +150,6 @@ static const luaL_Reg lovrPhysics[] = { int luaopen_lovr_physics(lua_State* L) { lua_newtable(L); luaL_register(L, NULL, lovrPhysics); - luax_atexit(L, lovrPhysicsDestroy); luax_registertype(L, "World", lovrWorld); luax_registertype(L, "Collider", lovrCollider); luax_extendtype(L, "Joint", "BallJoint", lovrJoint, lovrBallJoint); @@ -161,6 +160,8 @@ int luaopen_lovr_physics(lua_State* L) { luax_extendtype(L, "Shape", "BoxShape", lovrShape, lovrBoxShape); luax_extendtype(L, "Shape", "CapsuleShape", lovrShape, lovrCapsuleShape); luax_extendtype(L, "Shape", "CylinderShape", lovrShape, lovrCylinderShape); - lovrPhysicsInit(); + if (lovrPhysicsInit()) { + luax_atexit(L, lovrPhysicsDestroy); + } return 1; } diff --git a/src/api/thread.c b/src/api/thread.c index 996f0eb2..b10be842 100644 --- a/src/api/thread.c +++ b/src/api/thread.c @@ -66,10 +66,11 @@ static const luaL_Reg lovrThreadModule[] = { int luaopen_lovr_thread(lua_State* L) { lua_newtable(L); - luax_atexit(L, lovrThreadDeinit); luaL_register(L, NULL, lovrThreadModule); luax_registertype(L, "Thread", lovrThread); luax_registertype(L, "Channel", lovrChannel); - lovrThreadInit(); + if (lovrThreadInit()) { + luax_atexit(L, lovrThreadDeinit); + } return 1; } diff --git a/src/api/timer.c b/src/api/timer.c index 18168c63..68e6ac37 100644 --- a/src/api/timer.c +++ b/src/api/timer.c @@ -45,7 +45,8 @@ static const luaL_Reg lovrTimer[] = { int luaopen_lovr_timer(lua_State* L) { lua_newtable(L); luaL_register(L, NULL, lovrTimer); - luax_atexit(L, lovrTimerDestroy); - lovrTimerInit(); + if (lovrTimerInit()) { + luax_atexit(L, lovrTimerDestroy); + } return 1; } diff --git a/src/audio/audio.c b/src/audio/audio.c index a52b589a..8f2120c0 100644 --- a/src/audio/audio.c +++ b/src/audio/audio.c @@ -19,8 +19,8 @@ ALenum lovrAudioConvertFormat(int bitDepth, int channelCount) { return 0; } -void lovrAudioInit() { - if (state.initialized) return; +bool lovrAudioInit() { + if (state.initialized) return false; ALCdevice* device = alcOpenDevice(NULL); lovrAssert(device, "Unable to open default audio device"); @@ -46,7 +46,7 @@ void lovrAudioInit() { quat_set(state.orientation, 0, 0, 0, -1); vec3_set(state.position, 0, 0, 0); vec3_set(state.velocity, 0, 0, 0); - state.initialized = true; + return state.initialized = true; } void lovrAudioDestroy() { diff --git a/src/audio/audio.h b/src/audio/audio.h index e9c7181f..4b4d0dd0 100644 --- a/src/audio/audio.h +++ b/src/audio/audio.h @@ -23,7 +23,7 @@ typedef struct { ALenum lovrAudioConvertFormat(int bitDepth, int channelCount); -void lovrAudioInit(); +bool lovrAudioInit(); void lovrAudioDestroy(); void lovrAudioUpdate(); void lovrAudioAdd(Source* source); diff --git a/src/event/event.c b/src/event/event.c index 6707acc9..a41478d9 100644 --- a/src/event/event.c +++ b/src/event/event.c @@ -5,13 +5,13 @@ static EventState state; -void lovrEventInit() { - if (state.initialized) return; +bool lovrEventInit() { + if (state.initialized) return false; vec_init(&state.pumps); vec_init(&state.events); lovrEventAddPump(lovrPlatformPollEvents); atexit(lovrEventDestroy); - state.initialized = true; + return state.initialized = true; } void lovrEventDestroy() { diff --git a/src/event/event.h b/src/event/event.h index a79e41d9..cd125056 100644 --- a/src/event/event.h +++ b/src/event/event.h @@ -90,7 +90,7 @@ typedef struct { vec_event_t events; } EventState; -void lovrEventInit(); +bool lovrEventInit(); void lovrEventDestroy(); void lovrEventAddPump(EventPump pump); void lovrEventRemovePump(EventPump pump); diff --git a/src/filesystem/filesystem.c b/src/filesystem/filesystem.c index 0edf2784..90ae14d4 100644 --- a/src/filesystem/filesystem.c +++ b/src/filesystem/filesystem.c @@ -31,8 +31,8 @@ const char lovrDirSep = '/'; static FilesystemState state; -void lovrFilesystemInit(const char* argExe, const char* argGame, const char* argRoot) { - if (state.initialized) return; +bool lovrFilesystemInit(const char* argExe, const char* argGame, const char* argRoot) { + if (state.initialized) return false; state.initialized = true; if (!PHYSFS_init(argExe)) { @@ -55,13 +55,15 @@ void lovrFilesystemInit(const char* argExe, const char* argGame, const char* arg if (argGame) { strncpy(state.source, argGame, LOVR_PATH_MAX); if (!lovrFilesystemMount(state.source, NULL, 1, argRoot)) { // Attempt to load from arg. If success, init is done - return; + return true; } } free(state.source); // Couldn't load from argProject, so apparently it isn't the source state.source = NULL; } + + return true; } void lovrFilesystemDestroy() { diff --git a/src/filesystem/filesystem.h b/src/filesystem/filesystem.h index 6858f48c..edb1a6a4 100644 --- a/src/filesystem/filesystem.h +++ b/src/filesystem/filesystem.h @@ -22,7 +22,7 @@ typedef struct { vec_str_t requirePattern[2]; } FilesystemState; -void lovrFilesystemInit(const char* argExe, const char* argGame, const char* argRoot); +bool lovrFilesystemInit(const char* argExe, const char* argGame, const char* argRoot); void lovrFilesystemDestroy(); int lovrFilesystemCreateDirectory(const char* path); int lovrFilesystemGetAppdataDirectory(char* dest, unsigned int size); diff --git a/src/graphics/graphics.c b/src/graphics/graphics.c index 47340132..4f5ece1e 100644 --- a/src/graphics/graphics.c +++ b/src/graphics/graphics.c @@ -24,8 +24,9 @@ static void onResizeWindow(int width, int height) { // Base -void lovrGraphicsInit(bool gammaCorrect) { +bool lovrGraphicsInit(bool gammaCorrect) { state.gammaCorrect = gammaCorrect; + return false; } void lovrGraphicsDestroy() { diff --git a/src/graphics/graphics.h b/src/graphics/graphics.h index 8fe7083f..ed4898ce 100644 --- a/src/graphics/graphics.h +++ b/src/graphics/graphics.h @@ -154,7 +154,7 @@ typedef struct { } GraphicsState; // Base -void lovrGraphicsInit(bool gammaCorrect); +bool lovrGraphicsInit(bool gammaCorrect); void lovrGraphicsDestroy(); void lovrGraphicsPresent(); void lovrGraphicsSetWindow(WindowFlags* flags); diff --git a/src/headset/headset.c b/src/headset/headset.c index b91efe27..20b13985 100644 --- a/src/headset/headset.c +++ b/src/headset/headset.c @@ -4,8 +4,8 @@ HeadsetInterface* lovrHeadsetDriver = NULL; static bool initialized = false; -void lovrHeadsetInit(HeadsetDriver* drivers, int count, float offset, int msaa) { - if (initialized) return; +bool lovrHeadsetInit(HeadsetDriver* drivers, int count, float offset, int msaa) { + if (initialized) return false; initialized = true; for (int i = 0; i < count; i++) { @@ -37,6 +37,7 @@ void lovrHeadsetInit(HeadsetDriver* drivers, int count, float offset, int msaa) } lovrAssert(lovrHeadsetDriver, "No headset driver available, check t.headset.drivers in conf.lua"); + return true; } void lovrHeadsetDestroy() { diff --git a/src/headset/headset.h b/src/headset/headset.h index fe507ec1..7dde50aa 100644 --- a/src/headset/headset.h +++ b/src/headset/headset.h @@ -110,5 +110,5 @@ extern HeadsetInterface lovrHeadsetOculusMobileDriver; // Active driver extern HeadsetInterface* lovrHeadsetDriver; -void lovrHeadsetInit(HeadsetDriver* drivers, int count, float offset, int msaa); +bool lovrHeadsetInit(HeadsetDriver* drivers, int count, float offset, int msaa); void lovrHeadsetDestroy(); diff --git a/src/math/math.c b/src/math/math.c index 7a761621..2256ecce 100644 --- a/src/math/math.c +++ b/src/math/math.c @@ -7,12 +7,12 @@ static MathState state; -void lovrMathInit() { - if (state.initialized) return; +bool lovrMathInit() { + if (state.initialized) return false; state.generator = lovrRandomGeneratorCreate(); Seed seed = { .b64 = (uint64_t) time(0) }; lovrRandomGeneratorSetSeed(state.generator, seed); - state.initialized = true; + return state.initialized = true; } void lovrMathDestroy() { diff --git a/src/math/math.h b/src/math/math.h index fa8f1344..0e51fc1f 100644 --- a/src/math/math.h +++ b/src/math/math.h @@ -9,7 +9,7 @@ typedef struct { RandomGenerator* generator; } MathState; -void lovrMathInit(); +bool lovrMathInit(); void lovrMathDestroy(); RandomGenerator* lovrMathGetRandomGenerator(); void lovrMathOrientationToDirection(float angle, float ax, float ay, float az, vec3 v); diff --git a/src/physics/physics.c b/src/physics/physics.c index df1dd45f..666ab2d2 100644 --- a/src/physics/physics.c +++ b/src/physics/physics.c @@ -31,10 +31,10 @@ static void raycastCallback(void* data, dGeomID a, dGeomID b) { static bool initialized = false; -void lovrPhysicsInit() { - if (initialized) return; +bool lovrPhysicsInit() { + if (initialized) return false; dInitODE(); - initialized = true; + return initialized = true; } void lovrPhysicsDestroy() { diff --git a/src/physics/physics.h b/src/physics/physics.h index 233d7c21..6f456f1c 100644 --- a/src/physics/physics.h +++ b/src/physics/physics.h @@ -85,7 +85,7 @@ typedef struct { void* userdata; } RaycastData; -void lovrPhysicsInit(); +bool lovrPhysicsInit(); void lovrPhysicsDestroy(); World* lovrWorldCreate(float xg, float yg, float zg, bool allowSleep, const char** tags, int tagCount); diff --git a/src/thread/thread.c b/src/thread/thread.c index 5489cc79..f739c3ae 100644 --- a/src/thread/thread.c +++ b/src/thread/thread.c @@ -4,10 +4,10 @@ static ThreadState state; -void lovrThreadInit() { - if (state.initialized) return; +bool lovrThreadInit() { + if (state.initialized) return false; map_init(&state.channels); - state.initialized = true; + return state.initialized = true; } void lovrThreadDeinit() { diff --git a/src/thread/thread.h b/src/thread/thread.h index 8c6595a7..694e7472 100644 --- a/src/thread/thread.h +++ b/src/thread/thread.h @@ -22,7 +22,7 @@ typedef struct { bool running; } Thread; -void lovrThreadInit(); +bool lovrThreadInit(); void lovrThreadDeinit(); struct Channel* lovrThreadGetChannel(const char* name); diff --git a/src/timer/timer.c b/src/timer/timer.c index 483e7f8d..a2030904 100644 --- a/src/timer/timer.c +++ b/src/timer/timer.c @@ -4,10 +4,10 @@ static TimerState state; -void lovrTimerInit() { - if (state.initialized) return; +bool lovrTimerInit() { + if (state.initialized) return false; lovrTimerDestroy(); - state.initialized = true; + return state.initialized = true; } void lovrTimerDestroy() { diff --git a/src/timer/timer.h b/src/timer/timer.h index ca3baeb7..dc8285d6 100644 --- a/src/timer/timer.h +++ b/src/timer/timer.h @@ -16,7 +16,7 @@ typedef struct { int fps; } TimerState; -void lovrTimerInit(); +bool lovrTimerInit(); void lovrTimerDestroy(); double lovrTimerGetDelta(); double lovrTimerGetTime();