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