Fix lots of memory leaks;

Especially when restarting or using threads.
This commit is contained in:
bjorn 2018-03-23 19:31:32 -07:00
parent f94f0cd6c8
commit bdc9b63b8a
8 changed files with 38 additions and 9 deletions

View File

@ -87,6 +87,7 @@ int l_lovrAudioNewSource(lua_State* L) {
Source* source = lovrSourceCreate(stream);
luax_pushtype(L, Source, source);
lovrRelease(source);
lovrRelease(stream);
return 1;
}

View File

@ -823,6 +823,7 @@ int l_lovrGraphicsNewAnimator(lua_State* L) {
Model* model = luax_checktype(L, 1, Model);
Animator* animator = lovrAnimatorCreate(model->modelData);
luax_pushtype(L, Animator, animator);
lovrRelease(animator);
return 1;
}
@ -867,6 +868,7 @@ int l_lovrGraphicsNewCanvas(lua_State* L) {
Canvas* canvas = lovrCanvasCreate(width, height, format, flags);
luax_pushtype(L, Canvas, canvas);
lovrRelease(canvas);
return 1;
}
@ -892,6 +894,7 @@ int l_lovrGraphicsNewFont(lua_State* L) {
Font* font = lovrFontCreate(rasterizer);
luax_pushtype(L, Font, font);
lovrRelease(rasterizer);
lovrRelease(font);
return 1;
}
@ -904,9 +907,10 @@ int l_lovrGraphicsNewMaterial(lua_State* L) {
if (lua_type(L, index) == LUA_TSTRING) {
Blob* blob = luax_readblob(L, index++, "Texture");
TextureData* textureData = lovrTextureDataFromBlob(blob);
lovrRelease(blob);
Texture* texture = lovrTextureCreate(TEXTURE_2D, &textureData, 1, true, true);
lovrMaterialSetTexture(material, TEXTURE_DIFFUSE, texture);
lovrRelease(blob);
lovrRelease(textureData);
lovrRelease(texture);
} else if (lua_isuserdata(L, index)) {
Texture* texture = luax_checktypeof(L, index, Texture);
@ -920,6 +924,7 @@ int l_lovrGraphicsNewMaterial(lua_State* L) {
}
luax_pushtype(L, Material, material);
lovrRelease(material);
return 1;
}
@ -1036,6 +1041,7 @@ int l_lovrGraphicsNewModel(lua_State* L) {
}
luax_pushtype(L, Model, model);
lovrRelease(modelData);
lovrRelease(model);
return 1;
}
@ -1112,6 +1118,7 @@ int l_lovrGraphicsNewTexture(lua_State* L) {
lua_rawgeti(L, 1, i + 1);
TextureData* textureData = luax_checktexturedata(L, -1);
lovrTextureReplacePixels(texture, textureData, i);
lovrRelease(textureData);
lua_pop(L, 1);
}

View File

