mirror of https://github.com/bjornbytes/lovr.git
Fix module destruction;
There is a problem when a Thread stops: it destroys all of the modules that it required. This is because we unconditionally call luax_atexit when modules are required, and when the thread lua_State dies it takes all of the modules with it. To fix this, lovr<Module>Init will return whether or not initialization successfully happened, which provides us with enough info to know if we should place the luax_atexit destructor
This commit is contained in:
parent
465e5c2010
commit
0e99d47394
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -23,7 +23,7 @@ typedef struct {
|
|||
|
||||
ALenum lovrAudioConvertFormat(int bitDepth, int channelCount);
|
||||
|
||||
void lovrAudioInit();
|
||||
bool lovrAudioInit();
|
||||
void lovrAudioDestroy();
|
||||
void lovrAudioUpdate();
|
||||
void lovrAudioAdd(Source* source);
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -154,7 +154,7 @@ typedef struct {
|
|||
} GraphicsState;
|
||||
|
||||
// Base
|
||||
void lovrGraphicsInit(bool gammaCorrect);
|
||||
bool lovrGraphicsInit(bool gammaCorrect);
|
||||
void lovrGraphicsDestroy();
|
||||
void lovrGraphicsPresent();
|
||||
void lovrGraphicsSetWindow(WindowFlags* flags);
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -22,7 +22,7 @@ typedef struct {
|
|||
bool running;
|
||||
} Thread;
|
||||
|
||||
void lovrThreadInit();
|
||||
bool lovrThreadInit();
|
||||
void lovrThreadDeinit();
|
||||
struct Channel* lovrThreadGetChannel(const char* name);
|
||||
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -16,7 +16,7 @@ typedef struct {
|
|||
int fps;
|
||||
} TimerState;
|
||||
|
||||
void lovrTimerInit();
|
||||
bool lovrTimerInit();
|
||||
void lovrTimerDestroy();
|
||||
double lovrTimerGetDelta();
|
||||
double lovrTimerGetTime();
|
||||
|
|
Loading…
Reference in New Issue