1/**
2 * Copyright (c) 2006-2023 LOVE Development Team
3 *
4 * This software is provided 'as-is', without any express or implied
5 * warranty. In no event will the authors be held liable for any damages
6 * arising from the use of this software.
7 *
8 * Permission is granted to anyone to use this software for any purpose,
9 * including commercial applications, and to alter it and redistribute it
10 * freely, subject to the following restrictions:
11 *
12 * 1. The origin of this software must not be misrepresented; you must not
13 * claim that you wrote the original software. If you use this software
14 * in a product, an acknowledgment in the product documentation would be
15 * appreciated but is not required.
16 * 2. Altered source versions must be plainly marked as such, and must not be
17 * misrepresented as being the original software.
18 * 3. This notice may not be removed or altered from any source distribution.
19 **/
20
21// LOVE
22#include "wrap_Joint.h"
23#include "common/StringMap.h"
24#include "Body.h"
25#include "DistanceJoint.h"
26#include "RevoluteJoint.h"
27#include "PrismaticJoint.h"
28#include "MouseJoint.h"
29#include "PulleyJoint.h"
30#include "GearJoint.h"
31#include "FrictionJoint.h"
32#include "WeldJoint.h"
33#include "WheelJoint.h"
34#include "RopeJoint.h"
35#include "MotorJoint.h"
36
37namespace love
38{
39namespace physics
40{
41namespace box2d
42{
43
44void luax_pushjoint(lua_State *L, Joint *j)
45{
46 if (j == nullptr)
47 return lua_pushnil(L);
48
49 switch (j->getType())
50 {
51 case Joint::JOINT_DISTANCE:
52 return luax_pushtype(L, DistanceJoint::type, j);
53 case Joint::JOINT_REVOLUTE:
54 return luax_pushtype(L, RevoluteJoint::type, j);
55 case Joint::JOINT_PRISMATIC:
56 return luax_pushtype(L, PrismaticJoint::type, j);
57 case Joint::JOINT_MOUSE:
58 return luax_pushtype(L, MouseJoint::type, j);
59 case Joint::JOINT_PULLEY:
60 return luax_pushtype(L, PulleyJoint::type, j);
61 case Joint::JOINT_GEAR:
62 return luax_pushtype(L, GearJoint::type, j);
63 case Joint::JOINT_FRICTION:
64 return luax_pushtype(L, FrictionJoint::type, j);
65 case Joint::JOINT_WELD:
66 return luax_pushtype(L, WeldJoint::type, j);
67 case Joint::JOINT_WHEEL:
68 return luax_pushtype(L, WheelJoint::type, j);
69 case Joint::JOINT_ROPE:
70 return luax_pushtype(L, RopeJoint::type, j);
71 case Joint::JOINT_MOTOR:
72 return luax_pushtype(L, MotorJoint::type, j);
73 default:
74 return lua_pushnil(L);
75 }
76}
77
78Joint *luax_checkjoint(lua_State *L, int idx)
79{
80 Joint *t = luax_checktype<Joint>(L, idx);
81 if (!t->isValid())
82 luaL_error(L, "Attempt to use destroyed joint.");
83 return t;
84}
85
86int w_Joint_getType(lua_State *L)
87{
88 Joint *t = luax_checkjoint(L, 1);
89 const char *type = "";
90 Joint::getConstant(t->getType(), type);
91 lua_pushstring(L, type);
92 return 1;
93}
94
95int w_Joint_getBodies(lua_State *L)
96{
97 Joint *t = luax_checkjoint(L, 1);
98 Body *b1 = nullptr;
99 Body *b2 = nullptr;
100
101 luax_catchexcept(L, [&]() {
102 b1 = t->getBodyA();
103 b2 = t->getBodyB();
104 });
105
106 luax_pushtype(L, b1);
107 luax_pushtype(L, b2);
108 return 2;
109}
110
111int w_Joint_getAnchors(lua_State *L)
112{
113 Joint *t = luax_checkjoint(L, 1);
114 lua_remove(L, 1);
115 return t->getAnchors(L);
116}
117
118int w_Joint_getReactionForce(lua_State *L)
119{
120 Joint *t = luax_checkjoint(L, 1);
121 lua_remove(L, 1);
122 return t->getReactionForce(L);
123}
124
125int w_Joint_getReactionTorque(lua_State *L)
126{
127 Joint *t = luax_checkjoint(L, 1);
128 float inv_dt = (float)luaL_checknumber(L, 2);
129 lua_pushnumber(L, t->getReactionTorque(inv_dt));
130 return 1;
131}
132
133int w_Joint_getCollideConnected(lua_State *L)
134{
135 Joint *t = luax_checkjoint(L, 1);
136 luax_pushboolean(L, t->getCollideConnected());
137 return 1;
138}
139
140int w_Joint_setUserData(lua_State *L)
141{
142 Joint *t = luax_checkjoint(L, 1);
143 lua_remove(L, 1);
144 return t->setUserData(L);
145}
146
147int w_Joint_getUserData(lua_State *L)
148{
149 Joint *t = luax_checkjoint(L, 1);
150 lua_remove(L, 1);
151 return t->getUserData(L);
152}
153
154int w_Joint_destroy(lua_State *L)
155{
156 Joint *t = luax_checkjoint(L, 1);
157 luax_catchexcept(L, [&](){ t->destroyJoint(); });
158 return 0;
159}
160
161int w_Joint_isDestroyed(lua_State *L)
162{
163 Joint *t = luax_checktype<Joint>(L, 1);
164 luax_pushboolean(L, !t->isValid());
165 return 1;
166}
167
168const luaL_Reg w_Joint_functions[] =
169{
170 { "getType", w_Joint_getType },
171 { "getBodies", w_Joint_getBodies },
172 { "getAnchors", w_Joint_getAnchors },
173 { "getReactionForce", w_Joint_getReactionForce },
174 { "getReactionTorque", w_Joint_getReactionTorque },
175 { "getCollideConnected", w_Joint_getCollideConnected },
176 { "setUserData", w_Joint_setUserData },
177 { "getUserData", w_Joint_getUserData },
178 { "destroy", w_Joint_destroy },
179 { "isDestroyed", w_Joint_isDestroyed },
180 { 0, 0 }
181};
182
183extern "C" int luaopen_joint(lua_State *L)
184{
185 return luax_register_type(L, &Joint::type, w_Joint_functions, nullptr);
186}
187
188} // box2d
189} // physics
190} // love
191