@ -86,6 +86,7 @@ int l_lovrControllerNewModel(lua_State* L) {
if (modelData) {
Model* model = lovrModelCreate(modelData);
luax_pushtype(L, Model, model);
lovrRelease(modelData);
lovrRelease(model);
} else {
lua_pushnil(L);

View File

@ -521,10 +521,15 @@ void lovrModelDataDestroy(void* ref) {
for (int i = 0; i < modelData->nodeCount; i++) {
vec_deinit(&modelData->nodes[i].children);
vec_deinit(&modelData->nodes[i].primitives);
free((char*) modelData->nodes[i].name);
}
for (int i = 0; i < modelData->primitiveCount; i++) {
map_deinit(&modelData->primitives[i].boneMap);
ModelPrimitive* primitive = &modelData->primitives[i];
for (int j = 0; j < primitive->boneCount; j++) {
free((char*) primitive->bones[j].name);
}
map_deinit(&primitive->boneMap);
}
for (int i = 0; i < modelData->animationCount; i++) {
@ -538,6 +543,7 @@ void lovrModelDataDestroy(void* ref) {
vec_deinit(&channel->scaleKeyframes);
}
map_deinit(&animation->channels);
free((char*) animation->name);
}
for (int i = 0; i < modelData->textures.length; i++) {

View File

@ -206,29 +206,34 @@ void* lovrFilesystemRead(const char* path, size_t* bytesRead) {
// Create file
File* file = lovrFileCreate(path);
if (!file) {
lovrRelease(file);
return NULL;
}
// Open it
if (lovrFileOpen(file, OPEN_READ)) {
lovrRelease(file);
return NULL;
}
// Get file size
size_t size = lovrFileGetSize(file);
if (size == (unsigned int) -1) {
lovrRelease(file);
return NULL;
}
// Allocate buffer
void* data = malloc(size);
if (!data) {
lovrRelease(file);
return NULL;
}
// Perform read
*bytesRead = lovrFileRead(file, data, size);
lovrFileClose(file);
lovrRelease(file);
// Make sure we got everything
if (*bytesRead != (size_t) size) {

View File

@ -43,6 +43,10 @@ void lovrGraphicsDestroy() {
if (!state.initialized) return;
lovrGraphicsSetShader(NULL);
lovrGraphicsSetFont(NULL);
lovrGraphicsSetCanvas(NULL, 0);
for (int i = 0; i < MAX_TEXTURES; i++) {
lovrRelease(state.textures[i]);
}
for (int i = 0; i < DEFAULT_SHADER_COUNT; i++) {
lovrRelease(state.defaultShaders[i]);
}
@ -367,6 +371,7 @@ Font* lovrGraphicsGetFont() {
if (!state.defaultFont) {
Rasterizer* rasterizer = lovrRasterizerCreate(NULL, 32);
state.defaultFont = lovrFontCreate(rasterizer);
lovrRelease(rasterizer);
}
lovrGraphicsSetFont(state.defaultFont);
@ -1159,6 +1164,7 @@ void lovrGraphicsBindTexture(Texture* texture, TextureType type, int slot) {
if (!state.defaultTexture) {
TextureData* textureData = lovrTextureDataGetBlank(1, 1, 0xff, FORMAT_RGBA);
state.defaultTexture = lovrTextureCreate(TEXTURE_2D, &textureData, 1, true, false);
lovrRelease(textureData);
}
texture = state.defaultTexture;

View File

@ -11,8 +11,11 @@
static int errorCount = 0;
static void destroy(int exitCode) {
static void destroy(lua_State* L, int exitCode) {
lovrDestroy();
free(lovrCatch);
lovrCatch = NULL;
lua_close(L);
glfwTerminate();
exit(exitCode);
}
@ -30,7 +33,7 @@ static void handleError(lua_State* L, const char* message) {
} else {
fprintf(stderr, "%s\n", message);
}
destroy(1);
destroy(L, 1);
}
#ifdef EMSCRIPTEN
@ -110,14 +113,14 @@ int main(int argc, char** argv) {
// Failsafe in event that errhand throws
if (errorCount++) {
destroy(1);
destroy(L, 1);
}
lua_pushcfunction(L, luax_getstack);
lua_pushstring(L, lovrErrorMessage);
lua_pcall(L, 1, 1, 0);
handleError(L, lua_tostring(L, -1));
destroy(1);
destroy(L, 1);
}
// lovr.run()
@ -132,14 +135,13 @@ int main(int argc, char** argv) {
int exitCode = 0;
int returnType = lua_type(L, -1);
if (returnType == LUA_TSTRING && 0 == strcmp("restart", lua_tostring(L, -1))) {
lua_close(L);
lovrDestroy();
continue;
}
exitCode = luaL_optint(L, -1, 0);
free(lovrCatch);
lovrCatch = NULL;
destroy(exitCode);
destroy(L, exitCode);
#endif
#ifndef EMSCRIPTEN

View File

@ -70,6 +70,7 @@ void lovrWorldDestroy(void* ref) {
World* world = ref;
lovrWorldDestroyData(world);
vec_deinit(&world->overlaps);
map_deinit(&world->tags);
free(world);
}