From 6e92bd83025f5ae3b9a162fe8c2395a794ccc3c6 Mon Sep 17 00:00:00 2001 From: Alex Szpakowski Date: Mon, 27 Apr 2015 18:48:13 -0300 Subject: [PATCH] Improved the argument type checking for World:setCallbacks, World:setContactFilter, World:queryBoundingBox, and World:rayCast. --- src/common/runtime.cpp | 6 +- src/modules/physics/box2d/World.cpp | 105 +++++++++++++++++----------- 2 files changed, 67 insertions(+), 44 deletions(-) diff --git a/src/common/runtime.cpp b/src/common/runtime.cpp index 44ee56258..0765a4214 100644 --- a/src/common/runtime.cpp +++ b/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); diff --git a/src/modules/physics/box2d/World.cpp b/src/modules/physics/box2d/World.cpp index b48104b9f..ef151a7a7 100644 --- a/src/modules/physics/box2d/World.cpp +++ b/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();