Fix world/collider memory leaks;

This commit is contained in:
bjorn 2018-08-18 21:16:19 -07:00
parent d2b6def5c2
commit 1f00948da0
4 changed files with 44 additions and 6 deletions

View File

@ -57,6 +57,7 @@ int l_lovrPhysicsNewWorld(lua_State* L) {
}
World* world = lovrWorldCreate(xg, yg, zg, allowSleep, tags, tagCount);
luax_pushobject(L, world);
lovrRelease(world);
return 1;
}

View File

@ -44,6 +44,7 @@ int l_lovrWorldNewCollider(lua_State* L) {
float z = luaL_optnumber(L, 4, 0);
Collider* collider = lovrColliderCreate(world, x, y, z);
luax_pushobject(L, collider);
lovrRelease(collider);
return 1;
}
@ -58,6 +59,7 @@ int l_lovrWorldNewBoxCollider(lua_State* L) {
Collider* collider = lovrColliderCreate(world, x, y, z);
lovrColliderAddShape(collider, lovrBoxShapeCreate(sx, sy, sz));
luax_pushobject(L, collider);
lovrRelease(collider);
return 1;
}
@ -71,6 +73,7 @@ int l_lovrWorldNewCapsuleCollider(lua_State* L) {
Collider* collider = lovrColliderCreate(world, x, y, z);
lovrColliderAddShape(collider, lovrCapsuleShapeCreate(radius, length));
luax_pushobject(L, collider);
lovrRelease(collider);
return 1;
}
@ -84,6 +87,7 @@ int l_lovrWorldNewCylinderCollider(lua_State* L) {
Collider* collider = lovrColliderCreate(world, x, y, z);
lovrColliderAddShape(collider, lovrCylinderShapeCreate(radius, length));
luax_pushobject(L, collider);
lovrRelease(collider);
return 1;
}
@ -96,6 +100,7 @@ int l_lovrWorldNewSphereCollider(lua_State* L) {
Collider* collider = lovrColliderCreate(world, x, y, z);
lovrColliderAddShape(collider, lovrSphereShapeCreate(radius));
luax_pushobject(L, collider);
lovrRelease(collider);
return 1;
}

View File

@ -85,6 +85,12 @@ void lovrWorldDestroyData(World* world) {
world->space = NULL;
}
while (world->head) {
Collider* next = world->head->next;
lovrColliderDestroyData(world->head);
world->head = next;
}
if (world->id) {
dWorldDestroy(world->id);
world->id = NULL;
@ -268,7 +274,6 @@ int lovrWorldIsCollisionEnabledBetween(World* world, const char* tag1, const cha
}
Collider* lovrColliderCreate(World* world, float x, float y, float z) {
lovrAssert(world, "No world specified");
Collider* collider = lovrAlloc(Collider, lovrColliderDestroy);
if (!collider) return NULL;
@ -283,6 +288,18 @@ Collider* lovrColliderCreate(World* world, float x, float y, float z) {
lovrColliderSetPosition(collider, x, y, z);
// Adjust the world's collider list
if (!collider->world->head) {
collider->world->head = collider;
} else {
collider->next = collider->world->head;
collider->next->prev = collider;
collider->world->head = collider;
}
// The world owns a reference to the collider
lovrRetain(collider);
return collider;
}
@ -295,10 +312,20 @@ void lovrColliderDestroy(void* ref) {
}
void lovrColliderDestroyData(Collider* collider) {
if (collider->body) {
dBodyDestroy(collider->body);
collider->body = NULL;
if (!collider->body) {
return;
}
dBodyDestroy(collider->body);
collider->body = NULL;
if (collider->next) collider->next->prev = collider->prev;
if (collider->prev) collider->prev->next = collider->next;
if (collider->world->head == collider) collider->world->head = collider->next;
collider->next = collider->prev = NULL;
// If the Collider is destroyed, the world lets go of its reference to this Collider
lovrRelease(collider);
}
World* lovrColliderGetWorld(Collider* collider) {

View File

@ -25,6 +25,8 @@ typedef enum {
JOINT_SLIDER
} JointType;
typedef struct Collider Collider;
typedef struct {
Ref ref;
dWorldID id;
@ -33,19 +35,22 @@ typedef struct {
vec_void_t overlaps;
map_int_t tags;
uint16_t masks[MAX_TAGS];
Collider* head;
} World;
typedef struct {
struct Collider {
Ref ref;
dBodyID body;
World* world;
Collider* prev;
Collider* next;
void* userdata;
int tag;
vec_void_t shapes;
vec_void_t joints;
float friction;
float restitution;
} Collider;
};
typedef struct {
Ref ref;