3 Copyright (C) 2015 est31 <mtest31@outlook.com>
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.
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.
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.
21 #include "lua_api/l_areastore.h"
22 #include "lua_api/l_internal.h"
23 #include "common/c_converter.h"
24 #include "cpp_api/s_security.h"
25 #include "areastore.h"
28 #include "cmake_config.h"
32 static inline void get_data_and_border_flags(lua_State *L, u8 start_i,
33 bool *borders, bool *data)
35 if (!lua_isboolean(L, start_i))
37 *borders = lua_toboolean(L, start_i);
38 if (!lua_isboolean(L, start_i + 1))
40 *data = lua_toboolean(L, start_i + 1);
43 static void push_area(lua_State *L, const Area *a,
44 bool include_borders, bool include_data)
46 if (!include_borders && !include_data) {
47 lua_pushboolean(L, true);
51 if (include_borders) {
52 push_v3s16(L, a->minedge);
53 lua_setfield(L, -2, "min");
54 push_v3s16(L, a->maxedge);
55 lua_setfield(L, -2, "max");
58 lua_pushlstring(L, a->data.c_str(), a->data.size());
59 lua_setfield(L, -2, "data");
63 static inline void push_areas(lua_State *L, const std::vector<Area *> &areas,
64 bool borders, bool data)
67 size_t cnt = areas.size();
68 for (size_t i = 0; i < cnt; i++) {
69 lua_pushnumber(L, areas[i]->id);
70 push_area(L, areas[i], borders, data);
76 int LuaAreaStore::gc_object(lua_State *L)
78 LuaAreaStore *o = *(LuaAreaStore **)(lua_touserdata(L, 1));
83 // get_area(id, include_borders, include_data)
84 int LuaAreaStore::l_get_area(lua_State *L)
88 LuaAreaStore *o = checkobject(L, 1);
89 AreaStore *ast = o->as;
91 u32 id = luaL_checknumber(L, 2);
93 bool include_borders = true;
94 bool include_data = false;
95 get_data_and_border_flags(L, 3, &include_borders, &include_data);
99 res = ast->getArea(id);
100 push_area(L, res, include_borders, include_data);
105 // get_areas_for_pos(pos, include_borders, include_data)
106 int LuaAreaStore::l_get_areas_for_pos(lua_State *L)
108 NO_MAP_LOCK_REQUIRED;
110 LuaAreaStore *o = checkobject(L, 1);
111 AreaStore *ast = o->as;
113 v3s16 pos = check_v3s16(L, 2);
115 bool include_borders = true;
116 bool include_data = false;
117 get_data_and_border_flags(L, 3, &include_borders, &include_data);
119 std::vector<Area *> res;
121 ast->getAreasForPos(&res, pos);
122 push_areas(L, res, include_borders, include_data);
127 // get_areas_in_area(edge1, edge2, accept_overlap, include_borders, include_data)
128 int LuaAreaStore::l_get_areas_in_area(lua_State *L)
130 NO_MAP_LOCK_REQUIRED;
132 LuaAreaStore *o = checkobject(L, 1);
133 AreaStore *ast = o->as;
135 v3s16 minedge = check_v3s16(L, 2);
136 v3s16 maxedge = check_v3s16(L, 3);
138 bool include_borders = true;
139 bool include_data = false;
140 bool accept_overlap = false;
141 if (lua_isboolean(L, 4)) {
142 accept_overlap = lua_toboolean(L, 4);
143 get_data_and_border_flags(L, 5, &include_borders, &include_data);
145 std::vector<Area *> res;
147 ast->getAreasInArea(&res, minedge, maxedge, accept_overlap);
148 push_areas(L, res, include_borders, include_data);
153 // insert_area(edge1, edge2, data)
154 int LuaAreaStore::l_insert_area(lua_State *L)
156 NO_MAP_LOCK_REQUIRED;
158 LuaAreaStore *o = checkobject(L, 1);
159 AreaStore *ast = o->as;
163 a.minedge = check_v3s16(L, 2);
164 a.maxedge = check_v3s16(L, 3);
167 a.id = ast->getFreeId(a.minedge, a.maxedge);
169 if (a.id == AREA_ID_INVALID) {
170 // couldn't get free id
176 const char *data = luaL_checklstring(L, 4, &d_len);
178 a.data = std::string(data, d_len);
182 lua_pushnumber(L, a.id);
187 int LuaAreaStore::l_reserve(lua_State *L)
189 NO_MAP_LOCK_REQUIRED;
191 LuaAreaStore *o = checkobject(L, 1);
192 AreaStore *ast = o->as;
194 size_t count = luaL_checknumber(L, 2);
200 int LuaAreaStore::l_remove_area(lua_State *L)
202 NO_MAP_LOCK_REQUIRED;
204 LuaAreaStore *o = checkobject(L, 1);
205 AreaStore *ast = o->as;
207 u32 id = luaL_checknumber(L, 2);
208 bool success = ast->removeArea(id);
210 lua_pushboolean(L, success);
214 // set_cache_params(params)
215 int LuaAreaStore::l_set_cache_params(lua_State *L)
217 NO_MAP_LOCK_REQUIRED;
219 LuaAreaStore *o = checkobject(L, 1);
220 AreaStore *ast = o->as;
222 luaL_checktype(L, 2, LUA_TTABLE);
224 bool enabled = getboolfield_default(L, 2, "enabled", true);
225 u8 block_radius = getintfield_default(L, 2, "block_radius", 64);
226 size_t limit = getintfield_default(L, 2, "block_radius", 1000);
228 ast->setCacheParams(enabled, block_radius, limit);
235 int LuaAreaStore::l_to_string(lua_State *L)
237 NO_MAP_LOCK_REQUIRED;
239 LuaAreaStore *o = checkobject(L, 1);
240 AreaStore *ast = o->as;
242 std::ostringstream os(std::ios_base::binary);
244 std::string str = os.str();
246 lua_pushlstring(L, str.c_str(), str.length());
251 int LuaAreaStore::l_to_file(lua_State *L)
253 NO_MAP_LOCK_REQUIRED;
255 LuaAreaStore *o = checkobject(L, 1);
256 AreaStore *ast = o->as;
258 const char *filename = luaL_checkstring(L, 2);
259 CHECK_SECURE_PATH_OPTIONAL(L, filename);
261 std::ostringstream os(std::ios_base::binary);
264 lua_pushboolean(L, fs::safeWriteToFile(filename, os.str()));
269 int LuaAreaStore::l_from_string(lua_State *L)
271 NO_MAP_LOCK_REQUIRED;
273 LuaAreaStore *o = checkobject(L, 1);
274 AreaStore *ast = o->as;
277 const char *str = luaL_checklstring(L, 2, &len);
279 std::istringstream is(std::string(str, len), std::ios::binary);
280 bool success = ast->deserialize(is);
282 lua_pushboolean(L, success);
286 // from_file(filename)
287 int LuaAreaStore::l_from_file(lua_State *L)
289 NO_MAP_LOCK_REQUIRED;
291 LuaAreaStore *o = checkobject(L, 1);
292 AreaStore *ast = o->as;
294 const char *filename = luaL_checkstring(L, 2);
295 CHECK_SECURE_PATH_OPTIONAL(L, filename);
297 std::ifstream is(filename, std::ios::binary);
298 bool success = ast->deserialize(is);
300 lua_pushboolean(L, success);
305 LuaAreaStore::LuaAreaStore()
308 this->as = new SpatialAreaStore();
310 this->as = new VectorAreaStore();
314 LuaAreaStore::LuaAreaStore(const std::string &type)
317 if (type == "LibSpatial") {
318 this->as = new SpatialAreaStore();
322 this->as = new VectorAreaStore();
326 LuaAreaStore::~LuaAreaStore()
332 // Creates an LuaAreaStore and leaves it on top of stack
333 int LuaAreaStore::create_object(lua_State *L)
335 NO_MAP_LOCK_REQUIRED;
337 LuaAreaStore *o = (lua_isstring(L, 1)) ?
338 new LuaAreaStore(lua_tostring(L, 1)) :
341 *(void **)(lua_newuserdata(L, sizeof(void *))) = o;
342 luaL_getmetatable(L, className);
343 lua_setmetatable(L, -2);
347 LuaAreaStore *LuaAreaStore::checkobject(lua_State *L, int narg)
349 NO_MAP_LOCK_REQUIRED;
351 luaL_checktype(L, narg, LUA_TUSERDATA);
353 void *ud = luaL_checkudata(L, narg, className);
355 luaL_typerror(L, narg, className);
357 return *(LuaAreaStore **)ud; // unbox pointer
360 void LuaAreaStore::Register(lua_State *L)
363 int methodtable = lua_gettop(L);
364 luaL_newmetatable(L, className);
365 int metatable = lua_gettop(L);
367 lua_pushliteral(L, "__metatable");
368 lua_pushvalue(L, methodtable);
369 lua_settable(L, metatable); // hide metatable from Lua getmetatable()
371 lua_pushliteral(L, "__index");
372 lua_pushvalue(L, methodtable);
373 lua_settable(L, metatable);
375 lua_pushliteral(L, "__gc");
376 lua_pushcfunction(L, gc_object);
377 lua_settable(L, metatable);
379 lua_pop(L, 1); // drop metatable
381 luaL_openlib(L, 0, methods, 0); // fill methodtable
382 lua_pop(L, 1); // drop methodtable
384 // Can be created from Lua (AreaStore())
385 lua_register(L, className, create_object);
388 const char LuaAreaStore::className[] = "AreaStore";
389 const luaL_reg LuaAreaStore::methods[] = {
390 luamethod(LuaAreaStore, get_area),
391 luamethod(LuaAreaStore, get_areas_for_pos),
392 luamethod(LuaAreaStore, get_areas_in_area),
393 luamethod(LuaAreaStore, insert_area),
394 luamethod(LuaAreaStore, reserve),
395 luamethod(LuaAreaStore, remove_area),
396 luamethod(LuaAreaStore, set_cache_params),
397 /* luamethod(LuaAreaStore, to_string),
398 luamethod(LuaAreaStore, to_file),
399 luamethod(LuaAreaStore, from_string),
400 luamethod(LuaAreaStore, from_file),*/