dynamic::Value simplified

This commit is contained in:
MihailRis 2024-05-07 18:39:12 +03:00
parent 8e83a07094
commit a4c21984d5
26 changed files with 230 additions and 297 deletions

View File

@ -131,14 +131,14 @@ void AssetsLoader::processPreloadList(AssetType tag, dynamic::List* list) {
} }
for (uint i = 0; i < list->size(); i++) { for (uint i = 0; i < list->size(); i++) {
auto value = list->get(i); auto value = list->get(i);
switch (static_cast<dynamic::valtype>(value->value.index())) { switch (static_cast<dynamic::valtype>(value.index())) {
case dynamic::valtype::string: case dynamic::valtype::string:
processPreload(tag, std::get<std::string>(value->value), nullptr); processPreload(tag, std::get<std::string>(value), nullptr);
break; break;
case dynamic::valtype::map: { case dynamic::valtype::map: {
auto map = std::get<dynamic::Map*>(value->value); auto map = std::get<dynamic::Map_sptr>(value);
auto name = map->get<std::string>("name"); auto name = map->get<std::string>("name");
processPreload(tag, name, map); processPreload(tag, name, map.get());
break; break;
} }
default: default:

View File

@ -9,24 +9,24 @@
using namespace json; using namespace json;
using namespace dynamic; using namespace dynamic;
static void to_binary(ByteBuilder& builder, const Value* value) { static void to_binary(ByteBuilder& builder, const Value& value) {
switch (static_cast<valtype>(value->value.index())) { switch (static_cast<valtype>(value.index())) {
case valtype::none: case valtype::none:
throw std::runtime_error("none value is not implemented"); throw std::runtime_error("none value is not implemented");
case valtype::map: { case valtype::map: {
std::vector<ubyte> bytes = to_binary(std::get<Map*>(value->value)); auto bytes = to_binary(std::get<Map_sptr>(value).get());
builder.put(bytes.data(), bytes.size()); builder.put(bytes.data(), bytes.size());
break; break;
} }
case valtype::list: case valtype::list:
builder.put(BJSON_TYPE_LIST); builder.put(BJSON_TYPE_LIST);
for (auto& element : std::get<List*>(value->value)->values) { for (auto& element : std::get<List_sptr>(value)->values) {
to_binary(builder, element.get()); to_binary(builder, element);
} }
builder.put(BJSON_END); builder.put(BJSON_END);
break; break;
case valtype::integer: { case valtype::integer: {
auto val = std::get<integer_t>(value->value); auto val = std::get<integer_t>(value);
if (val >= 0 && val <= 255) { if (val >= 0 && val <= 255) {
builder.put(BJSON_TYPE_BYTE); builder.put(BJSON_TYPE_BYTE);
builder.put(val); builder.put(val);
@ -44,14 +44,14 @@ static void to_binary(ByteBuilder& builder, const Value* value) {
} }
case valtype::number: case valtype::number:
builder.put(BJSON_TYPE_NUMBER); builder.put(BJSON_TYPE_NUMBER);
builder.putFloat64(std::get<number_t>(value->value)); builder.putFloat64(std::get<number_t>(value));
break; break;
case valtype::boolean: case valtype::boolean:
builder.put(BJSON_TYPE_FALSE + std::get<bool>(value->value)); builder.put(BJSON_TYPE_FALSE + std::get<bool>(value));
break; break;
case valtype::string: case valtype::string:
builder.put(BJSON_TYPE_STRING); builder.put(BJSON_TYPE_STRING);
builder.put(std::get<std::string>(value->value)); builder.put(std::get<std::string>(value));
break; break;
} }
} }
@ -73,7 +73,7 @@ std::vector<ubyte> json::to_binary(const Map* obj, bool compress) {
// writing entries // writing entries
for (auto& entry : obj->values) { for (auto& entry : obj->values) {
builder.putCStr(entry.first.c_str()); builder.putCStr(entry.first.c_str());
to_binary(builder, entry.second.get()); to_binary(builder, entry.second);
} }
// terminating byte // terminating byte
builder.put(BJSON_END); builder.put(BJSON_END);
@ -83,52 +83,40 @@ std::vector<ubyte> json::to_binary(const Map* obj, bool compress) {
return builder.build(); return builder.build();
} }
static std::unique_ptr<Value> value_from_binary(ByteReader& reader) { static Value value_from_binary(ByteReader& reader) {
ubyte typecode = reader.get(); ubyte typecode = reader.get();
valvalue val;
switch (typecode) { switch (typecode) {
case BJSON_TYPE_DOCUMENT: case BJSON_TYPE_DOCUMENT:
reader.getInt32(); reader.getInt32();
val = object_from_binary(reader).release(); return Map_sptr(object_from_binary(reader).release());
break;
case BJSON_TYPE_LIST: case BJSON_TYPE_LIST:
val = array_from_binary(reader).release(); return List_sptr(array_from_binary(reader).release());
break;
case BJSON_TYPE_BYTE: case BJSON_TYPE_BYTE:
val = static_cast<integer_t>(reader.get()); return static_cast<integer_t>(reader.get());
break;
case BJSON_TYPE_INT16: case BJSON_TYPE_INT16:
val = static_cast<integer_t>(reader.getInt16()); return static_cast<integer_t>(reader.getInt16());
break;
case BJSON_TYPE_INT32: case BJSON_TYPE_INT32:
val = static_cast<integer_t>(reader.getInt32()); return static_cast<integer_t>(reader.getInt32());
break;
case BJSON_TYPE_INT64: case BJSON_TYPE_INT64:
val = reader.getInt64(); return reader.getInt64();
break;
case BJSON_TYPE_NUMBER: case BJSON_TYPE_NUMBER:
val = reader.getFloat64(); return reader.getFloat64();
break;
case BJSON_TYPE_FALSE: case BJSON_TYPE_FALSE:
case BJSON_TYPE_TRUE: case BJSON_TYPE_TRUE:
val = (typecode - BJSON_TYPE_FALSE) != 0; return (typecode - BJSON_TYPE_FALSE) != 0;
break;
case BJSON_TYPE_STRING: case BJSON_TYPE_STRING:
val = reader.getString(); return reader.getString();
break;
default: default:
throw std::runtime_error( throw std::runtime_error(
"type "+std::to_string(typecode)+" is not supported" "type "+std::to_string(typecode)+" is not supported"
); );
} }
return std::make_unique<Value>(val);
} }
static std::unique_ptr<List> array_from_binary(ByteReader& reader) { static std::unique_ptr<List> array_from_binary(ByteReader& reader) {
auto array = std::make_unique<List>(); auto array = std::make_unique<List>();
auto& items = array->values;
while (reader.peek() != BJSON_END) { while (reader.peek() != BJSON_END) {
items.push_back(value_from_binary(reader)); array->put(value_from_binary(reader));
} }
reader.get(); reader.get();
return array; return array;
@ -136,16 +124,15 @@ static std::unique_ptr<List> array_from_binary(ByteReader& reader) {
static std::unique_ptr<Map> object_from_binary(ByteReader& reader) { static std::unique_ptr<Map> object_from_binary(ByteReader& reader) {
auto obj = std::make_unique<Map>(); auto obj = std::make_unique<Map>();
auto& map = obj->values;
while (reader.peek() != BJSON_END) { while (reader.peek() != BJSON_END) {
const char* key = reader.getCString(); const char* key = reader.getCString();
map.insert(std::make_pair(key, value_from_binary(reader))); obj->put(key, value_from_binary(reader));
} }
reader.get(); reader.get();
return obj; return obj;
} }
std::unique_ptr<Map> json::from_binary(const ubyte* src, size_t size) { std::shared_ptr<Map> json::from_binary(const ubyte* src, size_t size) {
if (size < 2) { if (size < 2) {
throw std::runtime_error("bytes length is less than 2"); throw std::runtime_error("bytes length is less than 2");
} }
@ -155,12 +142,10 @@ std::unique_ptr<Map> json::from_binary(const ubyte* src, size_t size) {
return from_binary(data.data(), data.size()); return from_binary(data.data(), data.size());
} else { } else {
ByteReader reader(src, size); ByteReader reader(src, size);
std::unique_ptr<Value> value (value_from_binary(reader)); Value value = value_from_binary(reader);
if (Map* const* map = std::get_if<Map*>(&value->value)) { if (auto map = std::get_if<Map_sptr>(&value)) {
std::unique_ptr<Map> obj (*map); return *map;
value->value = (Map*)nullptr;
return obj;
} else { } else {
throw std::runtime_error("root value is not an object"); throw std::runtime_error("root value is not an object");
} }

View File

@ -27,7 +27,7 @@ namespace json {
const int BJSON_TYPE_CDOCUMENT = 0x1F; const int BJSON_TYPE_CDOCUMENT = 0x1F;
extern std::vector<ubyte> to_binary(const dynamic::Map* obj, bool compress=false); extern std::vector<ubyte> to_binary(const dynamic::Map* obj, bool compress=false);
extern std::unique_ptr<dynamic::Map> from_binary(const ubyte* src, size_t size); extern std::shared_ptr<dynamic::Map> from_binary(const ubyte* src, size_t size);
} }
#endif // CODERS_BINARY_JSON_HPP_ #endif // CODERS_BINARY_JSON_HPP_

View File

@ -27,7 +27,7 @@ inline void newline(
} }
void stringify( void stringify(
const Value* value, const Value& value,
std::stringstream& ss, std::stringstream& ss,
int indent, int indent,
const std::string& indentstr, const std::string& indentstr,
@ -43,16 +43,16 @@ void stringifyObj(
); );
void stringify( void stringify(
const Value* value, const Value& value,
std::stringstream& ss, std::stringstream& ss,
int indent, int indent,
const std::string& indentstr, const std::string& indentstr,
bool nice bool nice
) { ) {
if (auto map = std::get_if<Map*>(&value->value)) { if (auto map = std::get_if<Map_sptr>(&value)) {
stringifyObj(*map, ss, indent, indentstr, nice); stringifyObj(map->get(), ss, indent, indentstr, nice);
} }
else if (auto listptr = std::get_if<List*>(&value->value)) { else if (auto listptr = std::get_if<List_sptr>(&value)) {
auto list = *listptr; auto list = *listptr;
if (list->size() == 0) { if (list->size() == 0) {
ss << "[]"; ss << "[]";
@ -60,7 +60,7 @@ void stringify(
} }
ss << '['; ss << '[';
for (uint i = 0; i < list->size(); i++) { for (uint i = 0; i < list->size(); i++) {
Value* value = list->get(i); Value& value = list->get(i);
if (i > 0 || nice) { if (i > 0 || nice) {
newline(ss, nice, indent, indentstr); newline(ss, nice, indent, indentstr);
} }
@ -73,13 +73,13 @@ void stringify(
newline(ss, true, indent - 1, indentstr); newline(ss, true, indent - 1, indentstr);
} }
ss << ']'; ss << ']';
} else if (auto flag = std::get_if<bool>(&value->value)) { } else if (auto flag = std::get_if<bool>(&value)) {
ss << (*flag ? "true" : "false"); ss << (*flag ? "true" : "false");
} else if (auto num = std::get_if<number_t>(&value->value)) { } else if (auto num = std::get_if<number_t>(&value)) {
ss << std::setprecision(15) << *num; ss << std::setprecision(15) << *num;
} else if (auto num = std::get_if<integer_t>(&value->value)) { } else if (auto num = std::get_if<integer_t>(&value)) {
ss << *num; ss << *num;
} else if (auto str = std::get_if<std::string>(&value->value)) { } else if (auto str = std::get_if<std::string>(&value)) {
ss << util::escape(*str); ss << util::escape(*str);
} }
} }
@ -102,7 +102,7 @@ void stringifyObj(
if (index > 0 || nice) { if (index > 0 || nice) {
newline(ss, nice, indent, indentstr); newline(ss, nice, indent, indentstr);
} }
Value* value = entry.second.get(); const Value& value = entry.second;
ss << util::escape(key) << ": "; ss << util::escape(key) << ": ";
stringify(value, ss, indent+1, indentstr, nice); stringify(value, ss, indent+1, indentstr, nice);
index++; index++;
@ -191,53 +191,47 @@ std::unique_ptr<List> Parser::parseList() {
return arr; return arr;
} }
std::unique_ptr<Value> Parser::parseValue() { Value Parser::parseValue() {
char next = peek(); char next = peek();
dynamic::valvalue val;
if (next == '-' || next == '+') { if (next == '-' || next == '+') {
pos++; pos++;
number_u num; number_u num;
if (parseNumber(next == '-' ? -1 : 1, num)) { if (parseNumber(next == '-' ? -1 : 1, num)) {
val = std::get<integer_t>(num); return std::get<integer_t>(num);
} else { } else {
val = std::get<number_t>(num); return std::get<number_t>(num);
} }
return std::make_unique<Value>(val);
} }
if (is_identifier_start(next)) { if (is_identifier_start(next)) {
std::string literal = parseName(); std::string literal = parseName();
if (literal == "true") { if (literal == "true") {
return dynamic::value_of(true); return true;
} else if (literal == "false") { } else if (literal == "false") {
return dynamic::value_of(false); return false;
} else if (literal == "inf") { } else if (literal == "inf") {
return dynamic::value_of(INFINITY); return INFINITY;
} else if (literal == "nan") { } else if (literal == "nan") {
return dynamic::value_of(NAN); return NAN;
} }
throw error("invalid literal "); throw error("invalid literal ");
} }
if (next == '{') { if (next == '{') {
val = parseObject().release(); return Map_sptr(parseObject().release());
return std::make_unique<Value>(val);
} }
if (next == '[') { if (next == '[') {
val = parseList().release(); return List_sptr(parseList().release());
return std::make_unique<Value>(val);
} }
if (is_digit(next)) { if (is_digit(next)) {
number_u num; number_u num;
if (parseNumber(1, num)) { if (parseNumber(1, num)) {
val = std::get<integer_t>(num); return std::get<integer_t>(num);
} else { } else {
val = std::get<number_t>(num); return std::get<number_t>(num);
} }
return std::make_unique<Value>(val);
} }
if (next == '"' || next == '\'') { if (next == '"' || next == '\'') {
pos++; pos++;
val = parseString(next); return parseString(next);
return std::make_unique<Value>(val);
} }
throw error("unexpected character '"+std::string({next})+"'"); throw error("unexpected character '"+std::string({next})+"'");
} }

View File

@ -4,6 +4,7 @@
#include "commons.hpp" #include "commons.hpp"
#include "binary_json.hpp" #include "binary_json.hpp"
#include "../data/dynamic.hpp"
#include "../typedefs.hpp" #include "../typedefs.hpp"
#include <vector> #include <vector>
@ -12,17 +13,11 @@
#include <stdexcept> #include <stdexcept>
#include <unordered_map> #include <unordered_map>
namespace dynamic {
class Map;
class List;
class Value;
}
namespace json { namespace json {
class Parser : public BasicParser { class Parser : public BasicParser {
std::unique_ptr<dynamic::List> parseList(); std::unique_ptr<dynamic::List> parseList();
std::unique_ptr<dynamic::Map> parseObject(); std::unique_ptr<dynamic::Map> parseObject();
std::unique_ptr<dynamic::Value> parseValue(); dynamic::Value parseValue();
public: public:
Parser(const std::string& filename, const std::string& source); Parser(const std::string& filename, const std::string& source);

View File

@ -88,11 +88,11 @@ void ContentLoader::fixPackIndices() {
auto blocksFolder = folder/ContentPack::BLOCKS_FOLDER; auto blocksFolder = folder/ContentPack::BLOCKS_FOLDER;
auto itemsFolder = folder/ContentPack::ITEMS_FOLDER; auto itemsFolder = folder/ContentPack::ITEMS_FOLDER;
std::unique_ptr<dynamic::Map> root; dynamic::Map_sptr root;
if (fs::is_regular_file(indexFile)) { if (fs::is_regular_file(indexFile)) {
root = files::read_json(indexFile); root = files::read_json(indexFile);
} else { } else {
root.reset(new dynamic::Map()); root = std::make_shared<dynamic::Map>();
} }
bool modified = false; bool modified = false;

View File

@ -2,91 +2,88 @@
using namespace dynamic; using namespace dynamic;
List::~List() {
}
std::string List::str(size_t index) const { std::string List::str(size_t index) const {
const auto& val = values[index]; const auto& value = values[index];
switch (static_cast<valtype>(val->value.index())) { switch (static_cast<valtype>(value.index())) {
case valtype::string: return std::get<std::string>(val->value); case valtype::string: return std::get<std::string>(value);
case valtype::boolean: return std::get<bool>(val->value) ? "true" : "false"; case valtype::boolean: return std::get<bool>(value) ? "true" : "false";
case valtype::number: return std::to_string(std::get<double>(val->value)); case valtype::number: return std::to_string(std::get<double>(value));
case valtype::integer: return std::to_string(std::get<int64_t>(val->value)); case valtype::integer: return std::to_string(std::get<int64_t>(value));
default: default:
throw std::runtime_error("type error"); throw std::runtime_error("type error");
} }
} }
number_t List::num(size_t index) const { number_t List::num(size_t index) const {
const auto& val = values[index]; const auto& value = values[index];
switch (static_cast<valtype>(val->value.index())) { switch (static_cast<valtype>(value.index())) {
case valtype::number: return std::get<number_t>(val->value); case valtype::number: return std::get<number_t>(value);
case valtype::integer: return std::get<integer_t>(val->value); case valtype::integer: return std::get<integer_t>(value);
case valtype::string: return std::stoll(std::get<std::string>(val->value)); case valtype::string: return std::stoll(std::get<std::string>(value));
case valtype::boolean: return std::get<bool>(val->value); case valtype::boolean: return std::get<bool>(value);
default: default:
throw std::runtime_error("type error"); throw std::runtime_error("type error");
} }
} }
integer_t List::integer(size_t index) const { integer_t List::integer(size_t index) const {
const auto& val = values[index]; const auto& value = values[index];
switch (static_cast<valtype>(val->value.index())) { switch (static_cast<valtype>(value.index())) {
case valtype::number: return std::get<number_t>(val->value); case valtype::number: return std::get<number_t>(value);
case valtype::integer: return std::get<integer_t>(val->value); case valtype::integer: return std::get<integer_t>(value);
case valtype::string: return std::stoll(std::get<std::string>(val->value)); case valtype::string: return std::stoll(std::get<std::string>(value));
case valtype::boolean: return std::get<bool>(val->value); case valtype::boolean: return std::get<bool>(value);
default: default:
throw std::runtime_error("type error"); throw std::runtime_error("type error");
} }
} }
Map* List::map(size_t index) const { Map* List::map(size_t index) const {
if (auto* val = std::get_if<Map*>(&values[index]->value)) { if (auto* val = std::get_if<Map_sptr>(&values[index])) {
return *val; return val->get();
} else { } else {
throw std::runtime_error("type error"); throw std::runtime_error("type error");
} }
} }
List* List::list(size_t index) const { List* List::list(size_t index) const {
if (auto* val = std::get_if<List*>(&values[index]->value)) { if (auto* val = std::get_if<List_sptr>(&values[index])) {
return *val; return val->get();
} else { } else {
throw std::runtime_error("type error"); throw std::runtime_error("type error");
} }
} }
bool List::flag(size_t index) const { bool List::flag(size_t index) const {
const auto& val = values[index]; const auto& value = values[index];
switch (static_cast<valtype>(val->value.index())) { switch (static_cast<valtype>(value.index())) {
case valtype::integer: return std::get<integer_t>(val->value); case valtype::integer: return std::get<integer_t>(value);
case valtype::boolean: return std::get<bool>(val->value); case valtype::boolean: return std::get<bool>(value);
default: default:
throw std::runtime_error("type error"); throw std::runtime_error("type error");
} }
} }
Value* List::getValueWriteable(size_t index) const { Value* List::getValueWriteable(size_t index) {
if (index > values.size()) { if (index > values.size()) {
throw std::runtime_error("index error"); throw std::runtime_error("index error");
} }
return values.at(index).get(); return &values.at(index);
} }
List& List::put(std::unique_ptr<Value> value) { List& List::put(const Value& value) {
values.emplace_back(std::move(value)); values.emplace_back(value);
return *this; return *this;
} }
List& List::putList() { List& List::putList() {
List* arr = new List(); auto arr = std::make_shared<List>();
put(arr); put(arr);
return *arr; return *arr;
} }
Map& List::putMap() { Map& List::putMap() {
Map* map = new Map(); auto map = std::make_shared<Map>();
put(map); put(map);
return *map; return *map;
} }
@ -95,10 +92,7 @@ void List::remove(size_t index) {
values.erase(values.begin() + index); values.erase(values.begin() + index);
} }
Map::~Map() { void Map::str(const std::string& key, std::string& dst) const {
}
void Map::str(std::string key, std::string& dst) const {
dst = get(key, dst); dst = get(key, dst);
} }
@ -106,12 +100,12 @@ std::string Map::get(const std::string& key, const std::string def) const {
auto found = values.find(key); auto found = values.find(key);
if (found == values.end()) if (found == values.end())
return def; return def;
auto& val = found->second; auto& value = found->second;
switch (static_cast<valtype>(val->value.index())) { switch (static_cast<valtype>(value.index())) {
case valtype::string: return std::get<std::string>(val->value); case valtype::string: return std::get<std::string>(value);
case valtype::boolean: return std::get<bool>(val->value) ? "true" : "false"; case valtype::boolean: return std::get<bool>(value) ? "true" : "false";
case valtype::number: return std::to_string(std::get<number_t>(val->value)); case valtype::number: return std::to_string(std::get<number_t>(value));
case valtype::integer: return std::to_string(std::get<integer_t>(val->value)); case valtype::integer: return std::to_string(std::get<integer_t>(value));
default: throw std::runtime_error("type error"); default: throw std::runtime_error("type error");
} }
} }
@ -120,12 +114,12 @@ number_t Map::get(const std::string& key, double def) const {
auto found = values.find(key); auto found = values.find(key);
if (found == values.end()) if (found == values.end())
return def; return def;
auto& val = found->second; auto& value = found->second;
switch (static_cast<valtype>(val->value.index())) { switch (static_cast<valtype>(value.index())) {
case valtype::number: return std::get<number_t>(val->value); case valtype::number: return std::get<number_t>(value);
case valtype::integer: return std::get<integer_t>(val->value); case valtype::integer: return std::get<integer_t>(value);
case valtype::string: return std::stoull(std::get<std::string>(val->value)); case valtype::string: return std::stoull(std::get<std::string>(value));
case valtype::boolean: return std::get<bool>(val->value); case valtype::boolean: return std::get<bool>(value);
default: throw std::runtime_error("type error"); default: throw std::runtime_error("type error");
} }
} }
@ -134,12 +128,12 @@ integer_t Map::get(const std::string& key, integer_t def) const {
auto found = values.find(key); auto found = values.find(key);
if (found == values.end()) if (found == values.end())
return def; return def;
auto& val = found->second; auto& value = found->second;
switch (static_cast<valtype>(val->value.index())) { switch (static_cast<valtype>(value.index())) {
case valtype::number: return std::get<number_t>(val->value); case valtype::number: return std::get<number_t>(value);
case valtype::integer: return std::get<integer_t>(val->value); case valtype::integer: return std::get<integer_t>(value);
case valtype::string: return std::stoull(std::get<std::string>(val->value)); case valtype::string: return std::stoull(std::get<std::string>(value));
case valtype::boolean: return std::get<bool>(val->value); case valtype::boolean: return std::get<bool>(value);
default: throw std::runtime_error("type error"); default: throw std::runtime_error("type error");
} }
} }
@ -148,65 +142,65 @@ bool Map::get(const std::string& key, bool def) const {
auto found = values.find(key); auto found = values.find(key);
if (found == values.end()) if (found == values.end())
return def; return def;
auto& val = found->second; auto& value = found->second;
switch (static_cast<valtype>(val->value.index())) { switch (static_cast<valtype>(value.index())) {
case valtype::integer: return std::get<integer_t>(val->value); case valtype::integer: return std::get<integer_t>(value);
case valtype::boolean: return std::get<bool>(val->value); case valtype::boolean: return std::get<bool>(value);
default: throw std::runtime_error("type error"); default: throw std::runtime_error("type error");
} }
} }
void Map::num(std::string key, double& dst) const { void Map::num(const std::string& key, double& dst) const {
dst = get(key, dst); dst = get(key, dst);
} }
void Map::num(std::string key, float& dst) const { void Map::num(const std::string& key, float& dst) const {
dst = get(key, static_cast<number_t>(dst)); dst = get(key, static_cast<number_t>(dst));
} }
void Map::num(std::string key, ubyte& dst) const { void Map::num(const std::string& key, ubyte& dst) const {
dst = get(key, static_cast<integer_t>(dst)); dst = get(key, static_cast<integer_t>(dst));
} }
void Map::num(std::string key, int& dst) const { void Map::num(const std::string& key, int& dst) const {
dst = get(key, static_cast<integer_t>(dst)); dst = get(key, static_cast<integer_t>(dst));
} }
void Map::num(std::string key, int64_t& dst) const { void Map::num(const std::string& key, int64_t& dst) const {
dst = get(key, dst); dst = get(key, dst);
} }
void Map::num(std::string key, uint64_t& dst) const { void Map::num(const std::string& key, uint64_t& dst) const {
dst = get(key, static_cast<integer_t>(dst)); dst = get(key, static_cast<integer_t>(dst));
} }
void Map::num(std::string key, uint& dst) const { void Map::num(const std::string& key, uint& dst) const {
dst = get(key, static_cast<integer_t>(dst)); dst = get(key, static_cast<integer_t>(dst));
} }
Map* Map::map(std::string key) const { Map* Map::map(const std::string& key) const {
auto found = values.find(key); auto found = values.find(key);
if (found != values.end()) { if (found != values.end()) {
if (auto* val = std::get_if<Map*>(&found->second->value)) { if (auto* val = std::get_if<Map_sptr>(&found->second)) {
return *val; return val->get();
} }
} }
return nullptr; return nullptr;
} }
List* Map::list(std::string key) const { List* Map::list(const std::string& key) const {
auto found = values.find(key); auto found = values.find(key);
if (found != values.end()) if (found != values.end())
return std::get<List*>(found->second->value); return std::get<List_sptr>(found->second).get();
return nullptr; return nullptr;
} }
void Map::flag(std::string key, bool& dst) const { void Map::flag(const std::string& key, bool& dst) const {
dst = get(key, dst); dst = get(key, dst);
} }
Map& Map::put(std::string key, std::unique_ptr<Value> value) { Map& Map::put(std::string key, const Value& value) {
values.emplace(key, value.release()); values.emplace(key, value);
return *this; return *this;
} }
@ -215,13 +209,13 @@ void Map::remove(const std::string& key) {
} }
List& Map::putList(std::string key) { List& Map::putList(std::string key) {
List* arr = new List(); auto arr = std::make_shared<List>();
put(key, arr); put(key, arr);
return *arr; return *arr;
} }
Map& Map::putMap(std::string key) { Map& Map::putMap(std::string key) {
Map* obj = new Map(); auto obj = std::make_shared<Map>();
put(key, obj); put(key, obj);
return *obj; return *obj;
} }
@ -233,23 +227,3 @@ bool Map::has(const std::string& key) const {
size_t Map::size() const { size_t Map::size() const {
return values.size(); return values.size();
} }
Value::Value(valvalue value) : value(value) {
}
Value::~Value() {
switch (static_cast<valtype>(value.index())) {
case valtype::map: delete std::get<Map*>(value); break;
case valtype::list: delete std::get<List*>(value); break;
default:
break;
}
}
std::unique_ptr<Value> dynamic::value_of(const valvalue& value) {
return std::make_unique<Value>(value);
}
std::unique_ptr<Value> dynamic::value_of(std::unique_ptr<Map> value) {
return std::make_unique<Value>(value.release());
}

View File

@ -13,35 +13,27 @@
namespace dynamic { namespace dynamic {
class Map; class Map;
class List; class List;
class Value;
enum class valtype { enum class valtype {
none=0, map, list, string, number, boolean, integer none=0, map, list, string, number, boolean, integer
}; };
using valvalue = std::variant< using Map_sptr = std::shared_ptr<Map>;
using List_sptr = std::shared_ptr<List>;
using Value = std::variant<
std::monostate, std::monostate,
Map*, Map_sptr,
List*, List_sptr,
std::string, std::string,
number_t, number_t,
bool, bool,
integer_t integer_t
>; >;
class Value {
public:
valvalue value;
Value(valvalue value);
~Value();
};
std::unique_ptr<Value> value_of(const valvalue& value);
std::unique_ptr<Value> value_of(std::unique_ptr<Map> value);
class List { class List {
public: public:
std::vector<std::unique_ptr<Value>> values; std::vector<Value> values;
~List();
std::string str(size_t index) const; std::string str(size_t index) const;
number_t num(size_t index) const; number_t num(size_t index) const;
@ -54,18 +46,19 @@ namespace dynamic {
return values.size(); return values.size();
} }
inline Value* get(size_t i) const { inline Value& get(size_t i) {
return values.at(i).get(); return values.at(i);
} }
template<typename T> List& put(std::unique_ptr<Map> value) {
List& put(T value) { return put(Map_sptr(value.release()));
return put(std::make_unique<Value>(value));
} }
List& put(std::unique_ptr<List> value) {
return put(List_sptr(value.release()));
}
List& put(const Value& value);
List& put(std::unique_ptr<Value> value); Value* getValueWriteable(size_t index);
Value* getValueWriteable(size_t index) const;
List& putList(); List& putList();
Map& putMap(); Map& putMap();
@ -75,8 +68,7 @@ namespace dynamic {
class Map { class Map {
public: public:
std::unordered_map<std::string, std::unique_ptr<Value>> values; std::unordered_map<std::string, Value> values;
~Map();
template<typename T> template<typename T>
T get(const std::string& key) const { T get(const std::string& key) const {
@ -101,27 +93,25 @@ namespace dynamic {
return get(key, static_cast<integer_t>(def)); return get(key, static_cast<integer_t>(def));
} }
void str(std::string key, std::string& dst) const; void str(const std::string& key, std::string& dst) const;
void num(std::string key, int& dst) const; void num(const std::string& key, int& dst) const;
void num(std::string key, float& dst) const; void num(const std::string& key, float& dst) const;
void num(std::string key, uint& dst) const; void num(const std::string& key, uint& dst) const;
void num(std::string key, int64_t& dst) const; void num(const std::string& key, int64_t& dst) const;
void num(std::string key, uint64_t& dst) const; void num(const std::string& key, uint64_t& dst) const;
void num(std::string key, ubyte& dst) const; void num(const std::string& key, ubyte& dst) const;
void num(std::string key, double& dst) const; void num(const std::string& key, double& dst) const;
Map* map(std::string key) const; Map* map(const std::string& key) const;
List* list(std::string key) const; List* list(const std::string& key) const;
void flag(std::string key, bool& dst) const; void flag(const std::string& key, bool& dst) const;
template<typename T> Map& put(std::string key, std::unique_ptr<Map> value) {
Map& put(std::string key, T value) { return put(key, Map_sptr(value.release()));
return put(key, std::make_unique<Value>(value));
} }
Map& put(std::string key, uint64_t value) { Map& put(std::string key, std::unique_ptr<List> value) {
return put(key, value_of(static_cast<integer_t>(value))); return put(key, List_sptr(value.release()));
} }
Map& put(std::string key, const Value& value);
Map& put(std::string key, std::unique_ptr<Value> value);
void remove(const std::string& key); void remove(const std::string& key);

View File

@ -134,7 +134,7 @@ static void erase_pack_indices(dynamic::Map* root, const std::string& id) {
if (name.find(prefix) != 0) if (name.find(prefix) != 0)
continue; continue;
auto value = blocks->getValueWriteable(i); auto value = blocks->getValueWriteable(i);
value->value = CORE_AIR; *value = CORE_AIR;
} }
auto items = root->list("items"); auto items = root->list("items");
@ -143,7 +143,7 @@ static void erase_pack_indices(dynamic::Map* root, const std::string& id) {
if (name.find(prefix) != 0) if (name.find(prefix) != 0)
continue; continue;
auto value = items->getValueWriteable(i); auto value = items->getValueWriteable(i);
value->value = CORE_EMPTY; *value = CORE_EMPTY;
} }
} }

View File

@ -104,7 +104,7 @@ bool files::write_binary_json(fs::path filename, const dynamic::Map* obj, bool c
return files::write_bytes(filename, bytes.data(), bytes.size()); return files::write_bytes(filename, bytes.data(), bytes.size());
} }
std::unique_ptr<dynamic::Map> files::read_json(fs::path filename) { std::shared_ptr<dynamic::Map> files::read_json(fs::path filename) {
std::string text = files::read_string(filename); std::string text = files::read_string(filename);
try { try {
auto obj = json::parse(filename.string(), text); auto obj = json::parse(filename.string(), text);
@ -115,12 +115,10 @@ std::unique_ptr<dynamic::Map> files::read_json(fs::path filename) {
} }
} }
std::unique_ptr<dynamic::Map> files::read_binary_json(fs::path file) { std::shared_ptr<dynamic::Map> files::read_binary_json(fs::path file) {
size_t size; size_t size;
std::unique_ptr<ubyte[]> bytes (files::read_bytes(file, size)); std::unique_ptr<ubyte[]> bytes (files::read_bytes(file, size));
return std::unique_ptr<dynamic::Map>( return json::from_binary(bytes.get(), size);
json::from_binary(bytes.get(), size)
);
} }
std::vector<std::string> files::read_list(fs::path filename) { std::vector<std::string> files::read_list(fs::path filename) {

View File

@ -64,8 +64,8 @@ namespace files {
/// @brief Read JSON or BJSON file /// @brief Read JSON or BJSON file
/// @param file *.json or *.bjson file /// @param file *.json or *.bjson file
std::unique_ptr<dynamic::Map> read_json(fs::path file); std::shared_ptr<dynamic::Map> read_json(fs::path file);
std::unique_ptr<dynamic::Map> read_binary_json(fs::path file); std::shared_ptr<dynamic::Map> read_binary_json(fs::path file);
std::vector<std::string> read_list(fs::path file); std::vector<std::string> read_list(fs::path file);
} }

View File

@ -77,20 +77,20 @@ SettingsHandler::SettingsHandler(EngineSettings& settings) {
builder.add("do-write-lights", &settings.debug.doWriteLights); builder.add("do-write-lights", &settings.debug.doWriteLights);
} }
std::unique_ptr<dynamic::Value> SettingsHandler::getValue(const std::string& name) const { dynamic::Value SettingsHandler::getValue(const std::string& name) const {
auto found = map.find(name); auto found = map.find(name);
if (found == map.end()) { if (found == map.end()) {
throw std::runtime_error("setting '"+name+"' does not exist"); throw std::runtime_error("setting '"+name+"' does not exist");
} }
auto setting = found->second; auto setting = found->second;
if (auto number = dynamic_cast<NumberSetting*>(setting)) { if (auto number = dynamic_cast<NumberSetting*>(setting)) {
return dynamic::value_of((number_t)number->get()); return static_cast<number_t>(number->get());
} else if (auto integer = dynamic_cast<IntegerSetting*>(setting)) { } else if (auto integer = dynamic_cast<IntegerSetting*>(setting)) {
return dynamic::value_of((integer_t)integer->get()); return static_cast<integer_t>(integer->get());
} else if (auto flag = dynamic_cast<FlagSetting*>(setting)) { } else if (auto flag = dynamic_cast<FlagSetting*>(setting)) {
return dynamic::value_of(flag->get()); return flag->get();
} else if (auto string = dynamic_cast<StringSetting*>(setting)) { } else if (auto string = dynamic_cast<StringSetting*>(setting)) {
return dynamic::value_of(string->get()); return string->get();
} else { } else {
throw std::runtime_error("type is not implemented for '"+name+"'"); throw std::runtime_error("type is not implemented for '"+name+"'");
} }
@ -119,18 +119,18 @@ bool SettingsHandler::has(const std::string& name) const {
template<class T> template<class T>
static void set_numeric_value(T* setting, const dynamic::Value& value) { static void set_numeric_value(T* setting, const dynamic::Value& value) {
if (auto num = std::get_if<integer_t>(&value.value)) { if (auto num = std::get_if<integer_t>(&value)) {
setting->set(*num); setting->set(*num);
} else if (auto num = std::get_if<number_t>(&value.value)) { } else if (auto num = std::get_if<number_t>(&value)) {
setting->set(*num); setting->set(*num);
} else if (auto flag = std::get_if<bool>(&value.value)) { } else if (auto flag = std::get_if<bool>(&value)) {
setting->set(*flag); setting->set(*flag);
} else { } else {
throw std::runtime_error("type error, numeric value expected"); throw std::runtime_error("type error, numeric value expected");
} }
} }
void SettingsHandler::setValue(const std::string& name, const dynamic::valvalue& value) { void SettingsHandler::setValue(const std::string& name, const dynamic::Value& value) {
auto found = map.find(name); auto found = map.find(name);
if (found == map.end()) { if (found == map.end()) {
throw std::runtime_error("setting '"+name+"' does not exist"); throw std::runtime_error("setting '"+name+"' does not exist");

View File

@ -22,8 +22,8 @@ class SettingsHandler {
public: public:
SettingsHandler(EngineSettings& settings); SettingsHandler(EngineSettings& settings);
std::unique_ptr<dynamic::Value> getValue(const std::string& name) const; dynamic::Value getValue(const std::string& name) const;
void setValue(const std::string& name, const dynamic::valvalue& value); void setValue(const std::string& name, const dynamic::Value& value);
std::string toString(const std::string& name) const; std::string toString(const std::string& name) const;
Setting* getSetting(const std::string& name) const; Setting* getSetting(const std::string& name) const;
bool has(const std::string& name) const; bool has(const std::string& name) const;

View File

@ -387,10 +387,10 @@ void Hud::add(HudElement element) {
auto document = element.getDocument(); auto document = element.getDocument();
if (document) { if (document) {
auto inventory = invview ? invview->getInventory() : nullptr; auto inventory = invview ? invview->getInventory() : nullptr;
std::vector<std::unique_ptr<Value>> args; std::vector<Value> args;
args.push_back(value_of(inventory ? inventory.get()->getId() : 0)); args.push_back(inventory ? inventory.get()->getId() : 0);
for (int i = 0; i < 3; i++) { for (int i = 0; i < 3; i++) {
args.push_back(value_of(static_cast<integer_t>(blockPos[i]))); args.push_back(static_cast<integer_t>(blockPos[i]));
} }
scripting::on_ui_open( scripting::on_ui_open(
element.getDocument(), element.getDocument(),

View File

@ -76,10 +76,10 @@ void langs::loadLocalesInfo(const fs::path& resdir, std::string& fallback) {
if (langs) { if (langs) {
std::cout << "locales "; std::cout << "locales ";
for (auto& entry : langs->values) { for (auto& entry : langs->values) {
auto langInfo = entry.second.get(); auto langInfo = entry.second;
std::string name; std::string name;
if (auto mapptr = std::get_if<dynamic::Map*>(&langInfo->value)) { if (auto mapptr = std::get_if<dynamic::Map_sptr>(&langInfo)) {
name = (*mapptr)->get("name", "none"s); name = (*mapptr)->get("name", "none"s);
} else { } else {
continue; continue;

View File

@ -37,7 +37,7 @@ gui::page_loader_func menus::create_page_loader(Engine* engine) {
return [=](const std::string& query) { return [=](const std::string& query) {
using namespace dynamic; using namespace dynamic;
std::vector<std::unique_ptr<Value>> args; std::vector<Value> args;
std::string name; std::string name;
size_t index = query.find('?'); size_t index = query.find('?');
@ -45,7 +45,7 @@ gui::page_loader_func menus::create_page_loader(Engine* engine) {
auto argstr = query.substr(index+1); auto argstr = query.substr(index+1);
name = query.substr(0, index); name = query.substr(0, index);
auto map = std::make_unique<Map>(); auto map = std::make_shared<Map>();
BasicParser parser("query for "+name, argstr); BasicParser parser("query for "+name, argstr);
while (parser.hasNext()) { while (parser.hasNext()) {
auto key = parser.readUntil('='); auto key = parser.readUntil('=');
@ -53,7 +53,7 @@ gui::page_loader_func menus::create_page_loader(Engine* engine) {
auto value = parser.readUntil('&'); auto value = parser.readUntil('&');
map->put(key, value); map->put(key, value);
} }
args.push_back(value_of(std::move(map))); args.push_back(map);
} else { } else {
name = query; name = query;
} }
@ -69,7 +69,7 @@ gui::page_loader_func menus::create_page_loader(Engine* engine) {
}; };
} }
UiDocument* menus::show(Engine* engine, const std::string& name, std::vector<std::unique_ptr<dynamic::Value>> args) { UiDocument* menus::show(Engine* engine, const std::string& name, std::vector<dynamic::Value> args) {
auto menu = engine->getGUI()->getMenu(); auto menu = engine->getGUI()->getMenu();
auto file = engine->getResPaths()->find("layouts/"+name+".xml"); auto file = engine->getResPaths()->find("layouts/"+name+".xml");
auto fullname = "core:layouts/"+name; auto fullname = "core:layouts/"+name;
@ -89,9 +89,9 @@ void menus::show_process_panel(Engine* engine, std::shared_ptr<Task> task, std::
auto menu = engine->getGUI()->getMenu(); auto menu = engine->getGUI()->getMenu();
menu->reset(); menu->reset();
std::vector<std::unique_ptr<Value>> args; auto doc = menus::show(engine, "process", {
args.emplace_back(value_of(util::wstr2str_utf8(langs::get(text)))); util::wstr2str_utf8(langs::get(text))
auto doc = menus::show(engine, "process", std::move(args)); });
std::dynamic_pointer_cast<Container>(doc->getRoot())->listenInterval(0.01f, [=]() { std::dynamic_pointer_cast<Container>(doc->getRoot())->listenInterval(0.01f, [=]() {
task->update(); task->update();

View File

@ -1,6 +1,7 @@
#ifndef FRONTEND_MENU_MENU_HPP_ #ifndef FRONTEND_MENU_MENU_HPP_
#define FRONTEND_MENU_MENU_HPP_ #define FRONTEND_MENU_MENU_HPP_
#include "../data/dynamic.hpp"
#include "../graphics/ui/elements/Menu.hpp" #include "../graphics/ui/elements/Menu.hpp"
#include <string> #include <string>
@ -12,10 +13,6 @@ class Engine;
class UiDocument; class UiDocument;
namespace dynamic {
class Value;
}
namespace menus { namespace menus {
/// @brief Create development version label at the top-right screen corner /// @brief Create development version label at the top-right screen corner
void create_version_label(Engine* engine); void create_version_label(Engine* engine);
@ -25,7 +22,7 @@ namespace menus {
UiDocument* show( UiDocument* show(
Engine* engine, Engine* engine,
const std::string& name, const std::string& name,
std::vector<std::unique_ptr<dynamic::Value>> args std::vector<dynamic::Value> args
); );
void show_process_panel(Engine* engine, std::shared_ptr<Task> task, std::wstring text=L""); void show_process_panel(Engine* engine, std::shared_ptr<Task> task, std::wstring text=L"");

View File

@ -72,7 +72,7 @@ static void show_content_missing(
std::shared_ptr<ContentLUT> lut std::shared_ptr<ContentLUT> lut
) { ) {
using namespace dynamic; using namespace dynamic;
auto root = std::make_unique<Map>(); auto root = std::make_shared<Map>();
auto& contentEntries = root->putList("content"); auto& contentEntries = root->putList("content");
for (auto& entry : lut->getMissingContent()) { for (auto& entry : lut->getMissingContent()) {
std::string contentName = contenttype_name(entry.type); std::string contentName = contenttype_name(entry.type);
@ -80,9 +80,7 @@ static void show_content_missing(
contentEntry.put("type", contentName); contentEntry.put("type", contentName);
contentEntry.put("name", entry.name); contentEntry.put("name", entry.name);
} }
std::vector<std::unique_ptr<dynamic::Value>> args; menus::show(engine, "reports/missing_content", {root});
args.emplace_back(std::make_unique<Value>(root.release()));
menus::show(engine, "reports/missing_content", std::move(args));
} }
static bool loadWorldContent(Engine* engine, fs::path folder) { static bool loadWorldContent(Engine* engine, fs::path folder) {

View File

@ -219,26 +219,26 @@ int lua::LuaState::pushvalue(int idx) {
int lua::LuaState::pushvalue(const dynamic::Value& value) { int lua::LuaState::pushvalue(const dynamic::Value& value) {
using namespace dynamic; using namespace dynamic;
if (auto* flag = std::get_if<bool>(&value.value)) { if (auto* flag = std::get_if<bool>(&value)) {
pushboolean(*flag); pushboolean(*flag);
} else if (auto* num = std::get_if<integer_t>(&value.value)) { } else if (auto* num = std::get_if<integer_t>(&value)) {
pushinteger(*num); pushinteger(*num);
} else if (auto* num = std::get_if<number_t>(&value.value)) { } else if (auto* num = std::get_if<number_t>(&value)) {
pushnumber(*num); pushnumber(*num);
} else if (auto* str = std::get_if<std::string>(&value.value)) { } else if (auto* str = std::get_if<std::string>(&value)) {
pushstring(str->c_str()); pushstring(str->c_str());
} else if (List* const* listptr = std::get_if<List*>(&value.value)) { } else if (auto listptr = std::get_if<List_sptr>(&value)) {
auto list = *listptr; auto list = *listptr;
lua_createtable(L, list->size(), 0); lua_createtable(L, list->size(), 0);
for (size_t i = 0; i < list->size(); i++) { for (size_t i = 0; i < list->size(); i++) {
pushvalue(*list->get(i)); pushvalue(list->get(i));
lua_rawseti(L, -2, i+1); lua_rawseti(L, -2, i+1);
} }
} else if (Map* const* mapptr = std::get_if<Map*>(&value.value)) { } else if (auto mapptr = std::get_if<Map_sptr>(&value)) {
auto map = *mapptr; auto map = *mapptr;
lua_createtable(L, 0, map->size()); lua_createtable(L, 0, map->size());
for (auto& entry : map->values) { for (auto& entry : map->values) {
pushvalue(*entry.second); pushvalue(entry.second);
lua_setfield(L, -2, entry.first.c_str()); lua_setfield(L, -2, entry.first.c_str());
} }
} else { } else {
@ -303,40 +303,40 @@ const char* lua::LuaState::tostring(int idx) {
return lua_tostring(L, idx); return lua_tostring(L, idx);
} }
std::unique_ptr<dynamic::Value> lua::LuaState::tovalue(int idx) { dynamic::Value lua::LuaState::tovalue(int idx) {
using namespace dynamic; using namespace dynamic;
auto type = lua_type(L, idx); auto type = lua_type(L, idx);
switch (type) { switch (type) {
case LUA_TNIL: case LUA_TNIL:
case LUA_TNONE: case LUA_TNONE:
return std::make_unique<Value>(std::monostate()); return std::monostate();
case LUA_TBOOLEAN: case LUA_TBOOLEAN:
return dynamic::value_of(lua_toboolean(L, idx) == 1); return lua_toboolean(L, idx) == 1;
case LUA_TNUMBER: { case LUA_TNUMBER: {
auto number = lua_tonumber(L, idx); auto number = lua_tonumber(L, idx);
auto integer = lua_tointeger(L, idx); auto integer = lua_tointeger(L, idx);
if (number == (lua_Number)integer) { if (number == (lua_Number)integer) {
return dynamic::value_of(integer); return integer;
} else { } else {
return dynamic::value_of(number); return number;
} }
} }
case LUA_TSTRING: case LUA_TSTRING:
return dynamic::value_of(lua_tostring(L, idx)); return std::string(lua_tostring(L, idx));
case LUA_TTABLE: { case LUA_TTABLE: {
int len = lua_objlen(L, idx); int len = lua_objlen(L, idx);
if (len) { if (len) {
// array // array
auto list = std::make_unique<List>(); auto list = std::make_shared<List>();
for (int i = 1; i <= len; i++) { for (int i = 1; i <= len; i++) {
lua_rawgeti(L, idx, i); lua_rawgeti(L, idx, i);
list->put(tovalue(-1)); list->put(tovalue(-1));
lua_pop(L, 1); lua_pop(L, 1);
} }
return std::make_unique<Value>(list.release()); return list;
} else { } else {
// table // table
auto map = std::make_unique<Map>(); auto map = std::make_shared<Map>();
lua_pushvalue(L, idx); lua_pushvalue(L, idx);
lua_pushnil(L); lua_pushnil(L);
while (lua_next(L, -2)) { while (lua_next(L, -2)) {
@ -346,7 +346,7 @@ std::unique_ptr<dynamic::Value> lua::LuaState::tovalue(int idx) {
lua_pop(L, 2); lua_pop(L, 2);
} }
lua_pop(L, 1); lua_pop(L, 1);
return std::make_unique<Value>(map.release()); return map;
} }
} }
default: default:

View File

@ -52,7 +52,7 @@ namespace lua {
luanumber tonumber(int idx); luanumber tonumber(int idx);
glm::vec2 tovec2(int idx); glm::vec2 tovec2(int idx);
glm::vec4 tocolor(int idx); glm::vec4 tocolor(int idx);
std::unique_ptr<dynamic::Value> tovalue(int idx); dynamic::Value tovalue(int idx);
const char* tostring(int idx); const char* tostring(int idx);
bool isstring(int idx); bool isstring(int idx);
bool isfunction(int idx); bool isfunction(int idx);

View File

@ -110,14 +110,14 @@ static int l_get_bindings(lua_State* L) {
static int l_get_setting(lua_State* L) { static int l_get_setting(lua_State* L) {
auto name = lua_tostring(L, 1); auto name = lua_tostring(L, 1);
const auto value = scripting::engine->getSettingsHandler().getValue(name); const auto value = scripting::engine->getSettingsHandler().getValue(name);
scripting::state->pushvalue(*value); scripting::state->pushvalue(std::move(value));
return 1; return 1;
} }
static int l_set_setting(lua_State* L) { static int l_set_setting(lua_State* L) {
auto name = lua_tostring(L, 1); auto name = lua_tostring(L, 1);
const auto value = scripting::state->tovalue(2); const auto value = scripting::state->tovalue(2);
scripting::engine->getSettingsHandler().setValue(name, value->value); scripting::engine->getSettingsHandler().setValue(name, value);
return 0; return 0;
} }

View File

@ -12,9 +12,9 @@ namespace scripting {
static int l_json_stringify(lua_State* L) { static int l_json_stringify(lua_State* L) {
auto value = scripting::state->tovalue(1); auto value = scripting::state->tovalue(1);
if (auto mapptr = std::get_if<dynamic::Map*>(&value->value)) { if (auto mapptr = std::get_if<dynamic::Map_sptr>(&value)) {
bool nice = lua_toboolean(L, 2); bool nice = lua_toboolean(L, 2);
auto string = json::stringify(*mapptr, nice, " "); auto string = json::stringify(mapptr->get(), nice, " ");
lua_pushstring(L, string.c_str()); lua_pushstring(L, string.c_str());
return 1; return 1;
} else { } else {
@ -26,7 +26,9 @@ static int l_json_stringify(lua_State* L) {
static int l_json_parse(lua_State* L) { static int l_json_parse(lua_State* L) {
auto string = lua_tostring(L, 1); auto string = lua_tostring(L, 1);
auto element = json::parse("<string>", string); auto element = json::parse("<string>", string);
auto value = std::make_unique<dynamic::Value>(element.release()); auto value = std::make_unique<dynamic::Value>(
dynamic::Map_sptr(element.release())
);
scripting::state->pushvalue(*value); scripting::state->pushvalue(*value);
return 1; return 1;
} }

View File

@ -228,13 +228,13 @@ bool scripting::on_item_break_block(Player* player, const ItemDef* item, int x,
void scripting::on_ui_open( void scripting::on_ui_open(
UiDocument* layout, UiDocument* layout,
std::vector<std::unique_ptr<dynamic::Value>> args std::vector<dynamic::Value> args
) { ) {
auto argsptr = std::make_shared<std::vector<std::unique_ptr<dynamic::Value>>>(std::move(args)); auto argsptr = std::make_shared<std::vector<dynamic::Value>>(std::move(args));
std::string name = layout->getId() + ".open"; std::string name = layout->getId() + ".open";
state->emit_event(name, [=] (lua::LuaState* state) { state->emit_event(name, [=] (lua::LuaState* state) {
for (const auto& value : *argsptr) { for (const auto& value : *argsptr) {
state->pushvalue(*value); state->pushvalue(value);
} }
return argsptr->size(); return argsptr->size();
}); });

View File

@ -75,7 +75,7 @@ namespace scripting {
/// @brief Called on UI view show /// @brief Called on UI view show
void on_ui_open( void on_ui_open(
UiDocument* layout, UiDocument* layout,
std::vector<std::unique_ptr<dynamic::Value>> args std::vector<dynamic::Value> args
); );
void on_ui_progress(UiDocument* layout, int workDone, int totalWork); void on_ui_progress(UiDocument* layout, int workDone, int totalWork);

View File

@ -198,7 +198,7 @@ std::unique_ptr<dynamic::Map> Player::serialize() const {
root->put("flight", flight); root->put("flight", flight);
root->put("noclip", noclip); root->put("noclip", noclip);
root->put("chosen-slot", chosenSlot); root->put("chosen-slot", chosenSlot);
root->put("inventory", inventory->serialize().release()); root->put("inventory", inventory->serialize());
return root; return root;
} }

View File

@ -69,7 +69,7 @@ void World::write(Level* level) {
auto& players = playerFile.putList("players"); auto& players = playerFile.putList("players");
for (auto object : level->objects) { for (auto object : level->objects) {
if (std::shared_ptr<Player> player = std::dynamic_pointer_cast<Player>(object)) { if (std::shared_ptr<Player> player = std::dynamic_pointer_cast<Player>(object)) {
players.put(player->serialize().release()); players.put(player->serialize());
} }
} }
} }
@ -209,7 +209,7 @@ std::unique_ptr<dynamic::Map> World::serialize() const {
root->put("name", name); root->put("name", name);
root->put("generator", generator); root->put("generator", generator);
root->put("seed", seed); root->put("seed", static_cast<integer_t>(seed));
auto& timeobj = root->putMap("time"); auto& timeobj = root->putMap("time");
timeobj.put("day-time", daytime); timeobj.put("day-time", daytime);