Browse Source

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

Alex Szpakowski 10 years ago
parent
commit
6e92bd8302
2 changed files with 67 additions and 44 deletions
  1. 2 4
      src/common/runtime.cpp
  2. 65 40
      src/modules/physics/box2d/World.cpp

+ 2 - 4
src/common/runtime.cpp

@@ -70,7 +70,7 @@ static int w__eq(lua_State *L)
 
 Reference *luax_refif(lua_State *L, int type)
 {
-	Reference *r = 0;
+	Reference *r = nullptr;
 
 	// Create a reference only if the test succeeds.
 	if (lua_type(L, -1) == type)
@@ -84,9 +84,7 @@ Reference *luax_refif(lua_State *L, int type)
 void luax_printstack(lua_State *L)
 {
 	for (int i = 1; i<=lua_gettop(L); i++)
-	{
 		std::cout << i << " - " << luaL_typename(L, i) << std::endl;
-	}
 }
 
 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)
 		return;
 
-	for (; l->name != 0; l++)
+	for (; l->name != nullptr; l++)
 	{
 		lua_pushcfunction(L, l->func);
 		lua_setfield(L, -2, l->name);

+ 65 - 40
src/modules/physics/box2d/World.cpp

@@ -35,20 +35,20 @@ namespace box2d
 {
 
 World::ContactCallback::ContactCallback()
-	: ref(0)
+	: ref(nullptr)
 {
 }
 
 World::ContactCallback::~ContactCallback()
 {
-	if (ref != 0)
+	if (ref != nullptr)
 		delete ref;
 }
 
 void World::ContactCallback::process(b2Contact *contact, const b2ContactImpulse *impulse)
 {
 	// Process contacts.
-	if (ref != 0)
+	if (ref != nullptr)
 	{
 		lua_State *L = ref->getL();
 		ref->push();
@@ -56,7 +56,7 @@ void World::ContactCallback::process(b2Contact *contact, const b2ContactImpulse
 		// Push first fixture.
 		{
 			Fixture *a = (Fixture *)Memoizer::find(contact->GetFixtureA());
-			if (a != 0)
+			if (a != nullptr)
 				luax_pushtype(L, PHYSICS_FIXTURE_ID, a);
 			else
 				throw love::Exception("A fixture has escaped Memoizer!");
@@ -65,7 +65,7 @@ void World::ContactCallback::process(b2Contact *contact, const b2ContactImpulse
 		// Push second fixture.
 		{
 			Fixture *b = (Fixture *)Memoizer::find(contact->GetFixtureB());
-			if (b != 0)
+			if (b != nullptr)
 				luax_pushtype(L, PHYSICS_FIXTURE_ID, b);
 			else
 				throw love::Exception("A fixture has escaped Memoizer!");
@@ -96,13 +96,13 @@ void World::ContactCallback::process(b2Contact *contact, const b2ContactImpulse
 }
 
 World::ContactFilter::ContactFilter()
-	: ref(0)
+	: ref(nullptr)
 {
 }
 
 World::ContactFilter::~ContactFilter()
 {
-	if (ref != 0)
+	if (ref != nullptr)
 		delete ref;
 }
 
@@ -124,7 +124,7 @@ bool World::ContactFilter::process(Fixture *a, Fixture *b)
 		(filterB[1] & filterA[0]) == 0)
 		return false; // A and B aren't set to collide
 
-	if (ref != 0)
+	if (ref != nullptr)
 	{
 		lua_State *L = ref->getL();
 		ref->push();
@@ -137,19 +137,19 @@ bool World::ContactFilter::process(Fixture *a, Fixture *b)
 }
 
 World::QueryCallback::QueryCallback()
-	: ref(0)
+	: ref(nullptr)
 {
 }
 
 World::QueryCallback::~QueryCallback()
 {
-	if (ref != 0)
+	if (ref != nullptr)
 		delete ref;
 }
 
 bool World::QueryCallback::ReportFixture(b2Fixture *fixture)
 {
-	if (ref != 0)
+	if (ref != nullptr)
 	{
 		lua_State *L = ref->getL();
 		ref->push();
@@ -164,19 +164,19 @@ bool World::QueryCallback::ReportFixture(b2Fixture *fixture)
 }
 
 World::RayCastCallback::RayCastCallback()
-	: ref(0)
+	: ref(nullptr)
 {
 }
 
 World::RayCastCallback::~RayCastCallback()
 {
-	if (ref != 0)
+	if (ref != nullptr)
 		delete ref;
 }
 
 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();
 		ref->push();
@@ -213,7 +213,8 @@ void World::SayGoodbye(b2Joint *joint)
 }
 
 World::World()
-	: world(NULL), destructWorld(false)
+	: world(nullptr)
+	, destructWorld(false)
 {
 	world = new b2World(b2Vec2(0,0));
 	this->retain(); // The Box2D world holds a reference to this World.
@@ -227,7 +228,8 @@ World::World()
 }
 
 World::World(b2Vec2 gravity, bool sleep)
-	: world(NULL), destructWorld(false)
+	: world(nullptr)
+	, destructWorld(false)
 {
 	world = new b2World(Physics::scaleDown(gravity));
 	// 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.
 	for (Body *b : destructBodies)
 	{
-		if (b->body != 0) b->destroy();
+		if (b->body != nullptr) b->destroy();
 		// Release for reference in vector.
 		b->release();
 	}
@@ -314,34 +316,55 @@ bool World::ShouldCollide(b2Fixture *fixtureA, b2Fixture *fixtureB)
 
 bool World::isValid() const
 {
-	return world != 0;
+	return world != nullptr;
 }
 
 int World::setCallbacks(lua_State *L)
 {
-	int n = lua_gettop(L);
-	luax_assert_argc(L, 1, 4);
+	int nargs = lua_gettop(L);
 
-	switch (n)
+	for (int i = 1; i <= 4; i++)
 	{
-	case 4:
-		if (postsolve.ref)
-			delete postsolve.ref;
-		postsolve.ref = luax_refif(L, LUA_TFUNCTION);
-	case 3:
-		if (presolve.ref)
-			delete presolve.ref;
-		presolve.ref = luax_refif(L, LUA_TFUNCTION);
-	case 2:
-		if (end.ref)
-			delete end.ref;
-		end.ref = luax_refif(L, LUA_TFUNCTION);
-	case 1:
-		if (begin.ref)
-			delete begin.ref;
+		if (!lua_isnoneornil(L, i))
+			luaL_checktype(L, i, LUA_TFUNCTION);
+	}
+
+	delete begin.ref;
+	begin.ref = nullptr;
+
+	delete end.ref;
+	end.ref = nullptr;
+
+	delete presolve.ref;
+	presolve.ref = nullptr;
+
+	delete postsolve.ref;
+	postsolve.ref = nullptr;
+
+	if (nargs >= 1)
+	{
+		lua_pushvalue(L, 1);
 		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;
 }
 
@@ -356,7 +379,9 @@ int World::getCallbacks(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)
 		delete filter.ref;
 	filter.ref = luax_refif(L, LUA_TFUNCTION);
@@ -486,7 +511,6 @@ b2Body *World::getGroundBody() const
 
 int World::queryBoundingBox(lua_State *L)
 {
-	luax_assert_argc(L, 5);
 	b2AABB box;
 	float lx = (float)luaL_checknumber(L, 1);
 	float ly = (float)luaL_checknumber(L, 2);
@@ -494,6 +518,7 @@ int World::queryBoundingBox(lua_State *L)
 	float uy = (float)luaL_checknumber(L, 4);
 	box.lowerBound = Physics::scaleDown(b2Vec2(lx, ly));
 	box.upperBound = Physics::scaleDown(b2Vec2(ux, uy));
+	luaL_checktype(L, 5, LUA_TFUNCTION);
 	if (query.ref) delete query.ref;
 	query.ref = luax_refif(L, LUA_TFUNCTION);
 	world->QueryAABB(&query, box);
@@ -502,13 +527,13 @@ int World::queryBoundingBox(lua_State *L)
 
 int World::rayCast(lua_State *L)
 {
-	luax_assert_argc(L, 5);
 	float x1 = (float)luaL_checknumber(L, 1);
 	float y1 = (float)luaL_checknumber(L, 2);
 	float x2 = (float)luaL_checknumber(L, 3);
 	float y2 = (float)luaL_checknumber(L, 4);
 	b2Vec2 v1 = Physics::scaleDown(b2Vec2(x1, y1));
 	b2Vec2 v2 = Physics::scaleDown(b2Vec2(x2, y2));
+	luaL_checktype(L, 5, LUA_TFUNCTION);
 	if (raycast.ref)
 		delete raycast.ref;
 	raycast.ref = luax_refif(L, LUA_TFUNCTION);
@@ -541,7 +566,7 @@ void World::destroy()
 	world->DestroyBody(groundBody);
 	Memoizer::remove(world);
 	delete world;
-	world = 0;
+	world = nullptr;
 
 	// Box2D world destroyed. Release its reference.
 	this->release();