Skip to content

Commit 89478da

Browse files
committed
Register FixedPoint for use in Lua.
Added unit tests.
1 parent 672cff5 commit 89478da

File tree

8 files changed

+1045
-374
lines changed

8 files changed

+1045
-374
lines changed

apps/freeablo/farender/renderer.cpp

Lines changed: 345 additions & 345 deletions
Large diffs are not rendered by default.

components/misc/fixedpoint.cpp

Lines changed: 366 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,379 @@
33
#include "int128.h"
44
#include "stringops.h"
55
#include <iomanip>
6+
#include <script/luascript.h>
67
#include <sstream>
78

89
#ifndef NDEBUG
910
#define _USE_MATH_DEFINES
1011
#include "math.h"
1112
#endif
1213

14+
namespace Script
15+
{
16+
template <> void LuaScript::registerGlobalType<FixedPoint>()
17+
{
18+
luaL_newmetatable(mState, "FixedPoint");
19+
auto constructor = [](lua_State* state) -> int {
20+
FixedPoint** self = static_cast<FixedPoint**>(lua_newuserdata(state, sizeof(FixedPoint)));
21+
if (lua_isstring(state, -2))
22+
{
23+
std::string str = lua_tostring(state, -2);
24+
*self = new FixedPoint(str);
25+
}
26+
27+
else if (lua_isinteger(state, -2))
28+
{
29+
int64_t integer = lua_tointeger(state, -2);
30+
*self = new FixedPoint(integer);
31+
}
32+
33+
luaL_setmetatable(state, "FixedPoint");
34+
35+
return 1;
36+
};
37+
38+
auto destructor = [](lua_State* state) -> int {
39+
delete *static_cast<FixedPoint**>(luaL_checkudata(state, 1, "FixedPoint"));
40+
return 0;
41+
};
42+
43+
auto fromRawValue = [](lua_State* state) -> int {
44+
FixedPoint** ret = static_cast<FixedPoint**>(lua_newuserdata(state, sizeof(FixedPoint)));
45+
int64_t val = luaL_checkinteger(state, 1);
46+
*ret = new FixedPoint();
47+
**ret = FixedPoint::fromRawValue(val);
48+
luaL_setmetatable(state, "FixedPoint");
49+
return 1;
50+
};
51+
52+
auto rawValue = [](lua_State* state) -> int {
53+
FixedPoint** self = static_cast<FixedPoint**>(luaL_checkudata(state, 1, "FixedPoint"));
54+
lua_pushinteger(state, (*self)->rawValue());
55+
return 1;
56+
};
57+
58+
auto intPart = [](lua_State* state) -> int {
59+
FixedPoint** self = static_cast<FixedPoint**>(luaL_checkudata(state, 1, "FixedPoint"));
60+
lua_pushinteger(state, (*self)->intPart());
61+
return 1;
62+
};
63+
64+
auto fractionPart = [](lua_State* state) -> int {
65+
FixedPoint** self = static_cast<FixedPoint**>(luaL_checkudata(state, 1, "FixedPoint"));
66+
FixedPoint** ret = static_cast<FixedPoint**>(lua_newuserdata(state, sizeof(FixedPoint)));
67+
*ret = new FixedPoint();
68+
**ret = (*self)->fractionPart();
69+
luaL_setmetatable(state, "FixedPoint");
70+
return 1;
71+
};
72+
73+
auto round = [](lua_State* state) -> int {
74+
FixedPoint** self = static_cast<FixedPoint**>(luaL_checkudata(state, 1, "FixedPoint"));
75+
lua_pushinteger(state, (*self)->round());
76+
return 1;
77+
};
78+
79+
auto floor = [](lua_State* state) -> int {
80+
FixedPoint** self = static_cast<FixedPoint**>(luaL_checkudata(state, 1, "FixedPoint"));
81+
lua_pushinteger(state, (*self)->floor());
82+
return 1;
83+
};
84+
85+
auto ceil = [](lua_State* state) -> int {
86+
FixedPoint** self = static_cast<FixedPoint**>(luaL_checkudata(state, 1, "FixedPoint"));
87+
lua_pushinteger(state, (*self)->ceil());
88+
return 1;
89+
};
90+
91+
auto str = [](lua_State* state) -> int {
92+
FixedPoint** self = static_cast<FixedPoint**>(luaL_checkudata(state, 1, "FixedPoint"));
93+
lua_pushstring(state, (*self)->str().c_str());
94+
return 1;
95+
};
96+
97+
auto toDouble = [](lua_State* state) -> int {
98+
FixedPoint** self = static_cast<FixedPoint**>(luaL_checkudata(state, 1, "FixedPoint"));
99+
lua_pushnumber(state, (*self)->toDouble());
100+
return 1;
101+
};
102+
103+
auto maxVal = [](lua_State* state) -> int {
104+
FixedPoint** ret = static_cast<FixedPoint**>(lua_newuserdata(state, sizeof(FixedPoint)));
105+
*ret = new FixedPoint();
106+
**ret = FixedPoint::maxVal();
107+
luaL_setmetatable(state, "FixedPoint");
108+
return 1;
109+
};
110+
111+
auto minVal = [](lua_State* state) -> int {
112+
FixedPoint** ret = static_cast<FixedPoint**>(lua_newuserdata(state, sizeof(FixedPoint)));
113+
*ret = new FixedPoint();
114+
**ret = FixedPoint::minVal();
115+
luaL_setmetatable(state, "FixedPoint");
116+
return 1;
117+
};
118+
119+
auto sqrt = [](lua_State* state) -> int {
120+
FixedPoint** self = static_cast<FixedPoint**>(luaL_checkudata(state, 1, "FixedPoint"));
121+
FixedPoint** ret = static_cast<FixedPoint**>(lua_newuserdata(state, sizeof(FixedPoint)));
122+
*ret = new FixedPoint();
123+
**ret = (*self)->sqrt();
124+
luaL_setmetatable(state, "FixedPoint");
125+
return 1;
126+
};
127+
128+
auto abs = [](lua_State* state) -> int {
129+
FixedPoint** self = static_cast<FixedPoint**>(luaL_checkudata(state, 1, "FixedPoint"));
130+
FixedPoint** ret = static_cast<FixedPoint**>(lua_newuserdata(state, sizeof(FixedPoint)));
131+
*ret = new FixedPoint();
132+
**ret = (*self)->abs();
133+
luaL_setmetatable(state, "FixedPoint");
134+
return 1;
135+
};
136+
137+
auto atan2 = [](lua_State* state) -> int {
138+
FixedPoint** y = static_cast<FixedPoint**>(luaL_checkudata(state, 1, "FixedPoint"));
139+
FixedPoint** x = static_cast<FixedPoint**>(luaL_checkudata(state, 2, "FixedPoint"));
140+
FixedPoint** ret = static_cast<FixedPoint**>(lua_newuserdata(state, sizeof(FixedPoint)));
141+
*ret = new FixedPoint();
142+
**ret = FixedPoint::atan2(**y, **x);
143+
luaL_setmetatable(state, "FixedPoint");
144+
return 1;
145+
};
146+
147+
auto sin = [](lua_State* state) -> int {
148+
FixedPoint** rad = static_cast<FixedPoint**>(luaL_checkudata(state, 1, "FixedPoint"));
149+
FixedPoint** ret = static_cast<FixedPoint**>(lua_newuserdata(state, sizeof(FixedPoint)));
150+
*ret = new FixedPoint();
151+
**ret = FixedPoint::sin(**rad);
152+
luaL_setmetatable(state, "FixedPoint");
153+
return 1;
154+
};
155+
156+
auto cos = [](lua_State* state) -> int {
157+
FixedPoint** rad = static_cast<FixedPoint**>(luaL_checkudata(state, 1, "FixedPoint"));
158+
FixedPoint** ret = static_cast<FixedPoint**>(lua_newuserdata(state, sizeof(FixedPoint)));
159+
*ret = new FixedPoint();
160+
**ret = FixedPoint::cos(**rad);
161+
luaL_setmetatable(state, "FixedPoint");
162+
return 1;
163+
};
164+
165+
auto atan2_degrees = [](lua_State* state) -> int {
166+
FixedPoint** y = static_cast<FixedPoint**>(luaL_checkudata(state, 1, "FixedPoint"));
167+
FixedPoint** x = static_cast<FixedPoint**>(luaL_checkudata(state, 2, "FixedPoint"));
168+
FixedPoint** ret = static_cast<FixedPoint**>(lua_newuserdata(state, sizeof(FixedPoint)));
169+
*ret = new FixedPoint();
170+
**ret = FixedPoint::atan2_degrees(**y, **x);
171+
luaL_setmetatable(state, "FixedPoint");
172+
return 1;
173+
};
174+
175+
auto sin_degrees = [](lua_State* state) -> int {
176+
FixedPoint** deg = static_cast<FixedPoint**>(luaL_checkudata(state, 1, "FixedPoint"));
177+
FixedPoint** ret = static_cast<FixedPoint**>(lua_newuserdata(state, sizeof(FixedPoint)));
178+
*ret = new FixedPoint();
179+
**ret = FixedPoint::sin_degrees(**deg);
180+
luaL_setmetatable(state, "FixedPoint");
181+
return 1;
182+
};
183+
184+
auto cos_degrees = [](lua_State* state) -> int {
185+
FixedPoint** deg = static_cast<FixedPoint**>(luaL_checkudata(state, 1, "FixedPoint"));
186+
FixedPoint** ret = static_cast<FixedPoint**>(lua_newuserdata(state, sizeof(FixedPoint)));
187+
*ret = new FixedPoint();
188+
**ret = FixedPoint::cos_degrees(**deg);
189+
luaL_setmetatable(state, "FixedPoint");
190+
return 1;
191+
};
192+
193+
auto add = [](lua_State* state) -> int {
194+
int64_t intOp = 0;
195+
FixedPoint** self = static_cast<FixedPoint**>(luaL_checkudata(state, 1, "FixedPoint"));
196+
FixedPoint** ret = static_cast<FixedPoint**>(lua_newuserdata(state, sizeof(FixedPoint)));
197+
*ret = new FixedPoint();
198+
if (lua_isinteger(state, -2))
199+
{
200+
intOp = lua_tointeger(state, -2);
201+
**ret = (*self)->operator+(intOp);
202+
}
203+
204+
else
205+
{
206+
FixedPoint** other = static_cast<FixedPoint**>(luaL_checkudata(state, 2, "FixedPoint"));
207+
**ret = (*self)->operator+(**other);
208+
}
209+
210+
luaL_setmetatable(state, "FixedPoint");
211+
return 1;
212+
};
213+
214+
auto sub = [](lua_State* state) -> int {
215+
int64_t intOp = 0;
216+
FixedPoint** self = static_cast<FixedPoint**>(luaL_checkudata(state, 1, "FixedPoint"));
217+
FixedPoint** ret = static_cast<FixedPoint**>(lua_newuserdata(state, sizeof(FixedPoint)));
218+
*ret = new FixedPoint();
219+
if (lua_isinteger(state, -2))
220+
{
221+
intOp = lua_tointeger(state, -2);
222+
**ret = (*self)->operator-(intOp);
223+
}
224+
225+
else
226+
{
227+
FixedPoint** other = static_cast<FixedPoint**>(luaL_checkudata(state, 2, "FixedPoint"));
228+
**ret = (*self)->operator-(**other);
229+
}
230+
231+
luaL_setmetatable(state, "FixedPoint");
232+
return 1;
233+
};
234+
235+
auto mul = [](lua_State* state) -> int {
236+
int64_t intOp = 0;
237+
FixedPoint** self = static_cast<FixedPoint**>(luaL_checkudata(state, 1, "FixedPoint"));
238+
FixedPoint** ret = static_cast<FixedPoint**>(lua_newuserdata(state, sizeof(FixedPoint)));
239+
*ret = new FixedPoint();
240+
if (lua_isinteger(state, -2))
241+
{
242+
intOp = lua_tointeger(state, -2);
243+
**ret = (*self)->operator*(intOp);
244+
}
245+
246+
else
247+
{
248+
FixedPoint** other = static_cast<FixedPoint**>(luaL_checkudata(state, 2, "FixedPoint"));
249+
**ret = (*self)->operator*(**other);
250+
}
251+
252+
luaL_setmetatable(state, "FixedPoint");
253+
return 1;
254+
};
255+
256+
auto div = [](lua_State* state) -> int {
257+
int64_t intOp = 0;
258+
FixedPoint** self = static_cast<FixedPoint**>(luaL_checkudata(state, 1, "FixedPoint"));
259+
FixedPoint** ret = static_cast<FixedPoint**>(lua_newuserdata(state, sizeof(FixedPoint)));
260+
*ret = new FixedPoint();
261+
if (lua_isinteger(state, -2))
262+
{
263+
intOp = lua_tointeger(state, -2);
264+
**ret = (*self)->operator/(intOp);
265+
}
266+
267+
else
268+
{
269+
FixedPoint** other = static_cast<FixedPoint**>(luaL_checkudata(state, 2, "FixedPoint"));
270+
**ret = (*self)->operator/(**other);
271+
}
272+
273+
luaL_setmetatable(state, "FixedPoint");
274+
return 1;
275+
};
276+
277+
auto unm = [](lua_State* state) -> int {
278+
FixedPoint** self = static_cast<FixedPoint**>(luaL_checkudata(state, 1, "FixedPoint"));
279+
FixedPoint** ret = static_cast<FixedPoint**>(lua_newuserdata(state, sizeof(FixedPoint)));
280+
*ret = new FixedPoint();
281+
**ret = (*self)->operator-();
282+
luaL_setmetatable(state, "FixedPoint");
283+
return 1;
284+
};
285+
286+
auto eq = [](lua_State* state) -> int {
287+
FixedPoint** self = static_cast<FixedPoint**>(luaL_checkudata(state, 1, "FixedPoint"));
288+
FixedPoint** other = static_cast<FixedPoint**>(luaL_checkudata(state, 2, "FixedPoint"));
289+
lua_pushboolean(state, **self == **other);
290+
return 1;
291+
};
292+
293+
auto lt = [](lua_State* state) -> int {
294+
FixedPoint** self = static_cast<FixedPoint**>(luaL_checkudata(state, 1, "FixedPoint"));
295+
FixedPoint** other = static_cast<FixedPoint**>(luaL_checkudata(state, 2, "FixedPoint"));
296+
lua_pushboolean(state, (*self)->operator<(**other));
297+
return 1;
298+
};
299+
300+
auto le = [](lua_State* state) -> int {
301+
FixedPoint** self = static_cast<FixedPoint**>(luaL_checkudata(state, 1, "FixedPoint"));
302+
FixedPoint** other = static_cast<FixedPoint**>(luaL_checkudata(state, 2, "FixedPoint"));
303+
lua_pushboolean(state, (*self)->operator<=(**other));
304+
return 1;
305+
};
306+
307+
lua_newtable(mState);
308+
309+
// constructor and static functions
310+
lua_pushcfunction(mState, constructor);
311+
lua_setfield(mState, -2, "new");
312+
lua_pushcfunction(mState, fromRawValue);
313+
lua_setfield(mState, -2, "fromRawValue");
314+
lua_pushcfunction(mState, maxVal);
315+
lua_setfield(mState, -2, "maxVal");
316+
lua_pushcfunction(mState, minVal);
317+
lua_setfield(mState, -2, "minVal");
318+
lua_pushcfunction(mState, atan2);
319+
lua_setfield(mState, -2, "atan2");
320+
lua_pushcfunction(mState, sin);
321+
lua_setfield(mState, -2, "sin");
322+
lua_pushcfunction(mState, cos);
323+
lua_setfield(mState, -2, "cos");
324+
lua_pushcfunction(mState, atan2_degrees);
325+
lua_setfield(mState, -2, "atan2_degrees");
326+
lua_pushcfunction(mState, sin_degrees);
327+
lua_setfield(mState, -2, "sin_degrees");
328+
lua_pushcfunction(mState, cos_degrees);
329+
lua_setfield(mState, -2, "cos_degrees");
330+
lua_setglobal(mState, "FixedPoint");
331+
332+
// member functions
333+
lua_pushvalue(mState, -1);
334+
lua_setfield(mState, -2, "__index");
335+
lua_pushcfunction(mState, rawValue);
336+
lua_setfield(mState, -2, "rawValue");
337+
lua_pushcfunction(mState, intPart);
338+
lua_setfield(mState, -2, "intPart");
339+
lua_pushcfunction(mState, fractionPart);
340+
lua_setfield(mState, -2, "fractionPart");
341+
lua_pushcfunction(mState, str);
342+
lua_setfield(mState, -2, "str");
343+
lua_pushcfunction(mState, toDouble);
344+
lua_setfield(mState, -2, "toDouble");
345+
lua_pushcfunction(mState, round);
346+
lua_setfield(mState, -2, "round");
347+
lua_pushcfunction(mState, floor);
348+
lua_setfield(mState, -2, "floor");
349+
lua_pushcfunction(mState, ceil);
350+
lua_setfield(mState, -2, "ceil");
351+
lua_pushcfunction(mState, sqrt);
352+
lua_setfield(mState, -2, "sqrt");
353+
lua_pushcfunction(mState, abs);
354+
lua_setfield(mState, -2, "abs");
355+
356+
// operators
357+
lua_pushcfunction(mState, add);
358+
lua_setfield(mState, -2, "__add");
359+
lua_pushcfunction(mState, sub);
360+
lua_setfield(mState, -2, "__sub");
361+
lua_pushcfunction(mState, mul);
362+
lua_setfield(mState, -2, "__mul");
363+
lua_pushcfunction(mState, div);
364+
lua_setfield(mState, -2, "__div");
365+
lua_pushcfunction(mState, unm); // unary - (negation)
366+
lua_setfield(mState, -2, "__unm");
367+
lua_pushcfunction(mState, eq);
368+
lua_setfield(mState, -2, "__eq");
369+
lua_pushcfunction(mState, lt);
370+
lua_setfield(mState, -2, "__lt");
371+
lua_pushcfunction(mState, le);
372+
lua_setfield(mState, -2, "__le");
373+
374+
lua_pushcfunction(mState, destructor);
375+
lua_setfield(mState, -2, "__gc");
376+
}
377+
}
378+
13379
constexpr int64_t FixedPoint::scalingFactorPowerOf10;
14380
constexpr int64_t FixedPoint::scalingFactor;
15381

0 commit comments

Comments
 (0)