From fe5e7c17e79de8c251964f2612d58d08b9240609 Mon Sep 17 00:00:00 2001 From: Alex Szpakowski Date: Wed, 26 Feb 2014 20:47:05 -0400 Subject: [PATCH] Added Body:setUserData and Body:getUserData (resolves issue #853_ --- src/common/Reference.cpp | 2 +- src/modules/graphics/opengl/Canvas.cpp | 6 ++-- src/modules/physics/box2d/Body.cpp | 44 ++++++++++++++++++++++++- src/modules/physics/box2d/Body.h | 27 ++++++++++++++- src/modules/physics/box2d/Fixture.h | 3 -- src/modules/physics/box2d/wrap_Body.cpp | 16 +++++++++ src/modules/physics/box2d/wrap_Body.h | 2 ++ 7 files changed, 91 insertions(+), 9 deletions(-) diff --git a/src/common/Reference.cpp b/src/common/Reference.cpp index 127023974..d2ea05774 100644 --- a/src/common/Reference.cpp +++ b/src/common/Reference.cpp @@ -26,7 +26,7 @@ namespace love const char REFERENCE_TABLE_NAME[] = "love-references"; Reference::Reference() - : L(0) + : L(nullptr) , idx(LUA_REFNIL) { } diff --git a/src/modules/graphics/opengl/Canvas.cpp b/src/modules/graphics/opengl/Canvas.cpp index daf32429c..d534ac910 100644 --- a/src/modules/graphics/opengl/Canvas.cpp +++ b/src/modules/graphics/opengl/Canvas.cpp @@ -129,7 +129,7 @@ struct FramebufferStrategyGL3 : public FramebufferStrategy glGenRenderbuffers(1, &stencil); glBindRenderbuffer(GL_RENDERBUFFER, stencil); - if (samples > 0) + if (samples > 1) glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples, GL_DEPTH_STENCIL, width, height); else glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_STENCIL, width, height); @@ -249,7 +249,7 @@ struct FramebufferStrategyPackedEXT : public FramebufferStrategy glGenRenderbuffersEXT(1, &stencil); glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, stencil); - if (samples > 0) + if (samples > 1) { glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER, samples, GL_DEPTH_STENCIL, width, height); @@ -358,7 +358,7 @@ struct FramebufferStrategyEXT : public FramebufferStrategyPackedEXT glGenRenderbuffersEXT(1, &stencil); glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, stencil); - if (samples > 0) + if (samples > 1) { glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER, samples, GL_STENCIL_INDEX, width, height); diff --git a/src/modules/physics/box2d/Body.cpp b/src/modules/physics/box2d/Body.cpp index 72565658c..d43830d97 100644 --- a/src/modules/physics/box2d/Body.cpp +++ b/src/modules/physics/box2d/Body.cpp @@ -37,10 +37,14 @@ namespace box2d Body::Body(World *world, b2Vec2 p, Body::Type type) : world(world) + , udata(nullptr) { + udata = new bodyudata(); + udata->ref = nullptr; world->retain(); b2BodyDef def; def.position = Physics::scaleDown(p); + def.userData = (void *) udata; body = world->world->CreateBody(&def); // Box2D body holds a reference to the love Body. this->retain(); @@ -50,7 +54,9 @@ Body::Body(World *world, b2Vec2 p, Body::Type type) Body::Body(b2Body *b) : body(b) + , udata(nullptr) { + udata = (bodyudata *) b->GetUserData(); world = (World *)Memoizer::find(b->GetWorld()); world->retain(); // Box2D body holds a reference to the love Body. @@ -60,8 +66,10 @@ Body::Body(b2Body *b) Body::~Body() { + if (udata != nullptr) + delete udata->ref; + delete udata; world->release(); - body = 0; } float Body::getX() @@ -469,6 +477,40 @@ void Body::destroy() this->release(); } +int Body::setUserData(lua_State *L) +{ + love::luax_assert_argc(L, 1, 1); + + if (udata == nullptr) + { + udata = new bodyudata(); + body->SetUserData((void *) udata); + } + + if (udata->ref != nullptr) + { + // We set the Reference's lua_State to this one before deleting it, so + // it unrefs using the current lua_State's stack. This is necessary + // if setUserData is called in a coroutine. + udata->ref->setL(L); + delete udata->ref; + } + + udata->ref = new Reference(L); + + return 0; +} + +int Body::getUserData(lua_State *L) +{ + if (udata != nullptr && udata->ref != nullptr) + udata->ref->push(L); + else + lua_pushnil(L); + + return 1; +} + } // box2d } // physics } // love diff --git a/src/modules/physics/box2d/Body.h b/src/modules/physics/box2d/Body.h index 30cd1229b..cd4faf11b 100644 --- a/src/modules/physics/box2d/Body.h +++ b/src/modules/physics/box2d/Body.h @@ -41,6 +41,16 @@ class World; class Shape; class Fixture; +/** + * This struct is stored in a void pointer in the Box2D Body class. For now, all + * we need is a Lua reference to arbitrary data, but we might need more later. + **/ +struct bodyudata +{ + // Reference to arbitrary data. + Reference *ref; +}; + /** * A Body is an entity which has position and orientation * in world space. A Body does have collision geometry @@ -388,6 +398,18 @@ public: **/ void destroy(); + /** + * This function stores an in-C reference to + * arbitrary Lua data in the Box2D Body object. + **/ + int setUserData(lua_State *L); + + /** + * Gets the data set with setData. If no + * data is set, nil is returned. + **/ + int getUserData(lua_State *L); + private: /** @@ -408,7 +430,10 @@ private: // This ensures that a World only can be destroyed // once all bodies have been destroyed too. World *world; -}; + + bodyudata *udata; + +}; // Body } // box2d } // physics diff --git a/src/modules/physics/box2d/Fixture.h b/src/modules/physics/box2d/Fixture.h index e7f18f942..5564406d4 100644 --- a/src/modules/physics/box2d/Fixture.h +++ b/src/modules/physics/box2d/Fixture.h @@ -123,9 +123,6 @@ public: /** * This function stores an in-C reference to * arbitrary Lua data in the Box2D Fixture object. - * - * The data set here will be passed to the collision - * handler when collisions occur. **/ int setUserData(lua_State *L); diff --git a/src/modules/physics/box2d/wrap_Body.cpp b/src/modules/physics/box2d/wrap_Body.cpp index 419d1fb29..61eb7529d 100644 --- a/src/modules/physics/box2d/wrap_Body.cpp +++ b/src/modules/physics/box2d/wrap_Body.cpp @@ -538,6 +538,20 @@ int w_Body_destroy(lua_State *L) return 0; } +int w_Body_setUserData(lua_State *L) +{ + Body *t = luax_checkbody(L, 1); + lua_remove(L, 1); + return t->setUserData(L); +} + +int w_Body_getUserData(lua_State *L) +{ + Body *t = luax_checkbody(L, 1); + lua_remove(L, 1); + return t->getUserData(L); +} + static const luaL_Reg functions[] = { { "getX", w_Body_getX }, @@ -592,6 +606,8 @@ static const luaL_Reg functions[] = { "isFixedRotation", w_Body_isFixedRotation }, { "getFixtureList", w_Body_getFixtureList }, { "destroy", w_Body_destroy }, + { "setUserData", w_Body_setUserData }, + { "getUserData", w_Body_getUserData }, { 0, 0 } }; diff --git a/src/modules/physics/box2d/wrap_Body.h b/src/modules/physics/box2d/wrap_Body.h index f06348809..2a41556f0 100644 --- a/src/modules/physics/box2d/wrap_Body.h +++ b/src/modules/physics/box2d/wrap_Body.h @@ -85,6 +85,8 @@ int w_Body_setFixedRotation(lua_State *L); int w_Body_isFixedRotation(lua_State *L); int w_Body_getFixtureList(lua_State *L); int w_Body_destroy(lua_State *L); +int w_Body_setUserData(lua_State *L); +int w_Body_getUserData(lua_State *L); extern "C" int luaopen_body(lua_State *L); } // box2d