From 7a866552e91399641d199f62b99342c8f13d137f Mon Sep 17 00:00:00 2001 From: bjorn Date: Wed, 22 Aug 2018 09:29:34 -0700 Subject: [PATCH] Fix remaining physics leaks; --- src/api/physics.c | 8 ++++++++ src/api/types/world.c | 16 +++++++++++---- src/physics/physics.c | 47 +++++++++++++++++++++++++++++-------------- 3 files changed, 52 insertions(+), 19 deletions(-) diff --git a/src/api/physics.c b/src/api/physics.c index db22eed4..0350ebe1 100644 --- a/src/api/physics.c +++ b/src/api/physics.c @@ -69,6 +69,7 @@ int l_lovrPhysicsNewBallJoint(lua_State* L) { float z = luaL_checknumber(L, 5); BallJoint* joint = lovrBallJointCreate(a, b, x, y, z); luax_pushobject(L, joint); + lovrRelease(joint); return 1; } @@ -78,6 +79,7 @@ int l_lovrPhysicsNewBoxShape(lua_State* L) { float z = luaL_optnumber(L, 3, x); BoxShape* box = lovrBoxShapeCreate(x, y, z); luax_pushobject(L, box); + lovrRelease(box); return 1; } @@ -86,6 +88,7 @@ int l_lovrPhysicsNewCapsuleShape(lua_State* L) { float length = luaL_optnumber(L, 2, 1.f); CapsuleShape* capsule = lovrCapsuleShapeCreate(radius, length); luax_pushobject(L, capsule); + lovrRelease(capsule); return 1; } @@ -94,6 +97,7 @@ int l_lovrPhysicsNewCylinderShape(lua_State* L) { float length = luaL_optnumber(L, 2, 1.f); CylinderShape* cylinder = lovrCylinderShapeCreate(radius, length); luax_pushobject(L, cylinder); + lovrRelease(cylinder); return 1; } @@ -108,6 +112,7 @@ int l_lovrPhysicsNewDistanceJoint(lua_State* L) { float z2 = luaL_checknumber(L, 8); DistanceJoint* joint = lovrDistanceJointCreate(a, b, x1, y1, z1, x2, y2, z2); luax_pushobject(L, joint); + lovrRelease(joint); return 1; } @@ -122,6 +127,7 @@ int l_lovrPhysicsNewHingeJoint(lua_State* L) { float az = luaL_checknumber(L, 8); HingeJoint* joint = lovrHingeJointCreate(a, b, x, y, z, ax, ay, az); luax_pushobject(L, joint); + lovrRelease(joint); return 1; } @@ -133,6 +139,7 @@ int l_lovrPhysicsNewSliderJoint(lua_State* L) { float az = luaL_checknumber(L, 5); SliderJoint* joint = lovrSliderJointCreate(a, b, ax, ay, az); luax_pushobject(L, joint); + lovrRelease(joint); return 1; } @@ -140,6 +147,7 @@ int l_lovrPhysicsNewSphereShape(lua_State* L) { float radius = luaL_optnumber(L, 1, 1.f); SphereShape* sphere = lovrSphereShapeCreate(radius); luax_pushobject(L, sphere); + lovrRelease(sphere); return 1; } diff --git a/src/api/types/world.c b/src/api/types/world.c index 3d7e5e10..f42c3631 100644 --- a/src/api/types/world.c +++ b/src/api/types/world.c @@ -57,9 +57,11 @@ int l_lovrWorldNewBoxCollider(lua_State* L) { float sy = luaL_optnumber(L, 6, sx); float sz = luaL_optnumber(L, 7, sx); Collider* collider = lovrColliderCreate(world, x, y, z); - lovrColliderAddShape(collider, lovrBoxShapeCreate(sx, sy, sz)); + BoxShape* shape = lovrBoxShapeCreate(sx, sy, sz); + lovrColliderAddShape(collider, shape); luax_pushobject(L, collider); lovrRelease(collider); + lovrRelease(shape); return 1; } @@ -71,9 +73,11 @@ int l_lovrWorldNewCapsuleCollider(lua_State* L) { float radius = luaL_optnumber(L, 5, 1.f); float length = luaL_optnumber(L, 6, 1.f); Collider* collider = lovrColliderCreate(world, x, y, z); - lovrColliderAddShape(collider, lovrCapsuleShapeCreate(radius, length)); + CapsuleShape* shape = lovrCapsuleShapeCreate(radius, length); + lovrColliderAddShape(collider, shape); luax_pushobject(L, collider); lovrRelease(collider); + lovrRelease(shape); return 1; } @@ -85,9 +89,11 @@ int l_lovrWorldNewCylinderCollider(lua_State* L) { float radius = luaL_optnumber(L, 5, 1.f); float length = luaL_optnumber(L, 6, 1.f); Collider* collider = lovrColliderCreate(world, x, y, z); - lovrColliderAddShape(collider, lovrCylinderShapeCreate(radius, length)); + CylinderShape* shape = lovrCylinderShapeCreate(radius, length); + lovrColliderAddShape(collider, shape); luax_pushobject(L, collider); lovrRelease(collider); + lovrRelease(shape); return 1; } @@ -98,9 +104,11 @@ int l_lovrWorldNewSphereCollider(lua_State* L) { float z = luaL_optnumber(L, 4, 0); float radius = luaL_optnumber(L, 5, 1.f); Collider* collider = lovrColliderCreate(world, x, y, z); - lovrColliderAddShape(collider, lovrSphereShapeCreate(radius)); + SphereShape* shape = lovrSphereShapeCreate(radius); + lovrColliderAddShape(collider, shape); luax_pushobject(L, collider); lovrRelease(collider); + lovrRelease(shape); return 1; } diff --git a/src/physics/physics.c b/src/physics/physics.c index e842a63d..02b6d4c1 100644 --- a/src/physics/physics.c +++ b/src/physics/physics.c @@ -75,8 +75,14 @@ void lovrWorldDestroy(void* ref) { } void lovrWorldDestroyData(World* world) { + while (world->head) { + Collider* next = world->head->next; + lovrColliderDestroyData(world->head); + world->head = next; + } + if (world->contactGroup) { - dJointGroupEmpty(world->contactGroup); + dJointGroupDestroy(world->contactGroup); world->contactGroup = NULL; } @@ -85,12 +91,6 @@ 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; @@ -305,9 +305,9 @@ Collider* lovrColliderCreate(World* world, float x, float y, float z) { void lovrColliderDestroy(void* ref) { Collider* collider = ref; + lovrColliderDestroyData(collider); vec_deinit(&collider->shapes); vec_deinit(&collider->joints); - lovrColliderDestroyData(collider); free(collider); } @@ -316,6 +316,18 @@ void lovrColliderDestroyData(Collider* collider) { return; } + vec_void_t* shapes = lovrColliderGetShapes(collider); + Shape* shape; int i; + vec_foreach(shapes, shape, i) { + lovrColliderRemoveShape(collider, shape); + } + + vec_void_t* joints = lovrColliderGetJoints(collider); + Joint* joint; int j; + vec_foreach(joints, joint, j) { + lovrRelease(joint); + } + dBodyDestroy(collider->body); collider->body = NULL; @@ -333,16 +345,15 @@ World* lovrColliderGetWorld(Collider* collider) { } void lovrColliderAddShape(Collider* collider, Shape* shape) { - shape->collider = collider; - dGeomSetBody(shape->id, collider->body); + lovrRetain(shape); - dSpaceID oldSpace = dGeomGetSpace(shape->id); - dSpaceID newSpace = collider->world->space; - - if (oldSpace && oldSpace != newSpace) { - dSpaceRemove(oldSpace, shape->id); + if (shape->collider) { + lovrColliderRemoveShape(shape->collider, shape); } + shape->collider = collider; + dGeomSetBody(shape->id, collider->body); + dSpaceID newSpace = collider->world->space; dSpaceAdd(newSpace, shape->id); } @@ -350,6 +361,8 @@ void lovrColliderRemoveShape(Collider* collider, Shape* shape) { if (shape->collider == collider) { dSpaceRemove(collider->world->space, shape->id); dGeomSetBody(shape->id, 0); + shape->collider = NULL; + lovrRelease(shape); } } @@ -931,6 +944,7 @@ BallJoint* lovrBallJointCreate(Collider* a, Collider* b, float x, float y, float dJointSetData(joint->id, joint); dJointAttach(joint->id, a->body, b->body); lovrBallJointSetAnchor(joint, x, y, z); + lovrRetain(joint); return joint; } @@ -961,6 +975,7 @@ DistanceJoint* lovrDistanceJointCreate(Collider* a, Collider* b, float x1, float dJointSetData(joint->id, joint); dJointAttach(joint->id, a->body, b->body); lovrDistanceJointSetAnchors(joint, x1, y1, z1, x2, y2, z2); + lovrRetain(joint); return joint; } @@ -1001,6 +1016,7 @@ HingeJoint* lovrHingeJointCreate(Collider* a, Collider* b, float x, float y, flo dJointAttach(joint->id, a->body, b->body); lovrHingeJointSetAnchor(joint, x, y, z); lovrHingeJointSetAxis(joint, ax, ay, az); + lovrRetain(joint); return joint; } @@ -1063,6 +1079,7 @@ SliderJoint* lovrSliderJointCreate(Collider* a, Collider* b, float ax, float ay, dJointSetData(joint->id, joint); dJointAttach(joint->id, a->body, b->body); lovrSliderJointSetAxis(joint, ax, ay, az); + lovrRetain(joint); return joint; }