// Copyright (C) 2012-2013 ChaosForge / Kornel Kisielewicz // http://chaosforge.org/ // // This file is part of NV Libraries. // For conditions of distribution and use, see copyright notice in nv.hh #include "nv/lua/lua_map_area.hh" #include "nv/flags.hh" #include "nv/lua/lua_area.hh" #include "nv/lua/lua_glm.hh" #include "nv/lua/lua_raw.hh" static const char* NLUA_MAP_AREA_METATABLE = "map_area"; typedef nv::flags<512> cell_set; nv::uint32 nlua_to_cell_id( lua_State* L, int index, nv::map_area* map ) { if ( lua_type( L, index ) == LUA_TSTRING ) return map->string_to_id( lua_tostring( L, index ) ); else return (nv::uint32)lua_tointeger( L, index ); } cell_set nlua_to_cell_set( lua_State* L, int index, nv::map_area* map ) { cell_set result; switch ( lua_type( L, index ) ) { case LUA_TTABLE : { lua_pushnil( L ); while ( lua_next( L, index ) != 0 ) { if ( lua_type( L, -1 ) == LUA_TSTRING ) result.set( map->string_to_id( lua_tostring( L, -1 ) ), true ); else result.set( lua_tointeger( L, -1 ), true ); lua_pop( L, 1 ); } } break; case LUA_TSTRING : result.set( map->string_to_id( lua_tostring( L, index ) ), true ); break; case LUA_TNUMBER : result.set( lua_tointeger( L, index ), true ); break; } return result; } bool nlua_is_map_area( lua_State* L, int index ) { return luaL_testudata( L, index, NLUA_MAP_AREA_METATABLE ) != 0; } nv::map_area* nlua_to_map_area( lua_State* L, int index ) { return *(nv::map_area**)luaL_checkudata( L, index, NLUA_MAP_AREA_METATABLE ); } void nlua_push_map_area( lua_State* L, nv::map_area* c ) { nv::map_area** pm = (nv::map_area**) (lua_newuserdata(L, sizeof(nv::map_area*))); *pm = c; luaL_getmetatable( L, NLUA_MAP_AREA_METATABLE ); lua_setmetatable( L, -2 ); } static int nlua_map_area_tostring( lua_State* L ) { lua_pushstring( L, "map_area" ); return 1; } static int nlua_map_area_gc( lua_State* L ) { nv::map_area* ma = nlua_to_map_area( L, 1 ); if ( ma != nullptr ) { delete ma; } return 0; } static int nlua_map_area_get_area( lua_State* L ) { nv::map_area* ma = nlua_to_map_area( L, 1 ); nlua_push_area( L, ma->get_rectangle() ); return 1; } static int nlua_map_area_get_shift( lua_State* L ) { nv::map_area* ma = nlua_to_map_area( L, 1 ); nlua_push_coord( L, ma->get_shift() ); return 1; } static int nlua_map_area_get_size( lua_State* L ) { nv::map_area* ma = nlua_to_map_area( L, 1 ); nlua_push_coord( L, ma->get_size() ); return 1; } static int nlua_map_area_get_cell( lua_State* L ) { nv::map_area* ma = nlua_to_map_area( L, 1 ); lua_pushstring( L, ma->id_to_string( ma->get_cell( nlua_to_coord( L, 2 ) ) ).c_str() ); return 1; } static int nlua_map_area_set_cell( lua_State* L ) { nv::map_area* ma = nlua_to_map_area( L, 1 ); ma->set_cell( nlua_to_coord( L, 2 ), nlua_to_cell_id( L, 3, ma ) ); return 0; } static int nlua_map_area_raw_get_cell( lua_State* L ) { nv::map_area* ma = nlua_to_map_area( L, 1 ); lua_pushinteger( L, ma->get_cell( nlua_to_coord( L, 2 ) ) ); return 1; } static int nlua_map_area_raw_set_cell( lua_State* L ) { nv::map_area* ma = nlua_to_map_area( L, 1 ); ma->set_cell( nlua_to_coord( L, 2 ), lua_tointeger( L, 3 ) ); return 0; } static int nlua_map_area_index( lua_State* L ) { nv::map_area* ma = nlua_to_map_area( L, 1 ); if ( lua_type( L, 1 ) == LUA_TSTRING ) { luaL_getmetafield( L, 1, "__functions" ); lua_pushvalue( L, 2 ); lua_rawget( L, -2 ); } else { lua_pushinteger( L, ma->get_cell( nlua_to_coord( L, 2 ) ) ); } return 1; } static int nlua_map_area_newindex( lua_State* L ) { nv::map_area* ma = nlua_to_map_area( L, 1 ); ma->set_cell( nlua_to_coord( L, 2 ), lua_tointeger( L, 3 ) ); return 0; } static int nlua_map_area_new_sub_area( lua_State* L ) { nv::map_area* ma = nlua_to_map_area( L, 1 ); nlua_push_map_area( L, ma->create_sub_area( nlua_to_area( L, 2 ) ) ); return 1; } static const luaL_Reg nlua_map_area_f[] = { { "get_area", nlua_map_area_get_area }, { "get_shift", nlua_map_area_get_shift }, { "get_size", nlua_map_area_get_size }, { "get_cell", nlua_map_area_get_cell }, { "set_cell", nlua_map_area_set_cell }, { "raw_get_cell", nlua_map_area_raw_get_cell }, { "raw_set_cell", nlua_map_area_raw_set_cell }, { "new_sub_area", nlua_map_area_new_sub_area }, {NULL, NULL} }; static const luaL_Reg nlua_map_area_mt[] = { { "__newindex", nlua_map_area_newindex }, { "__index", nlua_map_area_index }, { "__tostring", nlua_map_area_tostring }, { "__gc", nlua_map_area_gc }, {NULL, NULL} }; int luaopen_map_area( lua_State * L ) { luaL_newmetatable( L, NLUA_MAP_AREA_METATABLE ); nlua_register( L, nlua_map_area_mt, -1 ); lua_createtable( L, 0, 0 ); nlua_register( L, nlua_map_area_f, -1 ); lua_setfield(L, -2, "__functions" ); lua_pop( L, 1 ); return 0; } void nlua_register_map_area_interface( lua_State* L, int index ) { nlua_register( L, nlua_map_area_f, index ); } void nlua_register_map_area( lua_State* L ) { luaopen_map_area(L); }