Improved the argument type checking for World:setCallbacks, World:setContactFilter, World:queryBoundingBox, and World:rayCast.

This commit is contained in:
Alex Szpakowski
2015-04-27 18:48:13 -03:00
parent 90a3c2b8ba
commit 6e92bd8302
2 changed files with 67 additions and 44 deletions
+2 -4
View File
@@ -70,7 +70,7 @@ static int w__eq(lua_State *L)
Reference *luax_refif(lua_State *L, int type) Reference *luax_refif(lua_State *L, int type)
{ {
Reference *r = 0; Reference *r = nullptr;
// Create a reference only if the test succeeds. // Create a reference only if the test succeeds.
if (lua_type(L, -1) == type) if (lua_type(L, -1) == type)
@@ -84,9 +84,7 @@ Reference *luax_refif(lua_State *L, int type)
void luax_printstack(lua_State *L) void luax_printstack(lua_State *L)
{ {
for (int i = 1; i<=lua_gettop(L); i++) for (int i = 1; i<=lua_gettop(L); i++)
{
std::cout << i << " - " << luaL_typename(L, i) << std::endl; std::cout << i << " - " << luaL_typename(L, i) << std::endl;
}
} }
bool luax_toboolean(lua_State *L, int idx) bool luax_toboolean(lua_State *L, int idx)
@@ -193,7 +191,7 @@ void luax_setfuncs(lua_State *L, const luaL_Reg *l)
if (l == 0) if (l == 0)
return; return;
for (; l->name != 0; l++) for (; l->name != nullptr; l++)
{ {
lua_pushcfunction(L, l->func); lua_pushcfunction(L, l->func);
lua_setfield(L, -2, l->name); lua_setfield(L, -2, l->name);
+65 -40
View File
@@ -35,20 +35,20 @@ namespace box2d
{ {
World::ContactCallback::ContactCallback() World::ContactCallback::ContactCallback()
: ref(0) : ref(nullptr)
{ {
} }
World::ContactCallback::~ContactCallback() World::ContactCallback::~ContactCallback()
{ {
if (ref != 0) if (ref != nullptr)
delete ref; delete ref;
} }
void World::ContactCallback::process(b2Contact *contact, const b2ContactImpulse *impulse) void World::ContactCallback::process(b2Contact *contact, const b2ContactImpulse *impulse)
{ {
// Process contacts. // Process contacts.
if (ref != 0) if (ref != nullptr)
{ {
lua_State *L = ref->getL(); lua_State *L = ref->getL();
ref->push(); ref->push();
@@ -56,7 +56,7 @@ void World::ContactCallback::process(b2Contact *contact, const b2ContactImpulse
// Push first fixture. // Push first fixture.
{ {
Fixture *a = (Fixture *)Memoizer::find(contact->GetFixtureA()); Fixture *a = (Fixture *)Memoizer::find(contact->GetFixtureA());
if (a != 0) if (a != nullptr)
luax_pushtype(L, PHYSICS_FIXTURE_ID, a); luax_pushtype(L, PHYSICS_FIXTURE_ID, a);
else else
throw love::Exception("A fixture has escaped Memoizer!"); throw love::Exception("A fixture has escaped Memoizer!");
@@ -65,7 +65,7 @@ void World::ContactCallback::process(b2Contact *contact, const b2ContactImpulse
// Push second fixture. // Push second fixture.
{ {
Fixture *b = (Fixture *)Memoizer::find(contact->GetFixtureB()); Fixture *b = (Fixture *)Memoizer::find(contact->GetFixtureB());
if (b != 0) if (b != nullptr)
luax_pushtype(L, PHYSICS_FIXTURE_ID, b); luax_pushtype(L, PHYSICS_FIXTURE_ID, b);
else else
throw love::Exception("A fixture has escaped Memoizer!"); throw love::Exception("A fixture has escaped Memoizer!");
@@ -96,13 +96,13 @@ void World::ContactCallback::process(b2Contact *contact, const b2ContactImpulse
} }
World::ContactFilter::ContactFilter() World::ContactFilter::ContactFilter()
: ref(0) : ref(nullptr)
{ {
} }
World::ContactFilter::~ContactFilter() World::ContactFilter::~ContactFilter()
{ {
if (ref != 0) if (ref != nullptr)
delete ref; delete ref;
} }
@@ -124,7 +124,7 @@ bool World::ContactFilter::process(Fixture *a, Fixture *b)
(filterB[1] & filterA[0]) == 0) (filterB[1] & filterA[0]) == 0)
return false; // A and B aren't set to collide return false; // A and B aren't set to collide
if (ref != 0) if (ref != nullptr)
{ {
lua_State *L = ref->getL(); lua_State *L = ref->getL();
ref->push(); ref->push();
@@ -137,19 +137,19 @@ bool World::ContactFilter::process(Fixture *a, Fixture *b)
} }
World::QueryCallback::QueryCallback() World::QueryCallback::QueryCallback()
: ref(0) : ref(nullptr)
{ {
} }
World::QueryCallback::~QueryCallback() World::QueryCallback::~QueryCallback()
{ {
if (ref != 0) if (ref != nullptr)
delete ref; delete ref;
} }
bool World::QueryCallback::ReportFixture(b2Fixture *fixture) bool World::QueryCallback::ReportFixture(b2Fixture *fixture)
{ {
if (ref != 0) if (ref != nullptr)
{ {
lua_State *L = ref->getL(); lua_State *L = ref->getL();
ref->push(); ref->push();
@@ -164,19 +164,19 @@ bool World::QueryCallback::ReportFixture(b2Fixture *fixture)
} }
World::RayCastCallback::RayCastCallback() World::RayCastCallback::RayCastCallback()
: ref(0) : ref(nullptr)
{ {
} }
World::RayCastCallback::~RayCastCallback() World::RayCastCallback::~RayCastCallback()
{ {
if (ref != 0) if (ref != nullptr)
delete ref; delete ref;
} }
float32 World::RayCastCallback::ReportFixture(b2Fixture *fixture, const b2Vec2 &point, const b2Vec2 &normal, float32 fraction) float32 World::RayCastCallback::ReportFixture(b2Fixture *fixture, const b2Vec2 &point, const b2Vec2 &normal, float32 fraction)
{ {
if (ref != 0) if (ref != nullptr)
{ {
lua_State *L = ref->getL(); lua_State *L = ref->getL();
ref->push(); ref->push();
@@ -213,7 +213,8 @@ void World::SayGoodbye(b2Joint *joint)
} }
World::World() World::World()
: world(NULL), destructWorld(false) : world(nullptr)
, 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. this->retain(); // The Box2D world holds a reference to this World.
@@ -227,7 +228,8 @@ World::World()
} }
World::World(b2Vec2 gravity, bool sleep) World::World(b2Vec2 gravity, bool sleep)
: world(NULL), destructWorld(false) : world(nullptr)
, destructWorld(false)
{ {
world = new b2World(Physics::scaleDown(gravity)); world = new b2World(Physics::scaleDown(gravity));
// The Box2D world holds a reference to this World. // The Box2D world holds a reference to this World.
@@ -252,7 +254,7 @@ void World::update(float dt)
// Destroy all objects marked during the time step. // Destroy all objects marked during the time step.
for (Body *b : destructBodies) for (Body *b : destructBodies)
{ {
if (b->body != 0) b->destroy(); if (b->body != nullptr) b->destroy();
// Release for reference in vector. // Release for reference in vector.
b->release(); b->release();
} }
@@ -314,34 +316,55 @@ bool World::ShouldCollide(b2Fixture *fixtureA, b2Fixture *fixtureB)
bool World::isValid() const bool World::isValid() const
{ {
return world != 0; return world != nullptr;
} }
int World::setCallbacks(lua_State *L) int World::setCallbacks(lua_State *L)
{ {
int n = lua_gettop(L); int nargs = lua_gettop(L);
luax_assert_argc(L, 1, 4);
switch (n) for (int i = 1; i <= 4; i++)
{ {
case 4: if (!lua_isnoneornil(L, i))
if (postsolve.ref) luaL_checktype(L, i, LUA_TFUNCTION);
delete postsolve.ref; }
postsolve.ref = luax_refif(L, LUA_TFUNCTION);
case 3: delete begin.ref;
if (presolve.ref) begin.ref = nullptr;
delete presolve.ref;
presolve.ref = luax_refif(L, LUA_TFUNCTION); delete end.ref;
case 2: end.ref = nullptr;
if (end.ref)
delete end.ref; delete presolve.ref;
end.ref = luax_refif(L, LUA_TFUNCTION); presolve.ref = nullptr;
case 1:
if (begin.ref) delete postsolve.ref;
delete begin.ref; postsolve.ref = nullptr;
if (nargs >= 1)
{
lua_pushvalue(L, 1);
begin.ref = luax_refif(L, LUA_TFUNCTION); begin.ref = luax_refif(L, LUA_TFUNCTION);
} }
if (nargs >= 2)
{
lua_pushvalue(L, 2);
end.ref = luax_refif(L, LUA_TFUNCTION);
}
if (nargs >= 3)
{
lua_pushvalue(L, 3);
presolve.ref = luax_refif(L, LUA_TFUNCTION);
}
if (nargs >= 4)
{
lua_pushvalue(L, 4);
postsolve.ref = luax_refif(L, LUA_TFUNCTION);
}
return 0; return 0;
} }
@@ -356,7 +379,9 @@ int World::getCallbacks(lua_State *L)
int World::setContactFilter(lua_State *L) int World::setContactFilter(lua_State *L)
{ {
luax_assert_argc(L, 1); if (!lua_isnoneornil(L, 1))
luaL_checktype(L, 1, LUA_TFUNCTION);
if (filter.ref) if (filter.ref)
delete filter.ref; delete filter.ref;
filter.ref = luax_refif(L, LUA_TFUNCTION); filter.ref = luax_refif(L, LUA_TFUNCTION);
@@ -486,7 +511,6 @@ b2Body *World::getGroundBody() const
int World::queryBoundingBox(lua_State *L) int World::queryBoundingBox(lua_State *L)
{ {
luax_assert_argc(L, 5);
b2AABB box; b2AABB box;
float lx = (float)luaL_checknumber(L, 1); float lx = (float)luaL_checknumber(L, 1);
float ly = (float)luaL_checknumber(L, 2); float ly = (float)luaL_checknumber(L, 2);
@@ -494,6 +518,7 @@ int World::queryBoundingBox(lua_State *L)
float uy = (float)luaL_checknumber(L, 4); float uy = (float)luaL_checknumber(L, 4);
box.lowerBound = Physics::scaleDown(b2Vec2(lx, ly)); box.lowerBound = Physics::scaleDown(b2Vec2(lx, ly));
box.upperBound = Physics::scaleDown(b2Vec2(ux, uy)); box.upperBound = Physics::scaleDown(b2Vec2(ux, uy));
luaL_checktype(L, 5, LUA_TFUNCTION);
if (query.ref) delete query.ref; if (query.ref) delete query.ref;
query.ref = luax_refif(L, LUA_TFUNCTION); query.ref = luax_refif(L, LUA_TFUNCTION);
world->QueryAABB(&query, box); world->QueryAABB(&query, box);
@@ -502,13 +527,13 @@ int World::queryBoundingBox(lua_State *L)
int World::rayCast(lua_State *L) int World::rayCast(lua_State *L)
{ {
luax_assert_argc(L, 5);
float x1 = (float)luaL_checknumber(L, 1); float x1 = (float)luaL_checknumber(L, 1);
float y1 = (float)luaL_checknumber(L, 2); float y1 = (float)luaL_checknumber(L, 2);
float x2 = (float)luaL_checknumber(L, 3); float x2 = (float)luaL_checknumber(L, 3);
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));
luaL_checktype(L, 5, LUA_TFUNCTION);
if (raycast.ref) if (raycast.ref)
delete raycast.ref; delete raycast.ref;
raycast.ref = luax_refif(L, LUA_TFUNCTION); raycast.ref = luax_refif(L, LUA_TFUNCTION);
@@ -541,7 +566,7 @@ void World::destroy()
world->DestroyBody(groundBody); world->DestroyBody(groundBody);
Memoizer::remove(world); Memoizer::remove(world);
delete world; delete world;
world = 0; world = nullptr;
// Box2D world destroyed. Release its reference. // Box2D world destroyed. Release its reference.
this->release(); this->release();