mirror of https://github.com/bjornbytes/lovr.git
Fix lots of memory leaks;
Especially when restarting or using threads.
This commit is contained in:
parent
f94f0cd6c8
commit
bdc9b63b8a
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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++) {
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
|
|
16
src/main.c
16
src/main.c
|
@ -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
|
||||
|
|
|
@ -70,6 +70,7 @@ void lovrWorldDestroy(void* ref) {
|
|||
World* world = ref;
|
||||
lovrWorldDestroyData(world);
|
||||
vec_deinit(&world->overlaps);
|
||||
map_deinit(&world->tags);
|
||||
free(world);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue