Improve memory management;

This commit is contained in:
bjorn 2016-08-08 13:23:40 -07:00
parent 9c3e4ddec9
commit beacc9d287
10 changed files with 68 additions and 25 deletions

View File

@ -1,4 +1,5 @@
#include "buffer.h"
#include <stdlib.h>
void luax_pushbuffer(lua_State* L, Buffer* buffer) {
Buffer** userdata = (Buffer**) lua_newuserdata(L, sizeof(Buffer*));
@ -11,6 +12,15 @@ Buffer* luax_checkbuffer(lua_State* L, int index) {
return *(Buffer**) luaL_checkudata(L, index, "Buffer");
}
int luax_destroybuffer(lua_State* L) {
Buffer* buffer = luax_checkbuffer(L, 1);
glDeleteBuffers(1, &buffer->vbo);
glDeleteVertexArrays(1, &buffer->vao);
free(buffer->data);
free(buffer);
return 0;
}
int lovrBufferDraw(lua_State* L) {
Buffer* buffer = luax_checkbuffer(L, 1);
@ -41,8 +51,20 @@ int lovrBufferSetVertex(lua_State* L) {
return 0;
}
int lovrBufferGetVertex(lua_State* L) {
Buffer* buffer = luax_checkbuffer(L, 1);
int index = luaL_checkint(L, 2) - 1;
lua_pushnumber(L, buffer->data[3 * index + 0]);
lua_pushnumber(L, buffer->data[3 * index + 1]);
lua_pushnumber(L, buffer->data[3 * index + 2]);
return 3;
}
const luaL_Reg lovrBuffer[] = {
{ "draw", lovrBufferDraw },
{ "setVertex", lovrBufferSetVertex },
{ "getVertex", lovrBufferGetVertex },
{ NULL, NULL }
};

View File

@ -12,8 +12,10 @@ typedef struct {
void luax_pushbuffer(lua_State* L, Buffer* buffer);
Buffer* luax_checkbuffer(lua_State* L, int index);
int luax_destroybuffer(lua_State* L);
int lovrBufferDraw(lua_State* L);
int lovrBufferSetVertex(lua_State* L);
int lovrBufferGetVertex(lua_State* L);
extern const luaL_Reg lovrBuffer[];

View File

@ -73,9 +73,9 @@ int lovrGraphicsNewModel(lua_State* L) {
int lovrGraphicsNewBuffer(lua_State* L) {
int size = luaL_checkint(L, 1);
Buffer* buffer = (Buffer*) malloc(sizeof(Buffer));
Buffer* buffer = malloc(sizeof(Buffer));
buffer->data = (GLfloat*) malloc(size * 3 * sizeof(GLfloat));
buffer->data = malloc(size * 3 * sizeof(GLfloat));
glGenBuffers(1, &buffer->vbo);
glBindBuffer(GL_ARRAY_BUFFER, buffer->vbo);
@ -123,8 +123,8 @@ const luaL_Reg lovrGraphics[] = {
int lovrInitGraphics(lua_State* L) {
lua_newtable(L);
luaL_register(L, NULL, lovrGraphics);
luaRegisterType(L, "Model", lovrModel);
luaRegisterType(L, "Buffer", lovrBuffer);
luaRegisterType(L, "Shader", lovrShader);
luaRegisterType(L, "Model", lovrModel, NULL);
luaRegisterType(L, "Buffer", lovrBuffer, luax_destroybuffer);
luaRegisterType(L, "Shader", lovrShader, luax_destroyshader);
return 1;
}

View File

@ -13,6 +13,13 @@ Shader* luax_checkshader(lua_State* L, int index) {
return *(Shader**) luaL_checkudata(L, index, "Shader");
}
int luax_destroyshader(lua_State* L) {
Shader* shader = luax_checkshader(L, 1);
glDeleteProgram(shader->id);
free(shader);
return 0;
}
GLuint compileShader(GLenum type, const char* source) {
GLuint shader = glCreateShader(type);
@ -57,7 +64,9 @@ GLuint linkShaders(GLuint vertexShader, GLuint fragmentShader) {
error(log);
}
glDetachShader(shader, vertexShader);
glDeleteShader(vertexShader);
glDetachShader(shader, fragmentShader);
glDeleteShader(fragmentShader);
return shader;

View File

@ -9,6 +9,7 @@ typedef struct {
void luax_pushshader(lua_State* L, Shader* shader);
Shader* luax_checkshader(lua_State* L, int index);
int luax_destroyshader(lua_State* L);
GLuint compileShader(GLuint type, const char* filename);
GLuint linkShaders(GLuint vertexShader, GLuint fragmentShader);

View File

@ -15,6 +15,24 @@ Joystick* luax_checkjoystick(lua_State* L, int index) {
return *(Joystick**) luaL_checkudata(L, index, "Joystick");
}
int luax_destroyjoystick(lua_State* L) {
Joystick* joystick = luax_checkjoystick(L, 1);
if (joystick->isTracked) {
osvrClientFreeInterface(ctx, *joystick->osvrTrackerInterface);
for (int i = 0; i < sizeof(joystick->osvrButtonInterfaces); i++) {
osvrClientFreeInterface(ctx, *joystick->osvrButtonInterfaces[i]);
}
for (int i = 0; i < sizeof(joystick->osvrAxisInterfaces); i++) {
osvrClientFreeInterface(ctx, *joystick->osvrAxisInterfaces[i]);
}
}
// The joystick itself is never freed
}
static unsigned char lovrJoystickGetButtonState(Joystick* joystick, int buttonIndex) {
if (joystick->isTracked) {
OSVR_TimeValue timestamp;
@ -43,20 +61,6 @@ static float lovrJoystickGetAxisState(Joystick* joystick, int axisIndex) {
}
}
void lovrJoystickDestroy(Joystick* joystick) {
if (joystick->isTracked) {
osvrClientFreeInterface(ctx, *joystick->osvrTrackerInterface);
for (int i = 0; i < sizeof(joystick->osvrButtonInterfaces); i++) {
osvrClientFreeInterface(ctx, *joystick->osvrButtonInterfaces[i]);
}
for (int i = 0; i < sizeof(joystick->osvrAxisInterfaces); i++) {
osvrClientFreeInterface(ctx, *joystick->osvrAxisInterfaces[i]);
}
}
}
int lovrJoystickIsConnected(Joystick* joystick) {
if (joystick == NULL) {
return 0;

View File

@ -13,8 +13,8 @@ typedef struct {
void luax_pushjoystick(lua_State* L, Joystick* joystick);
Joystick* luax_checkjoystick(lua_State* L, int index);
int luax_destroyjoystick(lua_State* L);
void lovrJoystickDestroy(Joystick* joystick);
int lovrJoystickIsConnected(Joystick* joystick);
int lovrJoystickGetAngularAcceleration(lua_State* L);

View File

@ -67,7 +67,7 @@ const luaL_Reg lovrJoysticks[] = {
int lovrInitJoysticks(lua_State* L) {
lua_newtable(L);
luaL_register(L, NULL, lovrJoysticks);
luaRegisterType(L, "Joystick", lovrJoystick);
luaRegisterType(L, "Joystick", lovrJoystick, luax_destroyjoystick);
glfwSetJoystickCallback(lovrJoysticksOnJoystickChanged);
for (int i = GLFW_JOYSTICK_1; i <= GLFW_JOYSTICK_LAST; i++) {

View File

@ -68,7 +68,7 @@ void luaRegisterModule(lua_State* L, const char* name, const luaL_Reg* module) {
lua_pop(L, 1);
}
void luaRegisterType(lua_State* L, const char* name, const luaL_Reg* functions) {
void luaRegisterType(lua_State* L, const char* name, const luaL_Reg* functions, lua_CFunction gc) {
// Push metatable
luaL_newmetatable(L, name);
@ -78,10 +78,15 @@ void luaRegisterType(lua_State* L, const char* name, const luaL_Reg* functions)
lua_pushvalue(L, -1);
lua_setfield(L, -1, "__index");
// m.__gc = gc
if (gc) {
lua_pushcfunction(L, gc);
lua_setfield(L, -2, "__gc");
}
// m.name = name
lua_pushstring(L, "name");
lua_pushstring(L, name);
lua_settable(L, -3);
lua_setfield(L, -2, "name");
// Register class functions
if (functions) {

View File

@ -5,5 +5,5 @@
void error(const char* format, ...);
char* loadFile(char* filename);
void luaRegisterModule(lua_State* L, const char* name, const luaL_Reg* module);
void luaRegisterType(lua_State* L, const char* name, const luaL_Reg* functions);
void luaRegisterType(lua_State* L, const char* name, const luaL_Reg* functions, lua_CFunction gc);
int luaPreloadModule(lua_State* L, const char* key, lua_CFunction f);