]> git.lizzy.rs Git - dragonfireclient.git/blob - src/script/common/c_converter.cpp
Schematics: Refactor NodeResolver and add NodeResolveMethod
[dragonfireclient.git] / src / script / common / c_converter.cpp
1 /*
2 Minetest
3 Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU Lesser General Public License as published by
7 the Free Software Foundation; either version 2.1 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 GNU Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public License along
16 with this program; if not, write to the Free Software Foundation, Inc.,
17 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 */
19
20 extern "C" {
21 #include "lua.h"
22 #include "lauxlib.h"
23 }
24
25 #include "util/numeric.h"
26 #include "common/c_converter.h"
27 #include "constants.h"
28
29 void push_v3f(lua_State *L, v3f p)
30 {
31         lua_newtable(L);
32         lua_pushnumber(L, p.X);
33         lua_setfield(L, -2, "x");
34         lua_pushnumber(L, p.Y);
35         lua_setfield(L, -2, "y");
36         lua_pushnumber(L, p.Z);
37         lua_setfield(L, -2, "z");
38 }
39
40 void push_v2f(lua_State *L, v2f p)
41 {
42         lua_newtable(L);
43         lua_pushnumber(L, p.X);
44         lua_setfield(L, -2, "x");
45         lua_pushnumber(L, p.Y);
46         lua_setfield(L, -2, "y");
47 }
48
49 v2s16 read_v2s16(lua_State *L, int index)
50 {
51         v2s16 p;
52         luaL_checktype(L, index, LUA_TTABLE);
53         lua_getfield(L, index, "x");
54         p.X = lua_tonumber(L, -1);
55         lua_pop(L, 1);
56         lua_getfield(L, index, "y");
57         p.Y = lua_tonumber(L, -1);
58         lua_pop(L, 1);
59         return p;
60 }
61
62 v2s32 read_v2s32(lua_State *L, int index)
63 {
64         v2s32 p;
65         luaL_checktype(L, index, LUA_TTABLE);
66         lua_getfield(L, index, "x");
67         p.X = lua_tonumber(L, -1);
68         lua_pop(L, 1);
69         lua_getfield(L, index, "y");
70         p.Y = lua_tonumber(L, -1);
71         lua_pop(L, 1);
72         return p;
73 }
74
75 v2f read_v2f(lua_State *L, int index)
76 {
77         v2f p;
78         luaL_checktype(L, index, LUA_TTABLE);
79         lua_getfield(L, index, "x");
80         p.X = lua_tonumber(L, -1);
81         lua_pop(L, 1);
82         lua_getfield(L, index, "y");
83         p.Y = lua_tonumber(L, -1);
84         lua_pop(L, 1);
85         return p;
86 }
87
88 v3f read_v3f(lua_State *L, int index)
89 {
90         v3f pos;
91         luaL_checktype(L, index, LUA_TTABLE);
92         lua_getfield(L, index, "x");
93         pos.X = lua_tonumber(L, -1);
94         lua_pop(L, 1);
95         lua_getfield(L, index, "y");
96         pos.Y = lua_tonumber(L, -1);
97         lua_pop(L, 1);
98         lua_getfield(L, index, "z");
99         pos.Z = lua_tonumber(L, -1);
100         lua_pop(L, 1);
101         return pos;
102 }
103
104 v3f check_v3f(lua_State *L, int index)
105 {
106         v3f pos;
107         luaL_checktype(L, index, LUA_TTABLE);
108         lua_getfield(L, index, "x");
109         pos.X = luaL_checknumber(L, -1);
110         lua_pop(L, 1);
111         lua_getfield(L, index, "y");
112         pos.Y = luaL_checknumber(L, -1);
113         lua_pop(L, 1);
114         lua_getfield(L, index, "z");
115         pos.Z = luaL_checknumber(L, -1);
116         lua_pop(L, 1);
117         return pos;
118 }
119
120 void pushFloatPos(lua_State *L, v3f p)
121 {
122         p /= BS;
123         push_v3f(L, p);
124 }
125
126 v3f checkFloatPos(lua_State *L, int index)
127 {
128         return check_v3f(L, index) * BS;
129 }
130
131 void push_v3s16(lua_State *L, v3s16 p)
132 {
133         lua_newtable(L);
134         lua_pushnumber(L, p.X);
135         lua_setfield(L, -2, "x");
136         lua_pushnumber(L, p.Y);
137         lua_setfield(L, -2, "y");
138         lua_pushnumber(L, p.Z);
139         lua_setfield(L, -2, "z");
140 }
141
142 v3s16 read_v3s16(lua_State *L, int index)
143 {
144         // Correct rounding at <0
145         v3f pf = read_v3f(L, index);
146         return floatToInt(pf, 1.0);
147 }
148
149 v3s16 check_v3s16(lua_State *L, int index)
150 {
151         // Correct rounding at <0
152         v3f pf = check_v3f(L, index);
153         return floatToInt(pf, 1.0);
154 }
155
156 video::SColor readARGB8(lua_State *L, int index)
157 {
158         video::SColor color(0);
159         luaL_checktype(L, index, LUA_TTABLE);
160         lua_getfield(L, index, "a");
161         if(lua_isnumber(L, -1))
162                 color.setAlpha(lua_tonumber(L, -1));
163         lua_pop(L, 1);
164         lua_getfield(L, index, "r");
165         color.setRed(lua_tonumber(L, -1));
166         lua_pop(L, 1);
167         lua_getfield(L, index, "g");
168         color.setGreen(lua_tonumber(L, -1));
169         lua_pop(L, 1);
170         lua_getfield(L, index, "b");
171         color.setBlue(lua_tonumber(L, -1));
172         lua_pop(L, 1);
173         return color;
174 }
175
176 aabb3f read_aabb3f(lua_State *L, int index, f32 scale)
177 {
178         aabb3f box;
179         if(lua_istable(L, index)){
180                 lua_rawgeti(L, index, 1);
181                 box.MinEdge.X = lua_tonumber(L, -1) * scale;
182                 lua_pop(L, 1);
183                 lua_rawgeti(L, index, 2);
184                 box.MinEdge.Y = lua_tonumber(L, -1) * scale;
185                 lua_pop(L, 1);
186                 lua_rawgeti(L, index, 3);
187                 box.MinEdge.Z = lua_tonumber(L, -1) * scale;
188                 lua_pop(L, 1);
189                 lua_rawgeti(L, index, 4);
190                 box.MaxEdge.X = lua_tonumber(L, -1) * scale;
191                 lua_pop(L, 1);
192                 lua_rawgeti(L, index, 5);
193                 box.MaxEdge.Y = lua_tonumber(L, -1) * scale;
194                 lua_pop(L, 1);
195                 lua_rawgeti(L, index, 6);
196                 box.MaxEdge.Z = lua_tonumber(L, -1) * scale;
197                 lua_pop(L, 1);
198         }
199         return box;
200 }
201
202 std::vector<aabb3f> read_aabb3f_vector(lua_State *L, int index, f32 scale)
203 {
204         std::vector<aabb3f> boxes;
205         if(lua_istable(L, index)){
206                 int n = lua_objlen(L, index);
207                 // Check if it's a single box or a list of boxes
208                 bool possibly_single_box = (n == 6);
209                 for(int i = 1; i <= n && possibly_single_box; i++){
210                         lua_rawgeti(L, index, i);
211                         if(!lua_isnumber(L, -1))
212                                 possibly_single_box = false;
213                         lua_pop(L, 1);
214                 }
215                 if(possibly_single_box){
216                         // Read a single box
217                         boxes.push_back(read_aabb3f(L, index, scale));
218                 } else {
219                         // Read a list of boxes
220                         for(int i = 1; i <= n; i++){
221                                 lua_rawgeti(L, index, i);
222                                 boxes.push_back(read_aabb3f(L, -1, scale));
223                                 lua_pop(L, 1);
224                         }
225                 }
226         }
227         return boxes;
228 }
229
230 size_t read_stringlist(lua_State *L, int index, std::vector<std::string> *result)
231 {
232         if (index < 0)
233                 index = lua_gettop(L) + 1 + index;
234
235         size_t num_strings = 0;
236
237         if (lua_istable(L, index)) {
238                 lua_pushnil(L);
239                 while (lua_next(L, index)) {
240                         if (lua_isstring(L, -1)) {
241                                 result->push_back(lua_tostring(L, -1));
242                                 num_strings++;
243                         }
244                         lua_pop(L, 1);
245                 }
246         } else if (lua_isstring(L, index)) {
247                 result->push_back(lua_tostring(L, index));
248                 num_strings++;
249         }
250
251         return num_strings;
252 }
253
254 /*
255         Table field getters
256 */
257
258 bool getstringfield(lua_State *L, int table,
259                 const char *fieldname, std::string &result)
260 {
261         lua_getfield(L, table, fieldname);
262         bool got = false;
263         if(lua_isstring(L, -1)){
264                 size_t len = 0;
265                 const char *ptr = lua_tolstring(L, -1, &len);
266                 if (ptr) {
267                         result.assign(ptr, len);
268                         got = true;
269                 }
270         }
271         lua_pop(L, 1);
272         return got;
273 }
274
275 bool getintfield(lua_State *L, int table,
276                 const char *fieldname, int &result)
277 {
278         lua_getfield(L, table, fieldname);
279         bool got = false;
280         if(lua_isnumber(L, -1)){
281                 result = lua_tonumber(L, -1);
282                 got = true;
283         }
284         lua_pop(L, 1);
285         return got;
286 }
287
288 bool getfloatfield(lua_State *L, int table,
289                 const char *fieldname, float &result)
290 {
291         lua_getfield(L, table, fieldname);
292         bool got = false;
293         if(lua_isnumber(L, -1)){
294                 result = lua_tonumber(L, -1);
295                 got = true;
296         }
297         lua_pop(L, 1);
298         return got;
299 }
300
301 bool getboolfield(lua_State *L, int table,
302                 const char *fieldname, bool &result)
303 {
304         lua_getfield(L, table, fieldname);
305         bool got = false;
306         if(lua_isboolean(L, -1)){
307                 result = lua_toboolean(L, -1);
308                 got = true;
309         }
310         lua_pop(L, 1);
311         return got;
312 }
313
314 size_t getstringlistfield(lua_State *L, int table, const char *fieldname,
315                 std::vector<std::string> *result)
316 {
317         lua_getfield(L, table, fieldname);
318
319         size_t num_strings_read = read_stringlist(L, -1, result);
320
321         lua_pop(L, 1);
322         return num_strings_read;
323 }
324
325 std::string checkstringfield(lua_State *L, int table,
326                 const char *fieldname)
327 {
328         lua_getfield(L, table, fieldname);
329         std::string s = luaL_checkstring(L, -1);
330         lua_pop(L, 1);
331         return s;
332 }
333
334 std::string getstringfield_default(lua_State *L, int table,
335                 const char *fieldname, const std::string &default_)
336 {
337         std::string result = default_;
338         getstringfield(L, table, fieldname, result);
339         return result;
340 }
341
342 int getintfield_default(lua_State *L, int table,
343                 const char *fieldname, int default_)
344 {
345         int result = default_;
346         getintfield(L, table, fieldname, result);
347         return result;
348 }
349
350 float getfloatfield_default(lua_State *L, int table,
351                 const char *fieldname, float default_)
352 {
353         float result = default_;
354         getfloatfield(L, table, fieldname, result);
355         return result;
356 }
357
358 bool getboolfield_default(lua_State *L, int table,
359                 const char *fieldname, bool default_)
360 {
361         bool result = default_;
362         getboolfield(L, table, fieldname, result);
363         return result;
364 }
365
366 void setintfield(lua_State *L, int table,
367                 const char *fieldname, int value)
368 {
369         lua_pushinteger(L, value);
370         if(table < 0)
371                 table -= 1;
372         lua_setfield(L, table, fieldname);
373 }
374
375 void setfloatfield(lua_State *L, int table,
376                 const char *fieldname, float value)
377 {
378         lua_pushnumber(L, value);
379         if(table < 0)
380                 table -= 1;
381         lua_setfield(L, table, fieldname);
382 }
383
384 void setboolfield(lua_State *L, int table,
385                 const char *fieldname, bool value)
386 {
387         lua_pushboolean(L, value);
388         if(table < 0)
389                 table -= 1;
390         lua_setfield(L, table, fieldname);
391 }
392
393