mirror of https://github.com/bjornbytes/lovr.git
Fix world/collider memory leaks;
This commit is contained in:
parent
d2b6def5c2
commit
1f00948da0
|
@ -57,6 +57,7 @@ int l_lovrPhysicsNewWorld(lua_State* L) {
|
||||||
}
|
}
|
||||||
World* world = lovrWorldCreate(xg, yg, zg, allowSleep, tags, tagCount);
|
World* world = lovrWorldCreate(xg, yg, zg, allowSleep, tags, tagCount);
|
||||||
luax_pushobject(L, world);
|
luax_pushobject(L, world);
|
||||||
|
lovrRelease(world);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -44,6 +44,7 @@ int l_lovrWorldNewCollider(lua_State* L) {
|
||||||
float z = luaL_optnumber(L, 4, 0);
|
float z = luaL_optnumber(L, 4, 0);
|
||||||
Collider* collider = lovrColliderCreate(world, x, y, z);
|
Collider* collider = lovrColliderCreate(world, x, y, z);
|
||||||
luax_pushobject(L, collider);
|
luax_pushobject(L, collider);
|
||||||
|
lovrRelease(collider);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,6 +59,7 @@ int l_lovrWorldNewBoxCollider(lua_State* L) {
|
||||||
Collider* collider = lovrColliderCreate(world, x, y, z);
|
Collider* collider = lovrColliderCreate(world, x, y, z);
|
||||||
lovrColliderAddShape(collider, lovrBoxShapeCreate(sx, sy, sz));
|
lovrColliderAddShape(collider, lovrBoxShapeCreate(sx, sy, sz));
|
||||||
luax_pushobject(L, collider);
|
luax_pushobject(L, collider);
|
||||||
|
lovrRelease(collider);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -71,6 +73,7 @@ int l_lovrWorldNewCapsuleCollider(lua_State* L) {
|
||||||
Collider* collider = lovrColliderCreate(world, x, y, z);
|
Collider* collider = lovrColliderCreate(world, x, y, z);
|
||||||
lovrColliderAddShape(collider, lovrCapsuleShapeCreate(radius, length));
|
lovrColliderAddShape(collider, lovrCapsuleShapeCreate(radius, length));
|
||||||
luax_pushobject(L, collider);
|
luax_pushobject(L, collider);
|
||||||
|
lovrRelease(collider);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -84,6 +87,7 @@ int l_lovrWorldNewCylinderCollider(lua_State* L) {
|
||||||
Collider* collider = lovrColliderCreate(world, x, y, z);
|
Collider* collider = lovrColliderCreate(world, x, y, z);
|
||||||
lovrColliderAddShape(collider, lovrCylinderShapeCreate(radius, length));
|
lovrColliderAddShape(collider, lovrCylinderShapeCreate(radius, length));
|
||||||
luax_pushobject(L, collider);
|
luax_pushobject(L, collider);
|
||||||
|
lovrRelease(collider);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -96,6 +100,7 @@ int l_lovrWorldNewSphereCollider(lua_State* L) {
|
||||||
Collider* collider = lovrColliderCreate(world, x, y, z);
|
Collider* collider = lovrColliderCreate(world, x, y, z);
|
||||||
lovrColliderAddShape(collider, lovrSphereShapeCreate(radius));
|
lovrColliderAddShape(collider, lovrSphereShapeCreate(radius));
|
||||||
luax_pushobject(L, collider);
|
luax_pushobject(L, collider);
|
||||||
|
lovrRelease(collider);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -85,6 +85,12 @@ void lovrWorldDestroyData(World* world) {
|
||||||
world->space = NULL;
|
world->space = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
while (world->head) {
|
||||||
|
Collider* next = world->head->next;
|
||||||
|
lovrColliderDestroyData(world->head);
|
||||||
|
world->head = next;
|
||||||
|
}
|
||||||
|
|
||||||
if (world->id) {
|
if (world->id) {
|
||||||
dWorldDestroy(world->id);
|
dWorldDestroy(world->id);
|
||||||
world->id = NULL;
|
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) {
|
Collider* lovrColliderCreate(World* world, float x, float y, float z) {
|
||||||
lovrAssert(world, "No world specified");
|
|
||||||
Collider* collider = lovrAlloc(Collider, lovrColliderDestroy);
|
Collider* collider = lovrAlloc(Collider, lovrColliderDestroy);
|
||||||
if (!collider) return NULL;
|
if (!collider) return NULL;
|
||||||
|
|
||||||
|
@ -283,6 +288,18 @@ Collider* lovrColliderCreate(World* world, float x, float y, float z) {
|
||||||
|
|
||||||
lovrColliderSetPosition(collider, x, y, 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;
|
return collider;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -295,10 +312,20 @@ void lovrColliderDestroy(void* ref) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void lovrColliderDestroyData(Collider* collider) {
|
void lovrColliderDestroyData(Collider* collider) {
|
||||||
if (collider->body) {
|
if (!collider->body) {
|
||||||
dBodyDestroy(collider->body);
|
return;
|
||||||
collider->body = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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) {
|
World* lovrColliderGetWorld(Collider* collider) {
|
||||||
|
|
|
@ -25,6 +25,8 @@ typedef enum {
|
||||||
JOINT_SLIDER
|
JOINT_SLIDER
|
||||||
} JointType;
|
} JointType;
|
||||||
|
|
||||||
|
typedef struct Collider Collider;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
Ref ref;
|
Ref ref;
|
||||||
dWorldID id;
|
dWorldID id;
|
||||||
|
@ -33,19 +35,22 @@ typedef struct {
|
||||||
vec_void_t overlaps;
|
vec_void_t overlaps;
|
||||||
map_int_t tags;
|
map_int_t tags;
|
||||||
uint16_t masks[MAX_TAGS];
|
uint16_t masks[MAX_TAGS];
|
||||||
|
Collider* head;
|
||||||
} World;
|
} World;
|
||||||
|
|
||||||
typedef struct {
|
struct Collider {
|
||||||
Ref ref;
|
Ref ref;
|
||||||
dBodyID body;
|
dBodyID body;
|
||||||
World* world;
|
World* world;
|
||||||
|
Collider* prev;
|
||||||
|
Collider* next;
|
||||||
void* userdata;
|
void* userdata;
|
||||||
int tag;
|
int tag;
|
||||||
vec_void_t shapes;
|
vec_void_t shapes;
|
||||||
vec_void_t joints;
|
vec_void_t joints;
|
||||||
float friction;
|
float friction;
|
||||||
float restitution;
|
float restitution;
|
||||||
} Collider;
|
};
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
Ref ref;
|
Ref ref;
|
||||||
|
|
Loading…
Reference in New Issue