Browse Source

Added Joint:setUserData and Joint:getUserData (resolves issue #894.)

Alex Szpakowski 11 years ago
parent
commit
5dd23dffd1

+ 39 - 1
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

+ 23 - 0
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,

+ 2 - 0
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 }
 };

+ 2 - 0
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 }
 };

+ 2 - 0
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 }
 };

+ 16 - 0
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 }
 };

+ 2 - 0
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);
 

+ 2 - 0
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 }
 };

+ 2 - 0
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 }
 };

+ 2 - 0
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 }
 };

+ 2 - 0
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 }
 };

+ 2 - 0
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 }
 };

+ 2 - 0
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 }
 };

+ 2 - 0
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 }
 };

+ 2 - 0
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 }
 };