lua json library
This commit is contained in:
@@ -128,6 +128,7 @@ void lua::LuaState::createLibs() {
|
||||
openlib("player", playerlib, 0);
|
||||
openlib("time", timelib, 0);
|
||||
openlib("world", worldlib, 0);
|
||||
openlib("json", jsonlib, 0);
|
||||
|
||||
addfunc("print", lua_wrap_errors<l_print>);
|
||||
}
|
||||
@@ -226,10 +227,24 @@ int lua::LuaState::pushvalue(const dynamic::Value& value) {
|
||||
case valtype::none:
|
||||
pushnil();
|
||||
break;
|
||||
case valtype::list:
|
||||
throw std::runtime_error("type 'list' is not implemented");
|
||||
case valtype::map:
|
||||
throw std::runtime_error("type 'map' is not implemented");
|
||||
case valtype::list: {
|
||||
auto list = std::get<dynamic::List*>(value.value);
|
||||
lua_createtable(L, list->size(), 0);
|
||||
for (size_t i = 0; i < list->size(); i++) {
|
||||
pushvalue(*list->get(i));
|
||||
lua_rawseti(L, -2, i+1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case valtype::map: {
|
||||
auto map = std::get<dynamic::Map*>(value.value);
|
||||
lua_createtable(L, 0, map->size());
|
||||
for (auto& entry : map->values) {
|
||||
pushvalue(*entry.second);
|
||||
lua_setfield(L, -2, entry.first.c_str());
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
@@ -277,28 +292,56 @@ const char* lua::LuaState::tostring(int idx) {
|
||||
return lua_tostring(L, idx);
|
||||
}
|
||||
|
||||
dynamic::Value lua::LuaState::tovalue(int idx) {
|
||||
using dynamic::valtype;
|
||||
std::unique_ptr<dynamic::Value> lua::LuaState::tovalue(int idx) {
|
||||
using namespace dynamic;
|
||||
auto type = lua_type(L, idx);
|
||||
switch (type) {
|
||||
case LUA_TNIL:
|
||||
case LUA_TNONE:
|
||||
return dynamic::Value(valtype::none, (integer_t)0);
|
||||
return std::make_unique<Value>(valtype::none, (integer_t)0);
|
||||
case LUA_TBOOLEAN:
|
||||
return dynamic::Value::boolean(lua_toboolean(L, idx) == 1);
|
||||
return Value::boolean(lua_toboolean(L, idx) == 1);
|
||||
case LUA_TNUMBER: {
|
||||
auto number = lua_tonumber(L, idx);
|
||||
auto integer = lua_tointeger(L, idx);
|
||||
if (number == (lua_Number)integer) {
|
||||
return dynamic::Value::of(integer);
|
||||
return Value::of(integer);
|
||||
} else {
|
||||
return dynamic::Value::of(number);
|
||||
return Value::of(number);
|
||||
}
|
||||
}
|
||||
case LUA_TSTRING:
|
||||
return dynamic::Value::of(lua_tostring(L, idx));
|
||||
return Value::of(lua_tostring(L, idx));
|
||||
case LUA_TTABLE: {
|
||||
int len = lua_objlen(L, idx);
|
||||
if (len) {
|
||||
// array
|
||||
auto list = std::make_unique<List>();
|
||||
for (int i = 1; i <= len; i++) {
|
||||
lua_rawgeti(L, idx, i);
|
||||
list->put(tovalue(-1));
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
return std::make_unique<Value>(valtype::list, list.release());
|
||||
} else {
|
||||
// table
|
||||
auto map = std::make_unique<Map>();
|
||||
lua_pushvalue(L, idx);
|
||||
lua_pushnil(L);
|
||||
while (lua_next(L, -2)) {
|
||||
lua_pushvalue(L, -2);
|
||||
auto key = lua_tostring(L, -1);
|
||||
map->put(key, tovalue(-2));
|
||||
lua_pop(L, 2);
|
||||
}
|
||||
lua_pop(L, 1);
|
||||
return std::make_unique<Value>(valtype::map, map.release());
|
||||
}
|
||||
}
|
||||
default:
|
||||
throw std::runtime_error("lua type "+std::to_string(type)+" is not supported");
|
||||
throw std::runtime_error(
|
||||
"lua type "+std::to_string(type)+" is not supported"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -47,7 +47,7 @@ namespace lua {
|
||||
bool toboolean(int idx);
|
||||
luaint tointeger(int idx);
|
||||
luanumber tonumber(int idx);
|
||||
dynamic::Value tovalue(int idx);
|
||||
std::unique_ptr<dynamic::Value> tovalue(int idx);
|
||||
const char* tostring(int idx);
|
||||
bool isstring(int idx);
|
||||
bool isfunction(int idx);
|
||||
|
||||
@@ -17,6 +17,7 @@ extern const luaL_Reg packlib [];
|
||||
extern const luaL_Reg playerlib [];
|
||||
extern const luaL_Reg timelib [];
|
||||
extern const luaL_Reg worldlib [];
|
||||
extern const luaL_Reg jsonlib [];
|
||||
|
||||
|
||||
// Lua Overrides
|
||||
|
||||
@@ -118,14 +118,14 @@ static int l_get_bindings(lua_State* L) {
|
||||
static int l_get_setting(lua_State* L) {
|
||||
auto name = lua_tostring(L, 1);
|
||||
const auto value = scripting::engine->getSettingsHandler().getValue(name);
|
||||
scripting::state->pushvalue(value);
|
||||
scripting::state->pushvalue(*value);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int l_set_setting(lua_State* L) {
|
||||
auto name = lua_tostring(L, 1);
|
||||
const auto value = scripting::state->tovalue(2);
|
||||
scripting::engine->getSettingsHandler().setValue(name, value);
|
||||
scripting::engine->getSettingsHandler().setValue(name, *value);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
#include "api_lua.h"
|
||||
#include "lua_commons.h"
|
||||
|
||||
#include "LuaState.h"
|
||||
|
||||
#include "../../../coders/json.h"
|
||||
#include "../../../data/dynamic.h"
|
||||
|
||||
namespace scripting {
|
||||
extern lua::LuaState* state;
|
||||
}
|
||||
|
||||
static int l_json_stringify(lua_State* L) {
|
||||
auto value = scripting::state->tovalue(1);
|
||||
if (value->type != dynamic::valtype::map) {
|
||||
luaL_error(L, "table expected");
|
||||
return 0;
|
||||
}
|
||||
bool nice = lua_toboolean(L, 2);
|
||||
auto string = json::stringify(std::get<dynamic::Map*>(value->value), nice, " ");
|
||||
lua_pushstring(L, string.c_str());
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int l_json_parse(lua_State* L) {
|
||||
auto string = lua_tostring(L, 1);
|
||||
auto element = json::parse("<string>", string);
|
||||
auto value = std::make_unique<dynamic::Value>(
|
||||
dynamic::valtype::map, element.release()
|
||||
);
|
||||
scripting::state->pushvalue(*value);
|
||||
return 1;
|
||||
}
|
||||
|
||||
const luaL_Reg jsonlib [] = {
|
||||
{"stringify", lua_wrap_errors<l_json_stringify>},
|
||||
{"parse", lua_wrap_errors<l_json_parse>},
|
||||
{NULL, NULL}
|
||||
};
|
||||
Reference in New Issue
Block a user