mirror of
https://github.com/bjornbytes/lovr.git
synced 2024-07-02 12:33:52 +00:00
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);
|
Source* source = lovrSourceCreate(stream);
|
||||||
luax_pushtype(L, Source, source);
|
luax_pushtype(L, Source, source);
|
||||||
lovrRelease(source);
|
lovrRelease(source);
|
||||||
|
lovrRelease(stream);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -823,6 +823,7 @@ int l_lovrGraphicsNewAnimator(lua_State* L) {
|
||||||
Model* model = luax_checktype(L, 1, Model);
|
Model* model = luax_checktype(L, 1, Model);
|
||||||
Animator* animator = lovrAnimatorCreate(model->modelData);
|
Animator* animator = lovrAnimatorCreate(model->modelData);
|
||||||
luax_pushtype(L, Animator, animator);
|
luax_pushtype(L, Animator, animator);
|
||||||
|
lovrRelease(animator);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -867,6 +868,7 @@ int l_lovrGraphicsNewCanvas(lua_State* L) {
|
||||||
|
|
||||||
Canvas* canvas = lovrCanvasCreate(width, height, format, flags);
|
Canvas* canvas = lovrCanvasCreate(width, height, format, flags);
|
||||||
luax_pushtype(L, Canvas, canvas);
|
luax_pushtype(L, Canvas, canvas);
|
||||||
|
lovrRelease(canvas);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -892,6 +894,7 @@ int l_lovrGraphicsNewFont(lua_State* L) {
|
||||||
|
|
||||||
Font* font = lovrFontCreate(rasterizer);
|
Font* font = lovrFontCreate(rasterizer);
|
||||||
luax_pushtype(L, Font, font);
|
luax_pushtype(L, Font, font);
|
||||||
|
lovrRelease(rasterizer);
|
||||||
lovrRelease(font);
|
lovrRelease(font);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -904,9 +907,10 @@ int l_lovrGraphicsNewMaterial(lua_State* L) {
|
||||||
if (lua_type(L, index) == LUA_TSTRING) {
|
if (lua_type(L, index) == LUA_TSTRING) {
|
||||||
Blob* blob = luax_readblob(L, index++, "Texture");
|
Blob* blob = luax_readblob(L, index++, "Texture");
|
||||||
TextureData* textureData = lovrTextureDataFromBlob(blob);
|
TextureData* textureData = lovrTextureDataFromBlob(blob);
|
||||||
lovrRelease(blob);
|
|
||||||
Texture* texture = lovrTextureCreate(TEXTURE_2D, &textureData, 1, true, true);
|
Texture* texture = lovrTextureCreate(TEXTURE_2D, &textureData, 1, true, true);
|
||||||
lovrMaterialSetTexture(material, TEXTURE_DIFFUSE, texture);
|
lovrMaterialSetTexture(material, TEXTURE_DIFFUSE, texture);
|
||||||
|
lovrRelease(blob);
|
||||||
|
lovrRelease(textureData);
|
||||||
lovrRelease(texture);
|
lovrRelease(texture);
|
||||||
} else if (lua_isuserdata(L, index)) {
|
} else if (lua_isuserdata(L, index)) {
|
||||||
Texture* texture = luax_checktypeof(L, index, Texture);
|
Texture* texture = luax_checktypeof(L, index, Texture);
|
||||||
|
@ -920,6 +924,7 @@ int l_lovrGraphicsNewMaterial(lua_State* L) {
|
||||||
}
|
}
|
||||||
|
|
||||||
luax_pushtype(L, Material, material);
|
luax_pushtype(L, Material, material);
|
||||||
|
lovrRelease(material);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1036,6 +1041,7 @@ int l_lovrGraphicsNewModel(lua_State* L) {
|
||||||
}
|
}
|
||||||
|
|
||||||
luax_pushtype(L, Model, model);
|
luax_pushtype(L, Model, model);
|
||||||
|
lovrRelease(modelData);
|
||||||
lovrRelease(model);
|
lovrRelease(model);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -1112,6 +1118,7 @@ int l_lovrGraphicsNewTexture(lua_State* L) {
|
||||||
lua_rawgeti(L, 1, i + 1);
|
lua_rawgeti(L, 1, i + 1);
|
||||||
TextureData* textureData = luax_checktexturedata(L, -1);
|
TextureData* textureData = luax_checktexturedata(L, -1);
|
||||||
lovrTextureReplacePixels(texture, textureData, i);
|
lovrTextureReplacePixels(texture, textureData, i);
|
||||||
|
lovrRelease(textureData);
|
||||||
lua_pop(L, 1);
|
lua_pop(L, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -86,6 +86,7 @@ int l_lovrControllerNewModel(lua_State* L) {
|
||||||
if (modelData) {
|
if (modelData) {
|
||||||
Model* model = lovrModelCreate(modelData);
|
Model* model = lovrModelCreate(modelData);
|
||||||
luax_pushtype(L, Model, model);
|
luax_pushtype(L, Model, model);
|
||||||
|
lovrRelease(modelData);
|
||||||
lovrRelease(model);
|
lovrRelease(model);
|
||||||
} else {
|
} else {
|
||||||
lua_pushnil(L);
|
lua_pushnil(L);
|
||||||
|
|
|
@ -521,10 +521,15 @@ void lovrModelDataDestroy(void* ref) {
|
||||||
for (int i = 0; i < modelData->nodeCount; i++) {
|
for (int i = 0; i < modelData->nodeCount; i++) {
|
||||||
vec_deinit(&modelData->nodes[i].children);
|
vec_deinit(&modelData->nodes[i].children);
|
||||||
vec_deinit(&modelData->nodes[i].primitives);
|
vec_deinit(&modelData->nodes[i].primitives);
|
||||||
|
free((char*) modelData->nodes[i].name);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < modelData->primitiveCount; i++) {
|
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++) {
|
for (int i = 0; i < modelData->animationCount; i++) {
|
||||||
|
@ -538,6 +543,7 @@ void lovrModelDataDestroy(void* ref) {
|
||||||
vec_deinit(&channel->scaleKeyframes);
|
vec_deinit(&channel->scaleKeyframes);
|
||||||
}
|
}
|
||||||
map_deinit(&animation->channels);
|
map_deinit(&animation->channels);
|
||||||
|
free((char*) animation->name);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < modelData->textures.length; i++) {
|
for (int i = 0; i < modelData->textures.length; i++) {
|
||||||
|
|
|
@ -206,29 +206,34 @@ void* lovrFilesystemRead(const char* path, size_t* bytesRead) {
|
||||||
// Create file
|
// Create file
|
||||||
File* file = lovrFileCreate(path);
|
File* file = lovrFileCreate(path);
|
||||||
if (!file) {
|
if (!file) {
|
||||||
|
lovrRelease(file);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Open it
|
// Open it
|
||||||
if (lovrFileOpen(file, OPEN_READ)) {
|
if (lovrFileOpen(file, OPEN_READ)) {
|
||||||
|
lovrRelease(file);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get file size
|
// Get file size
|
||||||
size_t size = lovrFileGetSize(file);
|
size_t size = lovrFileGetSize(file);
|
||||||
if (size == (unsigned int) -1) {
|
if (size == (unsigned int) -1) {
|
||||||
|
lovrRelease(file);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Allocate buffer
|
// Allocate buffer
|
||||||
void* data = malloc(size);
|
void* data = malloc(size);
|
||||||
if (!data) {
|
if (!data) {
|
||||||
|
lovrRelease(file);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Perform read
|
// Perform read
|
||||||
*bytesRead = lovrFileRead(file, data, size);
|
*bytesRead = lovrFileRead(file, data, size);
|
||||||
lovrFileClose(file);
|
lovrFileClose(file);
|
||||||
|
lovrRelease(file);
|
||||||
|
|
||||||
// Make sure we got everything
|
// Make sure we got everything
|
||||||
if (*bytesRead != (size_t) size) {
|
if (*bytesRead != (size_t) size) {
|
||||||
|
|
|
@ -43,6 +43,10 @@ void lovrGraphicsDestroy() {
|
||||||
if (!state.initialized) return;
|
if (!state.initialized) return;
|
||||||
lovrGraphicsSetShader(NULL);
|
lovrGraphicsSetShader(NULL);
|
||||||
lovrGraphicsSetFont(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++) {
|
for (int i = 0; i < DEFAULT_SHADER_COUNT; i++) {
|
||||||
lovrRelease(state.defaultShaders[i]);
|
lovrRelease(state.defaultShaders[i]);
|
||||||
}
|
}
|
||||||
|
@ -367,6 +371,7 @@ Font* lovrGraphicsGetFont() {
|
||||||
if (!state.defaultFont) {
|
if (!state.defaultFont) {
|
||||||
Rasterizer* rasterizer = lovrRasterizerCreate(NULL, 32);
|
Rasterizer* rasterizer = lovrRasterizerCreate(NULL, 32);
|
||||||
state.defaultFont = lovrFontCreate(rasterizer);
|
state.defaultFont = lovrFontCreate(rasterizer);
|
||||||
|
lovrRelease(rasterizer);
|
||||||
}
|
}
|
||||||
|
|
||||||
lovrGraphicsSetFont(state.defaultFont);
|
lovrGraphicsSetFont(state.defaultFont);
|
||||||
|
@ -1159,6 +1164,7 @@ void lovrGraphicsBindTexture(Texture* texture, TextureType type, int slot) {
|
||||||
if (!state.defaultTexture) {
|
if (!state.defaultTexture) {
|
||||||
TextureData* textureData = lovrTextureDataGetBlank(1, 1, 0xff, FORMAT_RGBA);
|
TextureData* textureData = lovrTextureDataGetBlank(1, 1, 0xff, FORMAT_RGBA);
|
||||||
state.defaultTexture = lovrTextureCreate(TEXTURE_2D, &textureData, 1, true, false);
|
state.defaultTexture = lovrTextureCreate(TEXTURE_2D, &textureData, 1, true, false);
|
||||||
|
lovrRelease(textureData);
|
||||||
}
|
}
|
||||||
|
|
||||||
texture = state.defaultTexture;
|
texture = state.defaultTexture;
|
||||||
|
|
16
src/main.c
16
src/main.c
|
@ -11,8 +11,11 @@
|
||||||
|
|
||||||
static int errorCount = 0;
|
static int errorCount = 0;
|
||||||
|
|
||||||
static void destroy(int exitCode) {
|
static void destroy(lua_State* L, int exitCode) {
|
||||||
lovrDestroy();
|
lovrDestroy();
|
||||||
|
free(lovrCatch);
|
||||||
|
lovrCatch = NULL;
|
||||||
|
lua_close(L);
|
||||||
glfwTerminate();
|
glfwTerminate();
|
||||||
exit(exitCode);
|
exit(exitCode);
|
||||||
}
|
}
|
||||||
|
@ -30,7 +33,7 @@ static void handleError(lua_State* L, const char* message) {
|
||||||
} else {
|
} else {
|
||||||
fprintf(stderr, "%s\n", message);
|
fprintf(stderr, "%s\n", message);
|
||||||
}
|
}
|
||||||
destroy(1);
|
destroy(L, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef EMSCRIPTEN
|
#ifdef EMSCRIPTEN
|
||||||
|
@ -110,14 +113,14 @@ int main(int argc, char** argv) {
|
||||||
|
|
||||||
// Failsafe in event that errhand throws
|
// Failsafe in event that errhand throws
|
||||||
if (errorCount++) {
|
if (errorCount++) {
|
||||||
destroy(1);
|
destroy(L, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
lua_pushcfunction(L, luax_getstack);
|
lua_pushcfunction(L, luax_getstack);
|
||||||
lua_pushstring(L, lovrErrorMessage);
|
lua_pushstring(L, lovrErrorMessage);
|
||||||
lua_pcall(L, 1, 1, 0);
|
lua_pcall(L, 1, 1, 0);
|
||||||
handleError(L, lua_tostring(L, -1));
|
handleError(L, lua_tostring(L, -1));
|
||||||
destroy(1);
|
destroy(L, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// lovr.run()
|
// lovr.run()
|
||||||
|
@ -132,14 +135,13 @@ int main(int argc, char** argv) {
|
||||||
int exitCode = 0;
|
int exitCode = 0;
|
||||||
int returnType = lua_type(L, -1);
|
int returnType = lua_type(L, -1);
|
||||||
if (returnType == LUA_TSTRING && 0 == strcmp("restart", lua_tostring(L, -1))) {
|
if (returnType == LUA_TSTRING && 0 == strcmp("restart", lua_tostring(L, -1))) {
|
||||||
|
lua_close(L);
|
||||||
lovrDestroy();
|
lovrDestroy();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
exitCode = luaL_optint(L, -1, 0);
|
exitCode = luaL_optint(L, -1, 0);
|
||||||
free(lovrCatch);
|
destroy(L, exitCode);
|
||||||
lovrCatch = NULL;
|
|
||||||
destroy(exitCode);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef EMSCRIPTEN
|
#ifndef EMSCRIPTEN
|
||||||
|
|
|
@ -70,6 +70,7 @@ void lovrWorldDestroy(void* ref) {
|
||||||
World* world = ref;
|
World* world = ref;
|
||||||
lovrWorldDestroyData(world);
|
lovrWorldDestroyData(world);
|
||||||
vec_deinit(&world->overlaps);
|
vec_deinit(&world->overlaps);
|
||||||
|
map_deinit(&world->tags);
|
||||||
free(world);
|
free(world);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue