Use Box2D's callbacks for destruction of physics objects and wait until the end of the timestep before destroying them.

Merge of box2d-id2 from love-experiments
This commit is contained in:
Bart van Strien
2012-01-08 13:16:50 +01:00
parent 9629e5b233
commit c1f68e058d
34 changed files with 340 additions and 118 deletions
+26 -7
View File
@@ -41,6 +41,8 @@ namespace box2d
b2BodyDef def;
def.position = Physics::scaleDown(p);
body = world->world->CreateBody(&def);
// Box2D body holds a reference to the love Body.
this->retain();
this->setType(type);
Memoizer::add(body, this);
}
@@ -50,13 +52,13 @@ namespace box2d
{
world = (World *)Memoizer::find(b->GetWorld());
world->retain();
// Box2D body holds a reference to the love Body.
this->retain();
Memoizer::add(body, this);
}
Body::~Body()
{
Memoizer::remove(body);
world->world->DestroyBody(body);
world->release();
body = 0;
}
@@ -148,7 +150,8 @@ namespace box2d
Body::Type Body::getType() const
{
switch (body->GetType()) {
switch (body->GetType())
{
case b2_staticBody:
return BODY_STATIC;
break;
@@ -266,7 +269,8 @@ namespace box2d
void Body::setType(Body::Type type)
{
switch (type) {
switch (type)
{
case Body::BODY_STATIC:
body->SetType(b2_staticBody);
break;
@@ -403,9 +407,11 @@ namespace box2d
b2Fixture * f = body->GetFixtureList();
int i = 1;
do {
if (!f) break;
if (!f)
break;
Fixture * fixture = (Fixture *)Memoizer::find(f);
if (!fixture) throw love::Exception("A fixture has escaped Memoizer!");
if (!fixture)
throw love::Exception("A fixture has escaped Memoizer!");
fixture->retain();
luax_newtype(L, "Fixture", PHYSICS_FIXTURE_T, (void*)fixture);
lua_rawseti(L, -2, i);
@@ -431,7 +437,20 @@ namespace box2d
void Body::destroy()
{
world->destroyBody(this);
if (world->world->IsLocked())
{
// Called during time step. Save reference for destruction afterwards.
this->retain();
world->destructBodies.push_back(this);
return;
}
world->world->DestroyBody(body);
Memoizer::remove(body);
body = NULL;
// Box2D body destroyed. Release its reference to the love Body.
this->release();
}
} // box2d
+2 -1
View File
@@ -56,6 +56,7 @@ namespace box2d
friend class CircleShape;
friend class PolygonShape;
friend class Shape;
friend class Fixture;
private:
@@ -386,7 +387,7 @@ namespace box2d
int getFixtureList(lua_State * L) const;
/**
* Mark the body for destruction
* Destroy this body.
**/
void destroy();
@@ -42,8 +42,6 @@ namespace box2d
DistanceJoint::~DistanceJoint()
{
destroyJoint(joint);
joint = 0;
}
void DistanceJoint::setLength(float length)
+33 -11
View File
@@ -39,7 +39,6 @@ namespace box2d
Fixture::Fixture(Body * body, Shape * shape, float density)
: body(body), fixture(NULL)
{
body->retain();
data = new fixtureudata();
data->ref = 0;
b2FixtureDef def;
@@ -47,6 +46,7 @@ namespace box2d
def.userData = (void *)data;
def.density = density;
fixture = body->body->CreateFixture(&def);
this->retain();
Memoizer::add(fixture, this);
}
@@ -55,8 +55,9 @@ namespace box2d
{
data = (fixtureudata *)f->GetUserData();
body = (Body *)Memoizer::find(f->GetBody());
if (!body) body = new Body(f->GetBody());
else body->retain();
if (!body)
body = new Body(f->GetBody());
this->retain();
Memoizer::add(fixture, this);
}
@@ -66,13 +67,9 @@ namespace box2d
delete data->ref;
delete data;
data = 0;
data = NULL;
if (fixture)
body->body->DestroyFixture(fixture);
fixture = 0;
body->release();
fixture = NULL;
}
Shape::Type Fixture::getType() const
@@ -127,12 +124,19 @@ namespace box2d
Shape * Fixture::getShape() const
{
if (!fixture->GetShape()) return NULL;
if (!fixture->GetShape())
return NULL;
Shape * s = (Shape *)Memoizer::find(fixture->GetShape());
if (!s) s = new Shape(fixture->GetShape());
if (!s)
s = new Shape(fixture->GetShape());
return s;
}
bool Fixture::isValid() const
{
return fixture != 0;
}
void Fixture::setFilterData(int * v)
{
b2Filter f;
@@ -300,6 +304,24 @@ namespace box2d
return 4;
}
void Fixture::destroy(bool implicit)
{
if (body->world->world->IsLocked())
{
// Called during time step. Save reference for destruction afterwards.
this->retain();
body->world->destructFixtures.push_back(this);
return;
}
if (!implicit && fixture != 0)
body->body->DestroyFixture(fixture);
Memoizer::remove(fixture);
fixture = NULL;
// Box2D fixture destroyed. Release its reference to the love Fixture.
this->release();
}
} // box2d
} // physics
+11 -1
View File
@@ -62,8 +62,8 @@ namespace box2d
protected:
Body * body;
b2Fixture * fixture;
fixtureudata * data;
b2Fixture * fixture;
public:
@@ -90,6 +90,11 @@ namespace box2d
**/
Shape * getShape() const;
/**
* Returns true if the fixture is active in a Box2D world.
**/
bool isValid() const;
/**
* Checks whether this Fixture acts as a sensor.
* @return True if sensor, false otherwise.
@@ -206,6 +211,11 @@ namespace box2d
* This operation may be expensive.
**/
int getMassData(lua_State * L) const;
/**
* Destroys this fixture.
**/
void destroy(bool implicit = false);
};
} // box2d
@@ -45,8 +45,6 @@ namespace box2d
FrictionJoint::~FrictionJoint()
{
destroyJoint(joint);
joint = 0;
}
void FrictionJoint::setMaxForce(float force)
-2
View File
@@ -46,8 +46,6 @@ namespace box2d
GearJoint::~GearJoint()
{
destroyJoint(joint);
joint = 0;
}
void GearJoint::setRatio(float ratio)
+26 -11
View File
@@ -23,11 +23,15 @@
// STD
#include <bitset>
// LOVE
#include <common/Memoizer.h>
// Module
#include "Body.h"
#include "World.h"
#include "Physics.h"
namespace love
{
namespace physics
@@ -37,24 +41,15 @@ namespace box2d
Joint::Joint(Body * body1)
: body1(body1), body2(0), world(body1->world)
{
body1->retain();
}
Joint::Joint(Body * body1, Body * body2)
: body1(body1), body2(body2), world(body1->world)
{
body1->retain();
body2->retain();
}
Joint::~Joint()
{
if (body1 != 0)
body1->release();
if (body2 != 0)
body2->release();
joint = 0;
}
Joint::Type Joint::getType() const
@@ -86,6 +81,11 @@ namespace box2d
}
}
bool Joint::isValid() const
{
return joint != 0;
}
int Joint::getAnchors(lua_State * L)
{
lua_pushnumber(L, Physics::scaleUp(joint->GetAnchorA().x));
@@ -112,13 +112,28 @@ namespace box2d
b2Joint * Joint::createJoint(b2JointDef * def)
{
joint = world->world->CreateJoint(def);
Memoizer::add(joint, this);
// Box2D joint has a reference to this love Joint.
this->retain();
return joint;
}
void Joint::destroyJoint(b2Joint * joint)
void Joint::destroyJoint(bool implicit)
{
if (joint != NULL)
if (world->world->IsLocked())
{
// Called during time step. Save reference for destruction afterwards.
this->retain();
world->destructJoints.push_back(this);
return;
}
if (!implicit && joint != 0)
world->world->DestroyJoint(joint);
Memoizer::remove(joint);
joint = NULL;
// Release the reference of the Box2D joint.
this->release();
}
bool Joint::isActive() const
+15 -7
View File
@@ -78,6 +78,12 @@ namespace box2d
virtual ~Joint();
/**
* Returns true if the joint is active in a Box2D world.
**/
bool isValid() const;
/**
* Gets the type of joint.
**/
@@ -103,25 +109,27 @@ namespace box2d
bool getCollideConnected() const;
protected:
/**
* Joints require pointers to a Box2D joint objects at
* different polymorphic levels, which is why these function
* were created.
**/
/**
* Destroys the joint. This function was created just to
* get some cinsistency.
**/
void destroyJoint(bool implicit = false);
protected:
/**
* Creates a Joint, and ensures that the parent class
* gets a copy of the pointer.
**/
b2Joint * createJoint(b2JointDef * def);
/**
* Destroys the joint. This function was created just to
* get some cinsistency.
**/
void destroyJoint(b2Joint * joint);
};
} // box2d
-2
View File
@@ -45,8 +45,6 @@ namespace box2d
MouseJoint::~MouseJoint()
{
destroyJoint(joint);
joint = 0;
}
void MouseJoint::setTarget(float x, float y)
@@ -47,8 +47,6 @@ namespace box2d
PrismaticJoint::~PrismaticJoint()
{
destroyJoint(joint);
joint = 0;
}
float PrismaticJoint::getJointTranslation() const
@@ -44,8 +44,6 @@ namespace box2d
PulleyJoint::~PulleyJoint()
{
destroyJoint(joint);
joint = 0;
}
int PulleyJoint::getGroundAnchors(lua_State * L)
@@ -44,8 +44,6 @@ namespace box2d
RevoluteJoint::~RevoluteJoint()
{
destroyJoint(joint);
joint = 0;
}
float RevoluteJoint::getJointAngle() const
-2
View File
@@ -46,8 +46,6 @@ namespace box2d
RopeJoint::~RopeJoint()
{
destroyJoint(joint);
joint = 0;
}
float RopeJoint::getMaxLength() const
-2
View File
@@ -45,8 +45,6 @@ namespace box2d
WeldJoint::~WeldJoint()
{
destroyJoint(joint);
joint = 0;
}
void WeldJoint::setFrequency(float hz)
-2
View File
@@ -44,8 +44,6 @@ namespace box2d
WheelJoint::~WheelJoint()
{
destroyJoint(joint);
joint = 0;
}
float WheelJoint::getJointTranslation() const
+108 -24
View File
@@ -79,7 +79,7 @@ namespace box2d
Contact * c = new Contact(contact);
luax_newtype(L, "Contact", (PHYSICS_CONTACT_T), (void*)c, true);
luax_newtype(L, "Contact", (PHYSICS_CONTACT_T), (void*)c);
int args = 3;
if (impulse)
@@ -97,7 +97,7 @@ namespace box2d
}
World::ContactFilter::ContactFilter()
: ref(0)
: ref(0)
{
}
@@ -122,7 +122,7 @@ namespace box2d
}
World::QueryCallback::QueryCallback()
: ref(0)
: ref(0)
{
}
@@ -139,7 +139,8 @@ namespace box2d
lua_State * L = ref->getL();
ref->push();
Fixture * f = (Fixture *)Memoizer::find(fixture);
if (!f) throw love::Exception("A fixture has escaped Memoizer!");
if (!f)
throw love::Exception("A fixture has escaped Memoizer!");
f->retain();
luax_newtype(L, "Fixture", PHYSICS_FIXTURE_T, (void*)f);
lua_call(L, 1, 1);
@@ -166,7 +167,8 @@ namespace box2d
lua_State * L = ref->getL();
ref->push();
Fixture * f = (Fixture *)Memoizer::find(fixture);
if (!f) throw love::Exception("A fixture has escaped Memoizer!");
if (!f)
throw love::Exception("A fixture has escaped Memoizer!");
f->retain();
luax_newtype(L, "Fixture", PHYSICS_FIXTURE_T, (void*)f);
b2Vec2 scaledPoint = Physics::scaleUp(point);
@@ -182,23 +184,42 @@ namespace box2d
return 0;
}
void World::SayGoodbye(b2Fixture* fixture)
{
Fixture * f = (Fixture *)Memoizer::find(fixture);
// Hint implicit destruction with true.
if (f) f->destroy(true);
}
void World::SayGoodbye(b2Joint* joint)
{
Joint * j = (Joint *)Memoizer::find(joint);
// Hint implicit destruction with true.
if (j) j->destroyJoint(true);
}
World::World()
: world(NULL)
: world(NULL), destructWorld(false)
{
world = new b2World(b2Vec2(0,0));
this->retain(); // The Box2D world holds a reference to this World.
world->SetAllowSleeping(true);
world->SetContactListener(this);
world->SetDestructionListener(this);
b2BodyDef def;
groundBody = world->CreateBody(&def);
Memoizer::add(world, this);
}
World::World(b2Vec2 gravity, bool sleep)
: world(NULL)
: world(NULL), destructWorld(false)
{
world = new b2World(Physics::scaleDown(gravity));
// The Box2D world holds a reference to this World.
this->retain();
world->SetAllowSleeping(sleep);
world->SetContactListener(this);
world->SetDestructionListener(this);
b2BodyDef def;
groundBody = world->CreateBody(&def);
Memoizer::add(world, this);
@@ -206,22 +227,43 @@ namespace box2d
World::~World()
{
world->DestroyBody(groundBody);
Memoizer::remove(world);
delete world;
}
void World::update(float dt)
{
world->Step(dt, 8, 6);
// Really destroy all marked bodies.
// Destroy all objects marked during the time step.
if (destructWorld)
{
destroy();
return;
}
for (std::vector<Body*>::iterator i = destructBodies.begin(); i < destructBodies.end(); i++)
{
Body * b = *i;
if (b->body != 0) b->destroy();
// Release for reference in vector.
b->release();
}
for (std::vector<Fixture*>::iterator i = destructFixtures.begin(); i < destructFixtures.end(); i++)
{
Fixture * f = *i;
if (f->isValid()) f->destroy();
// Release for reference in vector.
f->release();
}
for (std::vector<Joint*>::iterator i = destructJoints.begin(); i < destructJoints.end(); i++)
{
Joint * j = *i;
if (j->isValid()) j->destroyJoint();
// Release for reference in vector.
j->release();
}
destructBodies.clear();
destructFixtures.clear();
destructJoints.clear();
}
void World::BeginContact(b2Contact* contact)
@@ -249,14 +291,21 @@ namespace box2d
{
// Fixtures should be memoized, if we created them
Fixture * a = (Fixture *)Memoizer::find(fixtureA);
if (!a) throw love::Exception("A fixture has escaped Memoizer!");
if (!a)
throw love::Exception("A fixture has escaped Memoizer!");
a->retain();
Fixture * b = (Fixture *)Memoizer::find(fixtureB);
if (!b) throw love::Exception("A fixture has escaped Memoizer!");
if (!b)
throw love::Exception("A fixture has escaped Memoizer!");
b->retain();
return filter.process(a, b);
}
bool World::isValid() const
{
return world != 0;
}
int World::setCallbacks(lua_State * L)
{
int n = lua_gettop(L);
@@ -265,16 +314,20 @@ namespace box2d
switch(n)
{
case 4:
if (postsolve.ref) delete postsolve.ref;
if (postsolve.ref)
delete postsolve.ref;
postsolve.ref = luax_refif(L, LUA_TFUNCTION);
case 3:
if (presolve.ref) delete presolve.ref;
if (presolve.ref)
delete presolve.ref;
presolve.ref = luax_refif(L, LUA_TFUNCTION);
case 2:
if (end.ref) delete end.ref;
if (end.ref)
delete end.ref;
end.ref = luax_refif(L, LUA_TFUNCTION);
case 1:
if (begin.ref) delete begin.ref;
if (begin.ref)
delete begin.ref;
begin.ref = luax_refif(L, LUA_TFUNCTION);
}
@@ -293,7 +346,8 @@ namespace box2d
int World::setContactFilter(lua_State * L)
{
luax_assert_argc(L, 1);
if (filter.ref) delete filter.ref;
if (filter.ref)
delete filter.ref;
filter.ref = luax_refif(L, LUA_TFUNCTION);
return 0;
}
@@ -353,10 +407,13 @@ namespace box2d
b2Body * b = world->GetBodyList();
int i = 1;
do {
if (!b) break;
if (b == groundBody) continue;
if (!b)
break;
if (b == groundBody)
continue;
Body * body = (Body *)Memoizer::find(b);
if (!body) throw love::Exception("A body has escaped Memoizer!");
if (!body)
throw love::Exception("A body has escaped Memoizer!");
body->retain();
luax_newtype(L, "Body", PHYSICS_BODY_T, (void*)body);
lua_rawseti(L, -2, i);
@@ -429,15 +486,42 @@ namespace box2d
float y2 = (float)luaL_checknumber(L, 4);
b2Vec2 v1 = Physics::scaleDown(b2Vec2(x1, y1));
b2Vec2 v2 = Physics::scaleDown(b2Vec2(x2, y2));
if (raycast.ref) delete raycast.ref;
if (raycast.ref)
delete raycast.ref;
raycast.ref = luax_refif(L, LUA_TFUNCTION);
world->RayCast(&raycast, v1, v2);
return 0;
}
void World::destroyBody(Body * b)
void World::destroy()
{
destructBodies.push_back(b);
if (world->IsLocked())
{
destructWorld = true;
return;
}
// Cleaning up the world.
b2Body * b = world->GetBodyList();
while (b)
{
b2Body * t = b;
b = b->GetNext();
if (t == groundBody)
continue;
Body * body = (Body *)Memoizer::find(t);
if (!body)
throw love::Exception("A body has escaped Memoizer!");
body->destroy();
}
world->DestroyBody(groundBody);
Memoizer::remove(world);
delete world;
world = 0;
// Box2D world destroyed. Release its reference.
this->release();
}
} // box2d
+17 -4
View File
@@ -42,6 +42,7 @@ namespace box2d
class Contact;
class Body;
class Fixture;
class Joint;
/**
* The World is the "God" container class,
@@ -54,13 +55,14 @@ namespace box2d
* The world also controls global parameters, like
* gravity.
**/
class World : public Object, public b2ContactListener, public b2ContactFilter
class World : public Object, public b2ContactListener, public b2ContactFilter, public b2DestructionListener
{
// Friends.
friend class Joint;
friend class DistanceJoint;
friend class MouseJoint;
friend class Body;
friend class Fixture;
public:
@@ -110,6 +112,9 @@ namespace box2d
// The list of to be destructed bodies.
std::vector<Body*> destructBodies;
std::vector<Fixture*> destructFixtures;
std::vector<Joint*> destructJoints;
bool destructWorld;
// Contact callbacks.
ContactCallback begin, end, presolve, postsolve;
@@ -152,6 +157,15 @@ namespace box2d
// From b2ContactFilter
bool ShouldCollide(b2Fixture* fixtureA, b2Fixture* fixtureB);
// From b2DestructionListener
void SayGoodbye(b2Fixture* fixture);
void SayGoodbye(b2Joint* joint);
/**
* Returns true if the Box2D world is alive.
**/
bool isValid() const;
/**
* Receives up to four Lua functions as arguments. Each function is
* collision callback for the four events (in order): begin, end,
@@ -261,10 +275,9 @@ namespace box2d
int rayCast(lua_State * L);
/**
* Mark a body for destruction.
* To be called from Body
* Destroy this world.
**/
void destroyBody(Body * b);
void destroy();
};
+13 -7
View File
@@ -28,7 +28,10 @@ namespace box2d
{
Body * luax_checkbody(lua_State * L, int idx)
{
return luax_checktype<Body>(L, idx, "Body", PHYSICS_BODY_T);
Body * b = luax_checktype<Body>(L, idx, "Body", PHYSICS_BODY_T);
if (b->body == 0)
luaL_error(L, "Attempt to use destroyed body.");
return b;
}
int w_Body_getX(lua_State * L)
@@ -509,12 +512,15 @@ namespace box2d
int w_Body_destroy(lua_State * L)
{
Proxy * p = (Proxy *)lua_touserdata(L, 1);
p->own = false;
Body * t = (Body *)p->data;
t->destroy();
Body * t = luax_checkbody(L, 1);
try
{
t->destroy();
}
catch (love::Exception & e)
{
luaL_error(L, "%s", e.what());
}
return 0;
}
@@ -28,7 +28,10 @@ namespace box2d
{
DistanceJoint * luax_checkdistancejoint(lua_State * L, int idx)
{
return luax_checktype<DistanceJoint>(L, idx, "DistanceJoint", PHYSICS_DISTANCE_JOINT_T);
DistanceJoint * j = luax_checktype<DistanceJoint>(L, idx, "DistanceJoint", PHYSICS_DISTANCE_JOINT_T);
if (!j->isValid())
luaL_error(L, "Attempt to use destroyed joint.");
return j;
}
int w_DistanceJoint_setLength(lua_State * L)
+13 -6
View File
@@ -29,7 +29,10 @@ namespace box2d
{
Fixture * luax_checkfixture(lua_State * L, int idx)
{
return luax_checktype<Fixture>(L, idx, "Fixture", PHYSICS_FIXTURE_T);
Fixture * f = luax_checktype<Fixture>(L, idx, "Fixture", PHYSICS_FIXTURE_T);
if (!f->isValid())
luaL_error(L, "Attempt to use destroyed fixture.");
return f;
}
int w_Fixture_getType(lua_State * L)
@@ -251,11 +254,15 @@ namespace box2d
int w_Fixture_destroy(lua_State * L)
{
Proxy * p = (Proxy *)lua_touserdata(L, 1);
p->own = false;
Fixture * t = (Fixture *)p->data;
t->release();
Fixture * t = luax_checkfixture(L, 1);
try
{
t->destroy();
}
catch (love::Exception & e)
{
luaL_error(L, "%s", e.what());
}
return 0;
}
@@ -28,7 +28,10 @@ namespace box2d
{
FrictionJoint * luax_checkfrictionjoint(lua_State * L, int idx)
{
return luax_checktype<FrictionJoint>(L, idx, "FrictionJoint", PHYSICS_FRICTION_JOINT_T);
FrictionJoint * j = luax_checktype<FrictionJoint>(L, idx, "FrictionJoint", PHYSICS_FRICTION_JOINT_T);
if (!j->isValid())
luaL_error(L, "Attempt to use destroyed joint.");
return j;
}
int w_FrictionJoint_setMaxForce(lua_State * L)
+4 -1
View File
@@ -28,7 +28,10 @@ namespace box2d
{
GearJoint * luax_checkgearjoint(lua_State * L, int idx)
{
return luax_checktype<GearJoint>(L, idx, "GearJoint", PHYSICS_GEAR_JOINT_T);
GearJoint * j = luax_checktype<GearJoint>(L, idx, "GearJoint", PHYSICS_GEAR_JOINT_T);
if (!j->isValid())
luaL_error(L, "Attempt to use destroyed joint.");
return j;
}
int w_GearJoint_setRatio(lua_State * L)
+13 -7
View File
@@ -30,7 +30,10 @@ namespace box2d
{
Joint * luax_checkjoint(lua_State * L, int idx)
{
return luax_checktype<Joint>(L, idx, "Joint", PHYSICS_JOINT_T);
Joint * t = luax_checktype<Joint>(L, idx, "Joint", PHYSICS_JOINT_T);
if (!t->isValid())
luaL_error(L, "Attempt to use destroyed joint.");
return t;
}
int w_Joint_getType(lua_State * L)
@@ -73,12 +76,15 @@ namespace box2d
int w_Joint_destroy(lua_State * L)
{
Proxy * p = (Proxy *)lua_touserdata(L, 1);
p->own = false;
Joint * t = (Joint *)p->data;
t->release();
Joint * t = luax_checkjoint(L, 1);
try
{
t->destroyJoint();
}
catch (love::Exception & e)
{
luaL_error(L, "%s", e.what());
}
return 0;
}
@@ -28,7 +28,10 @@ namespace box2d
{
MouseJoint * luax_checkmousejoint(lua_State * L, int idx)
{
return luax_checktype<MouseJoint>(L, idx, "MouseJoint", PHYSICS_MOUSE_JOINT_T);
MouseJoint * j = luax_checktype<MouseJoint>(L, idx, "MouseJoint", PHYSICS_MOUSE_JOINT_T);
if (!j->isValid())
luaL_error(L, "Attempt to use destroyed joint.");
return j;
}
int w_MouseJoint_setTarget(lua_State * L)
+1 -1
View File
@@ -378,7 +378,7 @@ namespace box2d
{
Physics::setMeter(arg1);
}
catch (love::Exception e)
catch (love::Exception & e)
{
return luaL_error(L, e.what());
}
@@ -28,7 +28,10 @@ namespace box2d
{
PrismaticJoint * luax_checkprismaticjoint(lua_State * L, int idx)
{
return luax_checktype<PrismaticJoint>(L, idx, "PrismaticJoint", PHYSICS_PRISMATIC_JOINT_T);
PrismaticJoint * j = luax_checktype<PrismaticJoint>(L, idx, "PrismaticJoint", PHYSICS_PRISMATIC_JOINT_T);
if (!j->isValid())
luaL_error(L, "Attempt to use destroyed joint.");
return j;
}
int w_PrismaticJoint_getJointTranslation(lua_State * L)
@@ -28,7 +28,10 @@ namespace box2d
{
PulleyJoint * luax_checkpulleyjoint(lua_State * L, int idx)
{
return luax_checktype<PulleyJoint>(L, idx, "PulleyJoint", PHYSICS_PULLEY_JOINT_T);
PulleyJoint * j = luax_checktype<PulleyJoint>(L, idx, "PulleyJoint", PHYSICS_PULLEY_JOINT_T);
if (!j->isValid())
luaL_error(L, "Attempt to use destroyed joint.");
return j;
}
int w_PulleyJoint_getGroundAnchors(lua_State * L)
@@ -28,7 +28,10 @@ namespace box2d
{
RevoluteJoint * luax_checkrevolutejoint(lua_State * L, int idx)
{
return luax_checktype<RevoluteJoint>(L, idx, "RevoluteJoint", PHYSICS_REVOLUTE_JOINT_T);
RevoluteJoint * j = luax_checktype<RevoluteJoint>(L, idx, "RevoluteJoint", PHYSICS_REVOLUTE_JOINT_T);
if (!j->isValid())
luaL_error(L, "Attempt to use destroyed joint.");
return j;
}
int w_RevoluteJoint_getJointAngle(lua_State * L)
+4 -1
View File
@@ -28,7 +28,10 @@ namespace box2d
{
RopeJoint * luax_checkropejoint(lua_State * L, int idx)
{
return luax_checktype<RopeJoint>(L, idx, "RopeJoint", PHYSICS_ROPE_JOINT_T);
RopeJoint * j = luax_checktype<RopeJoint>(L, idx, "RopeJoint", PHYSICS_ROPE_JOINT_T);
if (!j->isValid())
luaL_error(L, "Attempt to use destroyed joint.");
return j;
}
int w_RopeJoint_getMaxLength(lua_State * L)
+4 -1
View File
@@ -28,7 +28,10 @@ namespace box2d
{
WeldJoint * luax_checkweldjoint(lua_State * L, int idx)
{
return luax_checktype<WeldJoint>(L, idx, "WeldJoint", PHYSICS_WELD_JOINT_T);
WeldJoint * j = luax_checktype<WeldJoint>(L, idx, "WeldJoint", PHYSICS_WELD_JOINT_T);
if (!j->isValid())
luaL_error(L, "Attempt to use destroyed joint.");
return j;
}
int w_WeldJoint_setFrequency(lua_State * L)
@@ -28,7 +28,10 @@ namespace box2d
{
WheelJoint * luax_checkwheeljoint(lua_State * L, int idx)
{
return luax_checktype<WheelJoint>(L, idx, "WheelJoint", PHYSICS_WHEEL_JOINT_T);
WheelJoint * j = luax_checktype<WheelJoint>(L, idx, "WheelJoint", PHYSICS_WHEEL_JOINT_T);
if (!j->isValid())
luaL_error(L, "Attempt to use destroyed joint.");
return j;
}
int w_WheelJoint_getJointTranslation(lua_State * L)
+20 -1
View File
@@ -29,7 +29,10 @@ namespace box2d
World * luax_checkworld(lua_State * L, int idx)
{
return luax_checktype<World>(L, idx, "World", PHYSICS_WORLD_T);
World * w = luax_checktype<World>(L, idx, "World", PHYSICS_WORLD_T);
if (!w->isValid())
luaL_error(L, "Attempt to use destroyed world.");
return w;
}
int w_World_update(lua_State * L)
@@ -162,6 +165,21 @@ namespace box2d
ASSERT_GUARD(return t->rayCast(L);)
}
int w_World_destroy(lua_State * L)
{
World * t = luax_checkworld(L, 1);
try
{
t->destroy();
}
catch (love::Exception & e)
{
luaL_error(L, "%s", e.what());
}
return 0;
}
static const luaL_Reg functions[] = {
{ "update", w_World_update },
{ "setCallbacks", w_World_setCallbacks },
@@ -181,6 +199,7 @@ namespace box2d
{ "getContactList", w_World_getContactList },
{ "queryBoundingBox", w_World_queryBoundingBox },
{ "rayCast", w_World_rayCast },
{ "destroy", w_World_destroy },
{ 0, 0 }
};
+2
View File
@@ -23,6 +23,7 @@
// LOVE
#include <common/runtime.h>
#include <common/Exception.h>
#include "World.h"
#include "wrap_Physics.h"
@@ -51,6 +52,7 @@ namespace box2d
int w_World_getContactList(lua_State * L);
int w_World_queryBoundingBox(lua_State * L);
int w_World_rayCast(lua_State * L);
int w_World_destroy(lua_State * L);
extern "C" int luaopen_world(lua_State * L);
} // box2d