]> git.lizzy.rs Git - dragonfireclient.git/blob - src/script/common/c_converter.cpp
Remove duplicate lua_getfield() in c_converter.cpp
[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
30 #define CHECK_TYPE(index, name, type) do { \
31         int t = lua_type(L, (index)); \
32         if (t != (type)) { \
33                 throw LuaError(std::string("Invalid ") + (name) + \
34                         " (expected " + lua_typename(L, (type)) + \
35                         " got " + lua_typename(L, t) + ")."); \
36         } \
37 } while(0)
38 #define CHECK_POS_COORD(name) CHECK_TYPE(-1, "position coordinate '" name "'", LUA_TNUMBER)
39 #define CHECK_POS_TAB(index) CHECK_TYPE(index, "position", LUA_TTABLE)
40
41
42 void push_v3f(lua_State *L, v3f p)
43 {
44         lua_newtable(L);
45         lua_pushnumber(L, p.X);
46         lua_setfield(L, -2, "x");
47         lua_pushnumber(L, p.Y);
48         lua_setfield(L, -2, "y");
49         lua_pushnumber(L, p.Z);
50         lua_setfield(L, -2, "z");
51 }
52
53 void push_v2f(lua_State *L, v2f p)
54 {
55         lua_newtable(L);
56         lua_pushnumber(L, p.X);
57         lua_setfield(L, -2, "x");
58         lua_pushnumber(L, p.Y);
59         lua_setfield(L, -2, "y");
60 }
61
62 v2s16 read_v2s16(lua_State *L, int index)
63 {
64         v2s16 p;
65         CHECK_POS_TAB(index);
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 v2s16 check_v2s16(lua_State *L, int index)
76 {
77         v2s16 p;
78         CHECK_POS_TAB(index);
79         lua_getfield(L, index, "x");
80         CHECK_POS_COORD("x");
81         p.X = lua_tonumber(L, -1);
82         lua_pop(L, 1);
83         lua_getfield(L, index, "y");
84         CHECK_POS_COORD("y");
85         p.Y = lua_tonumber(L, -1);
86         lua_pop(L, 1);
87         return p;
88 }
89
90 v2s32 read_v2s32(lua_State *L, int index)
91 {
92         v2s32 p;
93         CHECK_POS_TAB(index);
94         lua_getfield(L, index, "x");
95         p.X = lua_tonumber(L, -1);
96         lua_pop(L, 1);
97         lua_getfield(L, index, "y");
98         p.Y = lua_tonumber(L, -1);
99         lua_pop(L, 1);
100         return p;
101 }
102
103 v2f read_v2f(lua_State *L, int index)
104 {
105         v2f p;
106         CHECK_POS_TAB(index);
107         lua_getfield(L, index, "x");
108         p.X = lua_tonumber(L, -1);
109         lua_pop(L, 1);
110         lua_getfield(L, index, "y");
111         p.Y = lua_tonumber(L, -1);
112         lua_pop(L, 1);
113         return p;
114 }
115
116 v2f check_v2f(lua_State *L, int index)
117 {
118         v2f p;
119         CHECK_POS_TAB(index);
120         lua_getfield(L, index, "x");
121         CHECK_POS_COORD("x");
122         p.X = lua_tonumber(L, -1);
123         lua_pop(L, 1);
124         lua_getfield(L, index, "y");
125         CHECK_POS_COORD("y");
126         p.Y = lua_tonumber(L, -1);
127         lua_pop(L, 1);
128         return p;
129 }
130
131 v3f read_v3f(lua_State *L, int index)
132 {
133         v3f pos;
134         CHECK_POS_TAB(index);
135         lua_getfield(L, index, "x");
136         pos.X = lua_tonumber(L, -1);
137         lua_pop(L, 1);
138         lua_getfield(L, index, "y");
139         pos.Y = lua_tonumber(L, -1);
140         lua_pop(L, 1);
141         lua_getfield(L, index, "z");
142         pos.Z = lua_tonumber(L, -1);
143         lua_pop(L, 1);
144         return pos;
145 }
146
147 v3f check_v3f(lua_State *L, int index)
148 {
149         v3f pos;
150         CHECK_POS_TAB(index);
151         lua_getfield(L, index, "x");
152         CHECK_POS_COORD("x");
153         pos.X = lua_tonumber(L, -1);
154         lua_pop(L, 1);
155         lua_getfield(L, index, "y");
156         CHECK_POS_COORD("y");
157         pos.Z = lua_tonumber(L, -1);
158         lua_pop(L, 1);
159         lua_getfield(L, index, "z");
160         CHECK_POS_COORD("z");
161         pos.Z = lua_tonumber(L, -1);
162         lua_pop(L, 1);
163         return pos;
164 }
165
166 void pushFloatPos(lua_State *L, v3f p)
167 {
168         p /= BS;
169         push_v3f(L, p);
170 }
171
172 v3f checkFloatPos(lua_State *L, int index)
173 {
174         return check_v3f(L, index) * BS;
175 }
176
177 void push_v3s16(lua_State *L, v3s16 p)
178 {
179         lua_newtable(L);
180         lua_pushnumber(L, p.X);
181         lua_setfield(L, -2, "x");
182         lua_pushnumber(L, p.Y);
183         lua_setfield(L, -2, "y");
184         lua_pushnumber(L, p.Z);
185         lua_setfield(L, -2, "z");
186 }
187
188 v3s16 read_v3s16(lua_State *L, int index)
189 {
190         // Correct rounding at <0
191         v3f pf = read_v3f(L, index);
192         return floatToInt(pf, 1.0);
193 }
194
195 v3s16 check_v3s16(lua_State *L, int index)
196 {
197         // Correct rounding at <0
198         v3f pf = check_v3f(L, index);
199         return floatToInt(pf, 1.0);
200 }
201
202 video::SColor readARGB8(lua_State *L, int index)
203 {
204         video::SColor color(0);
205         CHECK_TYPE(index, "ARGB color", LUA_TTABLE);
206         lua_getfield(L, index, "a");
207         if(lua_isnumber(L, -1))
208                 color.setAlpha(lua_tonumber(L, -1));
209         lua_pop(L, 1);
210         lua_getfield(L, index, "r");
211         color.setRed(lua_tonumber(L, -1));
212         lua_pop(L, 1);
213         lua_getfield(L, index, "g");
214         color.setGreen(lua_tonumber(L, -1));
215         lua_pop(L, 1);
216         lua_getfield(L, index, "b");
217         color.setBlue(lua_tonumber(L, -1));
218         lua_pop(L, 1);
219         return color;
220 }
221
222 aabb3f read_aabb3f(lua_State *L, int index, f32 scale)
223 {
224         aabb3f box;
225         if(lua_istable(L, index)){
226                 lua_rawgeti(L, index, 1);
227                 box.MinEdge.X = lua_tonumber(L, -1) * scale;
228                 lua_pop(L, 1);
229                 lua_rawgeti(L, index, 2);
230                 box.MinEdge.Y = lua_tonumber(L, -1) * scale;
231                 lua_pop(L, 1);
232                 lua_rawgeti(L, index, 3);
233                 box.MinEdge.Z = lua_tonumber(L, -1) * scale;
234                 lua_pop(L, 1);
235                 lua_rawgeti(L, index, 4);
236                 box.MaxEdge.X = lua_tonumber(L, -1) * scale;
237                 lua_pop(L, 1);
238                 lua_rawgeti(L, index, 5);
239                 box.MaxEdge.Y = lua_tonumber(L, -1) * scale;
240                 lua_pop(L, 1);
241                 lua_rawgeti(L, index, 6);
242                 box.MaxEdge.Z = lua_tonumber(L, -1) * scale;
243                 lua_pop(L, 1);
244         }
245         return box;
246 }
247
248 std::vector<aabb3f> read_aabb3f_vector(lua_State *L, int index, f32 scale)
249 {
250         std::vector<aabb3f> boxes;
251         if(lua_istable(L, index)){
252                 int n = lua_objlen(L, index);
253                 // Check if it's a single box or a list of boxes
254                 bool possibly_single_box = (n == 6);
255                 for(int i = 1; i <= n && possibly_single_box; i++){
256                         lua_rawgeti(L, index, i);
257                         if(!lua_isnumber(L, -1))
258                                 possibly_single_box = false;
259                         lua_pop(L, 1);
260                 }
261                 if(possibly_single_box){
262                         // Read a single box
263                         boxes.push_back(read_aabb3f(L, index, scale));
264                 } else {
265                         // Read a list of boxes
266                         for(int i = 1; i <= n; i++){
267                                 lua_rawgeti(L, index, i);
268                                 boxes.push_back(read_aabb3f(L, -1, scale));
269                                 lua_pop(L, 1);
270                         }
271                 }
272         }
273         return boxes;
274 }
275
276 size_t read_stringlist(lua_State *L, int index, std::vector<std::string> *result)
277 {
278         if (index < 0)
279                 index = lua_gettop(L) + 1 + index;
280
281         size_t num_strings = 0;
282
283         if (lua_istable(L, index)) {
284                 lua_pushnil(L);
285                 while (lua_next(L, index)) {
286                         if (lua_isstring(L, -1)) {
287                                 result->push_back(lua_tostring(L, -1));
288                                 num_strings++;
289                         }
290                         lua_pop(L, 1);
291                 }
292         } else if (lua_isstring(L, index)) {
293                 result->push_back(lua_tostring(L, index));
294                 num_strings++;
295         }
296
297         return num_strings;
298 }
299
300 /*
301         Table field getters
302 */
303
304 bool getstringfield(lua_State *L, int table,
305                 const char *fieldname, std::string &result)
306 {
307         lua_getfield(L, table, fieldname);
308         bool got = false;
309         if(lua_isstring(L, -1)){
310                 size_t len = 0;
311                 const char *ptr = lua_tolstring(L, -1, &len);
312                 if (ptr) {
313                         result.assign(ptr, len);
314                         got = true;
315                 }
316         }
317         lua_pop(L, 1);
318         return got;
319 }
320
321 bool getintfield(lua_State *L, int table,
322                 const char *fieldname, int &result)
323 {
324         lua_getfield(L, table, fieldname);
325         bool got = false;
326         if(lua_isnumber(L, -1)){
327                 result = lua_tonumber(L, -1);
328                 got = true;
329         }
330         lua_pop(L, 1);
331         return got;
332 }
333
334 bool getintfield(lua_State *L, int table,
335                 const char *fieldname, u16 &result)
336 {
337         lua_getfield(L, table, fieldname);
338         bool got = false;
339         if(lua_isnumber(L, -1)){
340                 result = lua_tonumber(L, -1);
341                 got = true;
342         }
343         lua_pop(L, 1);
344         return got;
345 }
346
347 bool getintfield(lua_State *L, int table,
348                 const char *fieldname, u32 &result)
349 {
350         lua_getfield(L, table, fieldname);
351         bool got = false;
352         if(lua_isnumber(L, -1)){
353                 result = lua_tonumber(L, -1);
354                 got = true;
355         }
356         lua_pop(L, 1);
357         return got;
358 }
359
360 bool getfloatfield(lua_State *L, int table,
361                 const char *fieldname, float &result)
362 {
363         lua_getfield(L, table, fieldname);
364         bool got = false;
365         if(lua_isnumber(L, -1)){
366                 result = lua_tonumber(L, -1);
367                 got = true;
368         }
369         lua_pop(L, 1);
370         return got;
371 }
372
373 bool getboolfield(lua_State *L, int table,
374                 const char *fieldname, bool &result)
375 {
376         lua_getfield(L, table, fieldname);
377         bool got = false;
378         if(lua_isboolean(L, -1)){
379                 result = lua_toboolean(L, -1);
380                 got = true;
381         }
382         lua_pop(L, 1);
383         return got;
384 }
385
386 size_t getstringlistfield(lua_State *L, int table, const char *fieldname,
387                 std::vector<std::string> *result)
388 {
389         lua_getfield(L, table, fieldname);
390
391         size_t num_strings_read = read_stringlist(L, -1, result);
392
393         lua_pop(L, 1);
394         return num_strings_read;
395 }
396
397 std::string checkstringfield(lua_State *L, int table,
398                 const char *fieldname)
399 {
400         lua_getfield(L, table, fieldname);
401         CHECK_TYPE(-1, std::string("field \"") + fieldname + '"', LUA_TSTRING);
402         size_t len;
403         const char *s = lua_tolstring(L, -1, &len);
404         lua_pop(L, 1);
405         return std::string(s, len);
406 }
407
408 std::string getstringfield_default(lua_State *L, int table,
409                 const char *fieldname, const std::string &default_)
410 {
411         std::string result = default_;
412         getstringfield(L, table, fieldname, result);
413         return result;
414 }
415
416 int getintfield_default(lua_State *L, int table,
417                 const char *fieldname, int default_)
418 {
419         int result = default_;
420         getintfield(L, table, fieldname, result);
421         return result;
422 }
423
424 float getfloatfield_default(lua_State *L, int table,
425                 const char *fieldname, float default_)
426 {
427         float result = default_;
428         getfloatfield(L, table, fieldname, result);
429         return result;
430 }
431
432 bool getboolfield_default(lua_State *L, int table,
433                 const char *fieldname, bool default_)
434 {
435         bool result = default_;
436         getboolfield(L, table, fieldname, result);
437         return result;
438 }
439
440 void setintfield(lua_State *L, int table,
441                 const char *fieldname, int value)
442 {
443         lua_pushinteger(L, value);
444         if(table < 0)
445                 table -= 1;
446         lua_setfield(L, table, fieldname);
447 }
448
449 void setfloatfield(lua_State *L, int table,
450                 const char *fieldname, float value)
451 {
452         lua_pushnumber(L, value);
453         if(table < 0)
454                 table -= 1;
455         lua_setfield(L, table, fieldname);
456 }
457
458 void setboolfield(lua_State *L, int table,
459                 const char *fieldname, bool value)
460 {
461         lua_pushboolean(L, value);
462         if(table < 0)
463                 table -= 1;
464         lua_setfield(L, table, fieldname);
465 }
466
467