diff --git a/src/modules/physics/box2d/Joint.cpp b/src/modules/physics/box2d/Joint.cpp index 5e3ec277f..8ca574530 100644 --- a/src/modules/physics/box2d/Joint.cpp +++ b/src/modules/physics/box2d/Joint.cpp @@ -41,20 +41,29 @@ namespace box2d Joint::Joint(Body *body1) : world(body1->world) + , udata(nullptr) , body1(body1) - , body2(0) + , body2(nullptr) { + udata = new jointudata(); + udata->ref = nullptr; } Joint::Joint(Body *body1, Body *body2) : world(body1->world) + , udata(nullptr) , body1(body1) , body2(body2) { + udata = new jointudata(); + udata->ref = nullptr; } Joint::~Joint() { + if (udata != nullptr) + delete udata->ref; + delete udata; } Joint::Type Joint::getType() const @@ -116,6 +125,7 @@ float Joint::getReactionTorque(float dt) b2Joint *Joint::createJoint(b2JointDef *def) { + def->userData = udata; joint = world->world->CreateJoint(def); Memoizer::add(joint, this); // Box2D joint has a reference to this love Joint. @@ -151,6 +161,34 @@ bool Joint::getCollideConnected() const return joint->GetCollideConnected(); } +int Joint::setUserData(lua_State *L) +{ + love::luax_assert_argc(L, 1, 1); + + 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 Joint::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/Joint.h b/src/modules/physics/box2d/Joint.h index 22622df1d..ba266808b 100644 --- a/src/modules/physics/box2d/Joint.h +++ b/src/modules/physics/box2d/Joint.h @@ -39,6 +39,16 @@ namespace box2d class Body; class World; +/** + * This struct is stored in a void pointer in the Box2D Joint class. For now, all + * we need is a Lua reference to arbitrary data, but we might need more later. + **/ +struct jointudata +{ + // Reference to arbitrary data. + Reference *ref; +}; + /** * A Joint acts as positioning constraints on Bodies. * A Joint can be used to prevent Bodies from going to @@ -95,6 +105,17 @@ public: bool getCollideConnected() const; + /** + * This function stores an in-C reference to arbitrary Lua data in the Box2D + * Joint object. + **/ + int setUserData(lua_State *L); + + /** + * Gets the data set with setUserData. If no data is set, nil is returned. + **/ + int getUserData(lua_State *L); + /** * Joints require pointers to a Box2D joint objects at * different polymorphic levels, which is why these function @@ -117,6 +138,8 @@ protected: World *world; + jointudata *udata; + private: // A Joint must be destroyed *before* the bodies it acts upon, diff --git a/src/modules/physics/box2d/wrap_DistanceJoint.cpp b/src/modules/physics/box2d/wrap_DistanceJoint.cpp index 0824e3566..219196b03 100644 --- a/src/modules/physics/box2d/wrap_DistanceJoint.cpp +++ b/src/modules/physics/box2d/wrap_DistanceJoint.cpp @@ -94,6 +94,8 @@ static const luaL_Reg functions[] = { "getReactionForce", w_Joint_getReactionForce }, { "getReactionTorque", w_Joint_getReactionTorque }, { "getCollideConnected", w_Joint_getCollideConnected }, + { "setUserData", w_Joint_setUserData }, + { "getUserData", w_Joint_getUserData }, { "destroy", w_Joint_destroy }, { 0, 0 } }; diff --git a/src/modules/physics/box2d/wrap_FrictionJoint.cpp b/src/modules/physics/box2d/wrap_FrictionJoint.cpp index 7124a8530..cc202e3b8 100644 --- a/src/modules/physics/box2d/wrap_FrictionJoint.cpp +++ b/src/modules/physics/box2d/wrap_FrictionJoint.cpp @@ -78,6 +78,8 @@ static const luaL_Reg functions[] = { "getReactionForce", w_Joint_getReactionForce }, { "getReactionTorque", w_Joint_getReactionTorque }, { "getCollideConnected", w_Joint_getCollideConnected }, + { "setUserData", w_Joint_setUserData }, + { "getUserData", w_Joint_getUserData }, { "destroy", w_Joint_destroy }, { 0, 0 } }; diff --git a/src/modules/physics/box2d/wrap_GearJoint.cpp b/src/modules/physics/box2d/wrap_GearJoint.cpp index c6f84114f..114045e13 100644 --- a/src/modules/physics/box2d/wrap_GearJoint.cpp +++ b/src/modules/physics/box2d/wrap_GearJoint.cpp @@ -61,6 +61,8 @@ static const luaL_Reg functions[] = { "getReactionForce", w_Joint_getReactionForce }, { "getReactionTorque", w_Joint_getReactionTorque }, { "getCollideConnected", w_Joint_getCollideConnected }, + { "setUserData", w_Joint_setUserData }, + { "getUserData", w_Joint_getUserData }, { "destroy", w_Joint_destroy }, { 0, 0 } }; diff --git a/src/modules/physics/box2d/wrap_Joint.cpp b/src/modules/physics/box2d/wrap_Joint.cpp index 053f8b45d..4e2727e7c 100644 --- a/src/modules/physics/box2d/wrap_Joint.cpp +++ b/src/modules/physics/box2d/wrap_Joint.cpp @@ -75,6 +75,20 @@ int w_Joint_getCollideConnected(lua_State *L) return 1; } +int w_Joint_setUserData(lua_State *L) +{ + Joint *t = luax_checkjoint(L, 1); + lua_remove(L, 1); + return t->setUserData(L); +} + +int w_Joint_getUserData(lua_State *L) +{ + Joint *t = luax_checkjoint(L, 1); + lua_remove(L, 1); + return t->getUserData(L); +} + int w_Joint_destroy(lua_State *L) { Joint *t = luax_checkjoint(L, 1); @@ -89,6 +103,8 @@ static const luaL_Reg functions[] = { "getReactionForce", w_Joint_getReactionForce }, { "getReactionTorque", w_Joint_getReactionTorque }, { "getCollideConnected", w_Joint_getCollideConnected }, + { "setUserData", w_Joint_setUserData }, + { "getUserData", w_Joint_getUserData }, { "destroy", w_Joint_destroy }, { 0, 0 } }; diff --git a/src/modules/physics/box2d/wrap_Joint.h b/src/modules/physics/box2d/wrap_Joint.h index 3a2495d83..63d4537ec 100644 --- a/src/modules/physics/box2d/wrap_Joint.h +++ b/src/modules/physics/box2d/wrap_Joint.h @@ -38,6 +38,8 @@ int w_Joint_getAnchors(lua_State *L); int w_Joint_getReactionForce(lua_State *L); int w_Joint_getReactionTorque(lua_State *L); int w_Joint_getCollideConnected(lua_State *L); +int w_Joint_setUserData(lua_State *L); +int w_Joint_getUserData(lua_State *L); int w_Joint_destroy(lua_State *L); extern "C" int luaopen_joint(lua_State *L); diff --git a/src/modules/physics/box2d/wrap_MotorJoint.cpp b/src/modules/physics/box2d/wrap_MotorJoint.cpp index 4403ddc88..17d1501a0 100644 --- a/src/modules/physics/box2d/wrap_MotorJoint.cpp +++ b/src/modules/physics/box2d/wrap_MotorJoint.cpp @@ -128,6 +128,8 @@ static const luaL_Reg functions[] = { "getReactionForce", w_Joint_getReactionForce }, { "getReactionTorque", w_Joint_getReactionTorque }, { "getCollideConnected", w_Joint_getCollideConnected }, + { "setUserData", w_Joint_setUserData }, + { "getUserData", w_Joint_getUserData }, { "destroy", w_Joint_destroy }, { 0, 0 } }; diff --git a/src/modules/physics/box2d/wrap_MouseJoint.cpp b/src/modules/physics/box2d/wrap_MouseJoint.cpp index 8e02addf7..38cf46b26 100644 --- a/src/modules/physics/box2d/wrap_MouseJoint.cpp +++ b/src/modules/physics/box2d/wrap_MouseJoint.cpp @@ -112,6 +112,8 @@ static const luaL_Reg functions[] = { "getReactionForce", w_Joint_getReactionForce }, { "getReactionTorque", w_Joint_getReactionTorque }, { "getCollideConnected", w_Joint_getCollideConnected }, + { "setUserData", w_Joint_setUserData }, + { "getUserData", w_Joint_getUserData }, { "destroy", w_Joint_destroy }, { 0, 0 } }; diff --git a/src/modules/physics/box2d/wrap_PrismaticJoint.cpp b/src/modules/physics/box2d/wrap_PrismaticJoint.cpp index ed3b6838f..e820d38d8 100644 --- a/src/modules/physics/box2d/wrap_PrismaticJoint.cpp +++ b/src/modules/physics/box2d/wrap_PrismaticJoint.cpp @@ -189,6 +189,8 @@ static const luaL_Reg functions[] = { "getReactionForce", w_Joint_getReactionForce }, { "getReactionTorque", w_Joint_getReactionTorque }, { "getCollideConnected", w_Joint_getCollideConnected }, + { "setUserData", w_Joint_setUserData }, + { "getUserData", w_Joint_getUserData }, { "destroy", w_Joint_destroy }, { 0, 0 } }; diff --git a/src/modules/physics/box2d/wrap_PulleyJoint.cpp b/src/modules/physics/box2d/wrap_PulleyJoint.cpp index 1e9e01aa2..25c41758c 100644 --- a/src/modules/physics/box2d/wrap_PulleyJoint.cpp +++ b/src/modules/physics/box2d/wrap_PulleyJoint.cpp @@ -75,6 +75,8 @@ static const luaL_Reg functions[] = { "getReactionForce", w_Joint_getReactionForce }, { "getReactionTorque", w_Joint_getReactionTorque }, { "getCollideConnected", w_Joint_getCollideConnected }, + { "setUserData", w_Joint_setUserData }, + { "getUserData", w_Joint_getUserData }, { "destroy", w_Joint_destroy }, { 0, 0 } }; diff --git a/src/modules/physics/box2d/wrap_RevoluteJoint.cpp b/src/modules/physics/box2d/wrap_RevoluteJoint.cpp index 82203f0ad..13d3468f9 100644 --- a/src/modules/physics/box2d/wrap_RevoluteJoint.cpp +++ b/src/modules/physics/box2d/wrap_RevoluteJoint.cpp @@ -189,6 +189,8 @@ static const luaL_Reg functions[] = { "getReactionForce", w_Joint_getReactionForce }, { "getReactionTorque", w_Joint_getReactionTorque }, { "getCollideConnected", w_Joint_getCollideConnected }, + { "setUserData", w_Joint_setUserData }, + { "getUserData", w_Joint_getUserData }, { "destroy", w_Joint_destroy }, { 0, 0 } }; diff --git a/src/modules/physics/box2d/wrap_RopeJoint.cpp b/src/modules/physics/box2d/wrap_RopeJoint.cpp index 907b519c5..45fecce2b 100644 --- a/src/modules/physics/box2d/wrap_RopeJoint.cpp +++ b/src/modules/physics/box2d/wrap_RopeJoint.cpp @@ -51,6 +51,8 @@ static const luaL_Reg functions[] = { "getReactionForce", w_Joint_getReactionForce }, { "getReactionTorque", w_Joint_getReactionTorque }, { "getCollideConnected", w_Joint_getCollideConnected }, + { "setUserData", w_Joint_setUserData }, + { "getUserData", w_Joint_getUserData }, { "destroy", w_Joint_destroy }, { 0, 0 } }; diff --git a/src/modules/physics/box2d/wrap_WeldJoint.cpp b/src/modules/physics/box2d/wrap_WeldJoint.cpp index 84476ee05..0937c044b 100644 --- a/src/modules/physics/box2d/wrap_WeldJoint.cpp +++ b/src/modules/physics/box2d/wrap_WeldJoint.cpp @@ -77,6 +77,8 @@ static const luaL_Reg functions[] = { "getReactionForce", w_Joint_getReactionForce }, { "getReactionTorque", w_Joint_getReactionTorque }, { "getCollideConnected", w_Joint_getCollideConnected }, + { "setUserData", w_Joint_setUserData }, + { "getUserData", w_Joint_getUserData }, { "destroy", w_Joint_destroy }, { 0, 0 } }; diff --git a/src/modules/physics/box2d/wrap_WheelJoint.cpp b/src/modules/physics/box2d/wrap_WheelJoint.cpp index 861b61904..31b1c5b84 100644 --- a/src/modules/physics/box2d/wrap_WheelJoint.cpp +++ b/src/modules/physics/box2d/wrap_WheelJoint.cpp @@ -153,6 +153,8 @@ static const luaL_Reg functions[] = { "getReactionForce", w_Joint_getReactionForce }, { "getReactionTorque", w_Joint_getReactionTorque }, { "getCollideConnected", w_Joint_getCollideConnected }, + { "setUserData", w_Joint_setUserData }, + { "getUserData", w_Joint_getUserData }, { "destroy", w_Joint_destroy }, { 0, 0 } };