From a4c21984d519541bc367aa517313890321221a0f Mon Sep 17 00:00:00 2001 From: MihailRis Date: Tue, 7 May 2024 18:39:12 +0300 Subject: [PATCH] dynamic::Value simplified --- src/assets/AssetsLoader.cpp | 8 +- src/coders/binary_json.cpp | 67 ++++------- src/coders/binary_json.hpp | 2 +- src/coders/json.cpp | 52 ++++---- src/coders/json.hpp | 9 +- src/content/ContentLoader.cpp | 4 +- src/data/dynamic.cpp | 170 ++++++++++++--------------- src/data/dynamic.hpp | 76 ++++++------ src/files/WorldFiles.cpp | 4 +- src/files/files.cpp | 8 +- src/files/files.hpp | 4 +- src/files/settings_io.cpp | 18 +-- src/files/settings_io.hpp | 4 +- src/frontend/hud.cpp | 6 +- src/frontend/locale.cpp | 4 +- src/frontend/menu.cpp | 14 +-- src/frontend/menu.hpp | 7 +- src/logic/EngineController.cpp | 6 +- src/logic/scripting/lua/LuaState.cpp | 36 +++--- src/logic/scripting/lua/LuaState.hpp | 2 +- src/logic/scripting/lua/libcore.cpp | 4 +- src/logic/scripting/lua/libjson.cpp | 8 +- src/logic/scripting/scripting.cpp | 6 +- src/logic/scripting/scripting.hpp | 2 +- src/objects/Player.cpp | 2 +- src/world/World.cpp | 4 +- 26 files changed, 230 insertions(+), 297 deletions(-) diff --git a/src/assets/AssetsLoader.cpp b/src/assets/AssetsLoader.cpp index ae71d032..efa33d7d 100644 --- a/src/assets/AssetsLoader.cpp +++ b/src/assets/AssetsLoader.cpp @@ -131,14 +131,14 @@ void AssetsLoader::processPreloadList(AssetType tag, dynamic::List* list) { } for (uint i = 0; i < list->size(); i++) { auto value = list->get(i); - switch (static_cast(value->value.index())) { + switch (static_cast(value.index())) { case dynamic::valtype::string: - processPreload(tag, std::get(value->value), nullptr); + processPreload(tag, std::get(value), nullptr); break; case dynamic::valtype::map: { - auto map = std::get(value->value); + auto map = std::get(value); auto name = map->get("name"); - processPreload(tag, name, map); + processPreload(tag, name, map.get()); break; } default: diff --git a/src/coders/binary_json.cpp b/src/coders/binary_json.cpp index 0ee7ab00..e1cc95bd 100644 --- a/src/coders/binary_json.cpp +++ b/src/coders/binary_json.cpp @@ -9,24 +9,24 @@ using namespace json; using namespace dynamic; -static void to_binary(ByteBuilder& builder, const Value* value) { - switch (static_cast(value->value.index())) { +static void to_binary(ByteBuilder& builder, const Value& value) { + switch (static_cast(value.index())) { case valtype::none: throw std::runtime_error("none value is not implemented"); case valtype::map: { - std::vector bytes = to_binary(std::get(value->value)); + auto bytes = to_binary(std::get(value).get()); builder.put(bytes.data(), bytes.size()); break; } case valtype::list: builder.put(BJSON_TYPE_LIST); - for (auto& element : std::get(value->value)->values) { - to_binary(builder, element.get()); + for (auto& element : std::get(value)->values) { + to_binary(builder, element); } builder.put(BJSON_END); break; case valtype::integer: { - auto val = std::get(value->value); + auto val = std::get(value); if (val >= 0 && val <= 255) { builder.put(BJSON_TYPE_BYTE); builder.put(val); @@ -44,14 +44,14 @@ static void to_binary(ByteBuilder& builder, const Value* value) { } case valtype::number: builder.put(BJSON_TYPE_NUMBER); - builder.putFloat64(std::get(value->value)); + builder.putFloat64(std::get(value)); break; case valtype::boolean: - builder.put(BJSON_TYPE_FALSE + std::get(value->value)); + builder.put(BJSON_TYPE_FALSE + std::get(value)); break; case valtype::string: builder.put(BJSON_TYPE_STRING); - builder.put(std::get(value->value)); + builder.put(std::get(value)); break; } } @@ -73,7 +73,7 @@ std::vector json::to_binary(const Map* obj, bool compress) { // writing entries for (auto& entry : obj->values) { builder.putCStr(entry.first.c_str()); - to_binary(builder, entry.second.get()); + to_binary(builder, entry.second); } // terminating byte builder.put(BJSON_END); @@ -83,52 +83,40 @@ std::vector json::to_binary(const Map* obj, bool compress) { return builder.build(); } -static std::unique_ptr value_from_binary(ByteReader& reader) { +static Value value_from_binary(ByteReader& reader) { ubyte typecode = reader.get(); - valvalue val; switch (typecode) { case BJSON_TYPE_DOCUMENT: reader.getInt32(); - val = object_from_binary(reader).release(); - break; + return Map_sptr(object_from_binary(reader).release()); case BJSON_TYPE_LIST: - val = array_from_binary(reader).release(); - break; + return List_sptr(array_from_binary(reader).release()); case BJSON_TYPE_BYTE: - val = static_cast(reader.get()); - break; + return static_cast(reader.get()); case BJSON_TYPE_INT16: - val = static_cast(reader.getInt16()); - break; + return static_cast(reader.getInt16()); case BJSON_TYPE_INT32: - val = static_cast(reader.getInt32()); - break; + return static_cast(reader.getInt32()); case BJSON_TYPE_INT64: - val = reader.getInt64(); - break; + return reader.getInt64(); case BJSON_TYPE_NUMBER: - val = reader.getFloat64(); - break; + return reader.getFloat64(); case BJSON_TYPE_FALSE: case BJSON_TYPE_TRUE: - val = (typecode - BJSON_TYPE_FALSE) != 0; - break; + return (typecode - BJSON_TYPE_FALSE) != 0; case BJSON_TYPE_STRING: - val = reader.getString(); - break; + return reader.getString(); default: throw std::runtime_error( "type "+std::to_string(typecode)+" is not supported" ); } - return std::make_unique(val); } static std::unique_ptr array_from_binary(ByteReader& reader) { auto array = std::make_unique(); - auto& items = array->values; while (reader.peek() != BJSON_END) { - items.push_back(value_from_binary(reader)); + array->put(value_from_binary(reader)); } reader.get(); return array; @@ -136,16 +124,15 @@ static std::unique_ptr array_from_binary(ByteReader& reader) { static std::unique_ptr object_from_binary(ByteReader& reader) { auto obj = std::make_unique(); - auto& map = obj->values; while (reader.peek() != BJSON_END) { const char* key = reader.getCString(); - map.insert(std::make_pair(key, value_from_binary(reader))); + obj->put(key, value_from_binary(reader)); } reader.get(); return obj; } -std::unique_ptr json::from_binary(const ubyte* src, size_t size) { +std::shared_ptr json::from_binary(const ubyte* src, size_t size) { if (size < 2) { throw std::runtime_error("bytes length is less than 2"); } @@ -155,12 +142,10 @@ std::unique_ptr json::from_binary(const ubyte* src, size_t size) { return from_binary(data.data(), data.size()); } else { ByteReader reader(src, size); - std::unique_ptr value (value_from_binary(reader)); + Value value = value_from_binary(reader); - if (Map* const* map = std::get_if(&value->value)) { - std::unique_ptr obj (*map); - value->value = (Map*)nullptr; - return obj; + if (auto map = std::get_if(&value)) { + return *map; } else { throw std::runtime_error("root value is not an object"); } diff --git a/src/coders/binary_json.hpp b/src/coders/binary_json.hpp index 0c3056bb..ba7531bc 100644 --- a/src/coders/binary_json.hpp +++ b/src/coders/binary_json.hpp @@ -27,7 +27,7 @@ namespace json { const int BJSON_TYPE_CDOCUMENT = 0x1F; extern std::vector to_binary(const dynamic::Map* obj, bool compress=false); - extern std::unique_ptr from_binary(const ubyte* src, size_t size); + extern std::shared_ptr from_binary(const ubyte* src, size_t size); } #endif // CODERS_BINARY_JSON_HPP_ diff --git a/src/coders/json.cpp b/src/coders/json.cpp index b46c3a8a..376c5f13 100644 --- a/src/coders/json.cpp +++ b/src/coders/json.cpp @@ -27,7 +27,7 @@ inline void newline( } void stringify( - const Value* value, + const Value& value, std::stringstream& ss, int indent, const std::string& indentstr, @@ -43,16 +43,16 @@ void stringifyObj( ); void stringify( - const Value* value, + const Value& value, std::stringstream& ss, int indent, const std::string& indentstr, bool nice ) { - if (auto map = std::get_if(&value->value)) { - stringifyObj(*map, ss, indent, indentstr, nice); + if (auto map = std::get_if(&value)) { + stringifyObj(map->get(), ss, indent, indentstr, nice); } - else if (auto listptr = std::get_if(&value->value)) { + else if (auto listptr = std::get_if(&value)) { auto list = *listptr; if (list->size() == 0) { ss << "[]"; @@ -60,7 +60,7 @@ void stringify( } ss << '['; for (uint i = 0; i < list->size(); i++) { - Value* value = list->get(i); + Value& value = list->get(i); if (i > 0 || nice) { newline(ss, nice, indent, indentstr); } @@ -73,13 +73,13 @@ void stringify( newline(ss, true, indent - 1, indentstr); } ss << ']'; - } else if (auto flag = std::get_if(&value->value)) { + } else if (auto flag = std::get_if(&value)) { ss << (*flag ? "true" : "false"); - } else if (auto num = std::get_if(&value->value)) { + } else if (auto num = std::get_if(&value)) { ss << std::setprecision(15) << *num; - } else if (auto num = std::get_if(&value->value)) { + } else if (auto num = std::get_if(&value)) { ss << *num; - } else if (auto str = std::get_if(&value->value)) { + } else if (auto str = std::get_if(&value)) { ss << util::escape(*str); } } @@ -102,7 +102,7 @@ void stringifyObj( if (index > 0 || nice) { newline(ss, nice, indent, indentstr); } - Value* value = entry.second.get(); + const Value& value = entry.second; ss << util::escape(key) << ": "; stringify(value, ss, indent+1, indentstr, nice); index++; @@ -191,53 +191,47 @@ std::unique_ptr Parser::parseList() { return arr; } -std::unique_ptr Parser::parseValue() { +Value Parser::parseValue() { char next = peek(); - dynamic::valvalue val; if (next == '-' || next == '+') { pos++; number_u num; if (parseNumber(next == '-' ? -1 : 1, num)) { - val = std::get(num); + return std::get(num); } else { - val = std::get(num); + return std::get(num); } - return std::make_unique(val); } if (is_identifier_start(next)) { std::string literal = parseName(); if (literal == "true") { - return dynamic::value_of(true); + return true; } else if (literal == "false") { - return dynamic::value_of(false); + return false; } else if (literal == "inf") { - return dynamic::value_of(INFINITY); + return INFINITY; } else if (literal == "nan") { - return dynamic::value_of(NAN); + return NAN; } throw error("invalid literal "); } if (next == '{') { - val = parseObject().release(); - return std::make_unique(val); + return Map_sptr(parseObject().release()); } if (next == '[') { - val = parseList().release(); - return std::make_unique(val); + return List_sptr(parseList().release()); } if (is_digit(next)) { number_u num; if (parseNumber(1, num)) { - val = std::get(num); + return std::get(num); } else { - val = std::get(num); + return std::get(num); } - return std::make_unique(val); } if (next == '"' || next == '\'') { pos++; - val = parseString(next); - return std::make_unique(val); + return parseString(next); } throw error("unexpected character '"+std::string({next})+"'"); } diff --git a/src/coders/json.hpp b/src/coders/json.hpp index 5709d5a4..1643ce35 100644 --- a/src/coders/json.hpp +++ b/src/coders/json.hpp @@ -4,6 +4,7 @@ #include "commons.hpp" #include "binary_json.hpp" +#include "../data/dynamic.hpp" #include "../typedefs.hpp" #include @@ -12,17 +13,11 @@ #include #include -namespace dynamic { - class Map; - class List; - class Value; -} - namespace json { class Parser : public BasicParser { std::unique_ptr parseList(); std::unique_ptr parseObject(); - std::unique_ptr parseValue(); + dynamic::Value parseValue(); public: Parser(const std::string& filename, const std::string& source); diff --git a/src/content/ContentLoader.cpp b/src/content/ContentLoader.cpp index f6c53242..3e4bacfc 100644 --- a/src/content/ContentLoader.cpp +++ b/src/content/ContentLoader.cpp @@ -88,11 +88,11 @@ void ContentLoader::fixPackIndices() { auto blocksFolder = folder/ContentPack::BLOCKS_FOLDER; auto itemsFolder = folder/ContentPack::ITEMS_FOLDER; - std::unique_ptr root; + dynamic::Map_sptr root; if (fs::is_regular_file(indexFile)) { root = files::read_json(indexFile); } else { - root.reset(new dynamic::Map()); + root = std::make_shared(); } bool modified = false; diff --git a/src/data/dynamic.cpp b/src/data/dynamic.cpp index cce9b502..ec2b2942 100644 --- a/src/data/dynamic.cpp +++ b/src/data/dynamic.cpp @@ -2,91 +2,88 @@ using namespace dynamic; -List::~List() { -} - std::string List::str(size_t index) const { - const auto& val = values[index]; - switch (static_cast(val->value.index())) { - case valtype::string: return std::get(val->value); - case valtype::boolean: return std::get(val->value) ? "true" : "false"; - case valtype::number: return std::to_string(std::get(val->value)); - case valtype::integer: return std::to_string(std::get(val->value)); + const auto& value = values[index]; + switch (static_cast(value.index())) { + case valtype::string: return std::get(value); + case valtype::boolean: return std::get(value) ? "true" : "false"; + case valtype::number: return std::to_string(std::get(value)); + case valtype::integer: return std::to_string(std::get(value)); default: throw std::runtime_error("type error"); } } number_t List::num(size_t index) const { - const auto& val = values[index]; - switch (static_cast(val->value.index())) { - case valtype::number: return std::get(val->value); - case valtype::integer: return std::get(val->value); - case valtype::string: return std::stoll(std::get(val->value)); - case valtype::boolean: return std::get(val->value); + const auto& value = values[index]; + switch (static_cast(value.index())) { + case valtype::number: return std::get(value); + case valtype::integer: return std::get(value); + case valtype::string: return std::stoll(std::get(value)); + case valtype::boolean: return std::get(value); default: throw std::runtime_error("type error"); } } integer_t List::integer(size_t index) const { - const auto& val = values[index]; - switch (static_cast(val->value.index())) { - case valtype::number: return std::get(val->value); - case valtype::integer: return std::get(val->value); - case valtype::string: return std::stoll(std::get(val->value)); - case valtype::boolean: return std::get(val->value); + const auto& value = values[index]; + switch (static_cast(value.index())) { + case valtype::number: return std::get(value); + case valtype::integer: return std::get(value); + case valtype::string: return std::stoll(std::get(value)); + case valtype::boolean: return std::get(value); default: throw std::runtime_error("type error"); } } Map* List::map(size_t index) const { - if (auto* val = std::get_if(&values[index]->value)) { - return *val; + if (auto* val = std::get_if(&values[index])) { + return val->get(); } else { throw std::runtime_error("type error"); } } List* List::list(size_t index) const { - if (auto* val = std::get_if(&values[index]->value)) { - return *val; + if (auto* val = std::get_if(&values[index])) { + return val->get(); } else { throw std::runtime_error("type error"); } } bool List::flag(size_t index) const { - const auto& val = values[index]; - switch (static_cast(val->value.index())) { - case valtype::integer: return std::get(val->value); - case valtype::boolean: return std::get(val->value); + const auto& value = values[index]; + switch (static_cast(value.index())) { + case valtype::integer: return std::get(value); + case valtype::boolean: return std::get(value); default: throw std::runtime_error("type error"); } } -Value* List::getValueWriteable(size_t index) const { +Value* List::getValueWriteable(size_t index) { if (index > values.size()) { throw std::runtime_error("index error"); } - return values.at(index).get(); + return &values.at(index); } -List& List::put(std::unique_ptr value) { - values.emplace_back(std::move(value)); +List& List::put(const Value& value) { + values.emplace_back(value); return *this; } List& List::putList() { - List* arr = new List(); + auto arr = std::make_shared(); put(arr); return *arr; } Map& List::putMap() { - Map* map = new Map(); + auto map = std::make_shared(); put(map); return *map; } @@ -95,10 +92,7 @@ void List::remove(size_t index) { values.erase(values.begin() + index); } -Map::~Map() { -} - -void Map::str(std::string key, std::string& dst) const { +void Map::str(const std::string& key, std::string& dst) const { 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); if (found == values.end()) return def; - auto& val = found->second; - switch (static_cast(val->value.index())) { - case valtype::string: return std::get(val->value); - case valtype::boolean: return std::get(val->value) ? "true" : "false"; - case valtype::number: return std::to_string(std::get(val->value)); - case valtype::integer: return std::to_string(std::get(val->value)); + auto& value = found->second; + switch (static_cast(value.index())) { + case valtype::string: return std::get(value); + case valtype::boolean: return std::get(value) ? "true" : "false"; + case valtype::number: return std::to_string(std::get(value)); + case valtype::integer: return std::to_string(std::get(value)); 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); if (found == values.end()) return def; - auto& val = found->second; - switch (static_cast(val->value.index())) { - case valtype::number: return std::get(val->value); - case valtype::integer: return std::get(val->value); - case valtype::string: return std::stoull(std::get(val->value)); - case valtype::boolean: return std::get(val->value); + auto& value = found->second; + switch (static_cast(value.index())) { + case valtype::number: return std::get(value); + case valtype::integer: return std::get(value); + case valtype::string: return std::stoull(std::get(value)); + case valtype::boolean: return std::get(value); 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); if (found == values.end()) return def; - auto& val = found->second; - switch (static_cast(val->value.index())) { - case valtype::number: return std::get(val->value); - case valtype::integer: return std::get(val->value); - case valtype::string: return std::stoull(std::get(val->value)); - case valtype::boolean: return std::get(val->value); + auto& value = found->second; + switch (static_cast(value.index())) { + case valtype::number: return std::get(value); + case valtype::integer: return std::get(value); + case valtype::string: return std::stoull(std::get(value)); + case valtype::boolean: return std::get(value); 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); if (found == values.end()) return def; - auto& val = found->second; - switch (static_cast(val->value.index())) { - case valtype::integer: return std::get(val->value); - case valtype::boolean: return std::get(val->value); + auto& value = found->second; + switch (static_cast(value.index())) { + case valtype::integer: return std::get(value); + case valtype::boolean: return std::get(value); 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); } -void Map::num(std::string key, float& dst) const { +void Map::num(const std::string& key, float& dst) const { dst = get(key, static_cast(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(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(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); } -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(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(dst)); } -Map* Map::map(std::string key) const { +Map* Map::map(const std::string& key) const { auto found = values.find(key); if (found != values.end()) { - if (auto* val = std::get_if(&found->second->value)) { - return *val; + if (auto* val = std::get_if(&found->second)) { + return val->get(); } } return nullptr; } -List* Map::list(std::string key) const { +List* Map::list(const std::string& key) const { auto found = values.find(key); if (found != values.end()) - return std::get(found->second->value); + return std::get(found->second).get(); 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); } -Map& Map::put(std::string key, std::unique_ptr value) { - values.emplace(key, value.release()); +Map& Map::put(std::string key, const Value& value) { + values.emplace(key, value); return *this; } @@ -215,13 +209,13 @@ void Map::remove(const std::string& key) { } List& Map::putList(std::string key) { - List* arr = new List(); + auto arr = std::make_shared(); put(key, arr); return *arr; } Map& Map::putMap(std::string key) { - Map* obj = new Map(); + auto obj = std::make_shared(); put(key, obj); return *obj; } @@ -233,23 +227,3 @@ bool Map::has(const std::string& key) const { size_t Map::size() const { return values.size(); } - -Value::Value(valvalue value) : value(value) { -} - -Value::~Value() { - switch (static_cast(value.index())) { - case valtype::map: delete std::get(value); break; - case valtype::list: delete std::get(value); break; - default: - break; - } -} - -std::unique_ptr dynamic::value_of(const valvalue& value) { - return std::make_unique(value); -} - -std::unique_ptr dynamic::value_of(std::unique_ptr value) { - return std::make_unique(value.release()); -} diff --git a/src/data/dynamic.hpp b/src/data/dynamic.hpp index a2a24165..0e81dd4b 100644 --- a/src/data/dynamic.hpp +++ b/src/data/dynamic.hpp @@ -13,35 +13,27 @@ namespace dynamic { class Map; class List; - class Value; enum class valtype { none=0, map, list, string, number, boolean, integer }; - using valvalue = std::variant< + using Map_sptr = std::shared_ptr; + using List_sptr = std::shared_ptr; + + using Value = std::variant< std::monostate, - Map*, - List*, + Map_sptr, + List_sptr, std::string, number_t, bool, integer_t >; - class Value { - public: - valvalue value; - Value(valvalue value); - ~Value(); - }; - std::unique_ptr value_of(const valvalue& value); - std::unique_ptr value_of(std::unique_ptr value); - class List { public: - std::vector> values; - ~List(); + std::vector values; std::string str(size_t index) const; number_t num(size_t index) const; @@ -54,18 +46,19 @@ namespace dynamic { return values.size(); } - inline Value* get(size_t i) const { - return values.at(i).get(); + inline Value& get(size_t i) { + return values.at(i); } - template - List& put(T value) { - return put(std::make_unique(value)); + List& put(std::unique_ptr value) { + return put(Map_sptr(value.release())); } + List& put(std::unique_ptr value) { + return put(List_sptr(value.release())); + } + List& put(const Value& value); - List& put(std::unique_ptr value); - - Value* getValueWriteable(size_t index) const; + Value* getValueWriteable(size_t index); List& putList(); Map& putMap(); @@ -75,8 +68,7 @@ namespace dynamic { class Map { public: - std::unordered_map> values; - ~Map(); + std::unordered_map values; template T get(const std::string& key) const { @@ -101,27 +93,25 @@ namespace dynamic { return get(key, static_cast(def)); } - void str(std::string key, std::string& dst) const; - void num(std::string key, int& dst) const; - void num(std::string key, float& dst) const; - void num(std::string key, uint& dst) const; - void num(std::string key, int64_t& dst) const; - void num(std::string key, uint64_t& dst) const; - void num(std::string key, ubyte& dst) const; - void num(std::string key, double& dst) const; - Map* map(std::string key) const; - List* list(std::string key) const; - void flag(std::string key, bool& dst) const; + void str(const std::string& key, std::string& dst) const; + void num(const std::string& key, int& dst) const; + void num(const std::string& key, float& dst) const; + void num(const std::string& key, uint& dst) const; + void num(const std::string& key, int64_t& dst) const; + void num(const std::string& key, uint64_t& dst) const; + void num(const std::string& key, ubyte& dst) const; + void num(const std::string& key, double& dst) const; + Map* map(const std::string& key) const; + List* list(const std::string& key) const; + void flag(const std::string& key, bool& dst) const; - template - Map& put(std::string key, T value) { - return put(key, std::make_unique(value)); + Map& put(std::string key, std::unique_ptr value) { + return put(key, Map_sptr(value.release())); } - Map& put(std::string key, uint64_t value) { - return put(key, value_of(static_cast(value))); + Map& put(std::string key, std::unique_ptr value) { + return put(key, List_sptr(value.release())); } - - Map& put(std::string key, std::unique_ptr value); + Map& put(std::string key, const Value& value); void remove(const std::string& key); diff --git a/src/files/WorldFiles.cpp b/src/files/WorldFiles.cpp index e92d8e62..ff9b2663 100644 --- a/src/files/WorldFiles.cpp +++ b/src/files/WorldFiles.cpp @@ -134,7 +134,7 @@ static void erase_pack_indices(dynamic::Map* root, const std::string& id) { if (name.find(prefix) != 0) continue; auto value = blocks->getValueWriteable(i); - value->value = CORE_AIR; + *value = CORE_AIR; } 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) continue; auto value = items->getValueWriteable(i); - value->value = CORE_EMPTY; + *value = CORE_EMPTY; } } diff --git a/src/files/files.cpp b/src/files/files.cpp index 3cfffe76..d1ec0ffb 100644 --- a/src/files/files.cpp +++ b/src/files/files.cpp @@ -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()); } -std::unique_ptr files::read_json(fs::path filename) { +std::shared_ptr files::read_json(fs::path filename) { std::string text = files::read_string(filename); try { auto obj = json::parse(filename.string(), text); @@ -115,12 +115,10 @@ std::unique_ptr files::read_json(fs::path filename) { } } -std::unique_ptr files::read_binary_json(fs::path file) { +std::shared_ptr files::read_binary_json(fs::path file) { size_t size; std::unique_ptr bytes (files::read_bytes(file, size)); - return std::unique_ptr( - json::from_binary(bytes.get(), size) - ); + return json::from_binary(bytes.get(), size); } std::vector files::read_list(fs::path filename) { diff --git a/src/files/files.hpp b/src/files/files.hpp index 87a6e3a8..1270d6eb 100644 --- a/src/files/files.hpp +++ b/src/files/files.hpp @@ -64,8 +64,8 @@ namespace files { /// @brief Read JSON or BJSON file /// @param file *.json or *.bjson file - std::unique_ptr read_json(fs::path file); - std::unique_ptr read_binary_json(fs::path file); + std::shared_ptr read_json(fs::path file); + std::shared_ptr read_binary_json(fs::path file); std::vector read_list(fs::path file); } diff --git a/src/files/settings_io.cpp b/src/files/settings_io.cpp index e0c225f6..66fced1d 100644 --- a/src/files/settings_io.cpp +++ b/src/files/settings_io.cpp @@ -77,20 +77,20 @@ SettingsHandler::SettingsHandler(EngineSettings& settings) { builder.add("do-write-lights", &settings.debug.doWriteLights); } -std::unique_ptr SettingsHandler::getValue(const std::string& name) const { +dynamic::Value SettingsHandler::getValue(const std::string& name) const { auto found = map.find(name); if (found == map.end()) { throw std::runtime_error("setting '"+name+"' does not exist"); } auto setting = found->second; if (auto number = dynamic_cast(setting)) { - return dynamic::value_of((number_t)number->get()); + return static_cast(number->get()); } else if (auto integer = dynamic_cast(setting)) { - return dynamic::value_of((integer_t)integer->get()); + return static_cast(integer->get()); } else if (auto flag = dynamic_cast(setting)) { - return dynamic::value_of(flag->get()); + return flag->get(); } else if (auto string = dynamic_cast(setting)) { - return dynamic::value_of(string->get()); + return string->get(); } else { throw std::runtime_error("type is not implemented for '"+name+"'"); } @@ -119,18 +119,18 @@ bool SettingsHandler::has(const std::string& name) const { template static void set_numeric_value(T* setting, const dynamic::Value& value) { - if (auto num = std::get_if(&value.value)) { + if (auto num = std::get_if(&value)) { setting->set(*num); - } else if (auto num = std::get_if(&value.value)) { + } else if (auto num = std::get_if(&value)) { setting->set(*num); - } else if (auto flag = std::get_if(&value.value)) { + } else if (auto flag = std::get_if(&value)) { setting->set(*flag); } else { 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); if (found == map.end()) { throw std::runtime_error("setting '"+name+"' does not exist"); diff --git a/src/files/settings_io.hpp b/src/files/settings_io.hpp index 0d8c56fd..cc112e43 100644 --- a/src/files/settings_io.hpp +++ b/src/files/settings_io.hpp @@ -22,8 +22,8 @@ class SettingsHandler { public: SettingsHandler(EngineSettings& settings); - std::unique_ptr getValue(const std::string& name) const; - void setValue(const std::string& name, const dynamic::valvalue& value); + dynamic::Value getValue(const std::string& name) const; + void setValue(const std::string& name, const dynamic::Value& value); std::string toString(const std::string& name) const; Setting* getSetting(const std::string& name) const; bool has(const std::string& name) const; diff --git a/src/frontend/hud.cpp b/src/frontend/hud.cpp index e5ddb229..3b66c188 100644 --- a/src/frontend/hud.cpp +++ b/src/frontend/hud.cpp @@ -387,10 +387,10 @@ void Hud::add(HudElement element) { auto document = element.getDocument(); if (document) { auto inventory = invview ? invview->getInventory() : nullptr; - std::vector> args; - args.push_back(value_of(inventory ? inventory.get()->getId() : 0)); + std::vector args; + args.push_back(inventory ? inventory.get()->getId() : 0); for (int i = 0; i < 3; i++) { - args.push_back(value_of(static_cast(blockPos[i]))); + args.push_back(static_cast(blockPos[i])); } scripting::on_ui_open( element.getDocument(), diff --git a/src/frontend/locale.cpp b/src/frontend/locale.cpp index f99e5fd3..2afb23f6 100644 --- a/src/frontend/locale.cpp +++ b/src/frontend/locale.cpp @@ -76,10 +76,10 @@ void langs::loadLocalesInfo(const fs::path& resdir, std::string& fallback) { if (langs) { std::cout << "locales "; for (auto& entry : langs->values) { - auto langInfo = entry.second.get(); + auto langInfo = entry.second; std::string name; - if (auto mapptr = std::get_if(&langInfo->value)) { + if (auto mapptr = std::get_if(&langInfo)) { name = (*mapptr)->get("name", "none"s); } else { continue; diff --git a/src/frontend/menu.cpp b/src/frontend/menu.cpp index 73693bc7..e8a9b5fc 100644 --- a/src/frontend/menu.cpp +++ b/src/frontend/menu.cpp @@ -37,7 +37,7 @@ gui::page_loader_func menus::create_page_loader(Engine* engine) { return [=](const std::string& query) { using namespace dynamic; - std::vector> args; + std::vector args; std::string name; 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); name = query.substr(0, index); - auto map = std::make_unique(); + auto map = std::make_shared(); BasicParser parser("query for "+name, argstr); while (parser.hasNext()) { auto key = parser.readUntil('='); @@ -53,7 +53,7 @@ gui::page_loader_func menus::create_page_loader(Engine* engine) { auto value = parser.readUntil('&'); map->put(key, value); } - args.push_back(value_of(std::move(map))); + args.push_back(map); } else { 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> args) { +UiDocument* menus::show(Engine* engine, const std::string& name, std::vector args) { auto menu = engine->getGUI()->getMenu(); auto file = engine->getResPaths()->find("layouts/"+name+".xml"); auto fullname = "core:layouts/"+name; @@ -89,9 +89,9 @@ void menus::show_process_panel(Engine* engine, std::shared_ptr task, std:: auto menu = engine->getGUI()->getMenu(); menu->reset(); - std::vector> args; - args.emplace_back(value_of(util::wstr2str_utf8(langs::get(text)))); - auto doc = menus::show(engine, "process", std::move(args)); + auto doc = menus::show(engine, "process", { + util::wstr2str_utf8(langs::get(text)) + }); std::dynamic_pointer_cast(doc->getRoot())->listenInterval(0.01f, [=]() { task->update(); diff --git a/src/frontend/menu.hpp b/src/frontend/menu.hpp index cf3d7630..a47fb908 100644 --- a/src/frontend/menu.hpp +++ b/src/frontend/menu.hpp @@ -1,6 +1,7 @@ #ifndef FRONTEND_MENU_MENU_HPP_ #define FRONTEND_MENU_MENU_HPP_ +#include "../data/dynamic.hpp" #include "../graphics/ui/elements/Menu.hpp" #include @@ -12,10 +13,6 @@ class Engine; class UiDocument; -namespace dynamic { - class Value; -} - namespace menus { /// @brief Create development version label at the top-right screen corner void create_version_label(Engine* engine); @@ -25,7 +22,7 @@ namespace menus { UiDocument* show( Engine* engine, const std::string& name, - std::vector> args + std::vector args ); void show_process_panel(Engine* engine, std::shared_ptr task, std::wstring text=L""); diff --git a/src/logic/EngineController.cpp b/src/logic/EngineController.cpp index 82956279..6681942a 100644 --- a/src/logic/EngineController.cpp +++ b/src/logic/EngineController.cpp @@ -72,7 +72,7 @@ static void show_content_missing( std::shared_ptr lut ) { using namespace dynamic; - auto root = std::make_unique(); + auto root = std::make_shared(); auto& contentEntries = root->putList("content"); for (auto& entry : lut->getMissingContent()) { std::string contentName = contenttype_name(entry.type); @@ -80,9 +80,7 @@ static void show_content_missing( contentEntry.put("type", contentName); contentEntry.put("name", entry.name); } - std::vector> args; - args.emplace_back(std::make_unique(root.release())); - menus::show(engine, "reports/missing_content", std::move(args)); + menus::show(engine, "reports/missing_content", {root}); } static bool loadWorldContent(Engine* engine, fs::path folder) { diff --git a/src/logic/scripting/lua/LuaState.cpp b/src/logic/scripting/lua/LuaState.cpp index b79c958f..a8f682be 100644 --- a/src/logic/scripting/lua/LuaState.cpp +++ b/src/logic/scripting/lua/LuaState.cpp @@ -219,26 +219,26 @@ int lua::LuaState::pushvalue(int idx) { int lua::LuaState::pushvalue(const dynamic::Value& value) { using namespace dynamic; - if (auto* flag = std::get_if(&value.value)) { + if (auto* flag = std::get_if(&value)) { pushboolean(*flag); - } else if (auto* num = std::get_if(&value.value)) { + } else if (auto* num = std::get_if(&value)) { pushinteger(*num); - } else if (auto* num = std::get_if(&value.value)) { + } else if (auto* num = std::get_if(&value)) { pushnumber(*num); - } else if (auto* str = std::get_if(&value.value)) { + } else if (auto* str = std::get_if(&value)) { pushstring(str->c_str()); - } else if (List* const* listptr = std::get_if(&value.value)) { + } else if (auto listptr = std::get_if(&value)) { auto list = *listptr; lua_createtable(L, list->size(), 0); for (size_t i = 0; i < list->size(); i++) { - pushvalue(*list->get(i)); + pushvalue(list->get(i)); lua_rawseti(L, -2, i+1); } - } else if (Map* const* mapptr = std::get_if(&value.value)) { + } else if (auto mapptr = std::get_if(&value)) { auto map = *mapptr; lua_createtable(L, 0, map->size()); for (auto& entry : map->values) { - pushvalue(*entry.second); + pushvalue(entry.second); lua_setfield(L, -2, entry.first.c_str()); } } else { @@ -303,40 +303,40 @@ const char* lua::LuaState::tostring(int idx) { return lua_tostring(L, idx); } -std::unique_ptr lua::LuaState::tovalue(int idx) { +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 std::make_unique(std::monostate()); + return std::monostate(); case LUA_TBOOLEAN: - return dynamic::value_of(lua_toboolean(L, idx) == 1); + return 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 integer; } else { - return dynamic::value_of(number); + return number; } } case LUA_TSTRING: - return dynamic::value_of(lua_tostring(L, idx)); + return std::string(lua_tostring(L, idx)); case LUA_TTABLE: { int len = lua_objlen(L, idx); if (len) { // array - auto list = std::make_unique(); + auto list = std::make_shared(); for (int i = 1; i <= len; i++) { lua_rawgeti(L, idx, i); list->put(tovalue(-1)); lua_pop(L, 1); } - return std::make_unique(list.release()); + return list; } else { // table - auto map = std::make_unique(); + auto map = std::make_shared(); lua_pushvalue(L, idx); lua_pushnil(L); while (lua_next(L, -2)) { @@ -346,7 +346,7 @@ std::unique_ptr lua::LuaState::tovalue(int idx) { lua_pop(L, 2); } lua_pop(L, 1); - return std::make_unique(map.release()); + return map; } } default: diff --git a/src/logic/scripting/lua/LuaState.hpp b/src/logic/scripting/lua/LuaState.hpp index df1bacc7..0ab6194c 100644 --- a/src/logic/scripting/lua/LuaState.hpp +++ b/src/logic/scripting/lua/LuaState.hpp @@ -52,7 +52,7 @@ namespace lua { luanumber tonumber(int idx); glm::vec2 tovec2(int idx); glm::vec4 tocolor(int idx); - std::unique_ptr tovalue(int idx); + dynamic::Value tovalue(int idx); const char* tostring(int idx); bool isstring(int idx); bool isfunction(int idx); diff --git a/src/logic/scripting/lua/libcore.cpp b/src/logic/scripting/lua/libcore.cpp index 6caa105f..4f07f67a 100644 --- a/src/logic/scripting/lua/libcore.cpp +++ b/src/logic/scripting/lua/libcore.cpp @@ -110,14 +110,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(std::move(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->value); + scripting::engine->getSettingsHandler().setValue(name, value); return 0; } diff --git a/src/logic/scripting/lua/libjson.cpp b/src/logic/scripting/lua/libjson.cpp index 542be7cf..bce8b1b6 100644 --- a/src/logic/scripting/lua/libjson.cpp +++ b/src/logic/scripting/lua/libjson.cpp @@ -12,9 +12,9 @@ namespace scripting { static int l_json_stringify(lua_State* L) { auto value = scripting::state->tovalue(1); - if (auto mapptr = std::get_if(&value->value)) { + if (auto mapptr = std::get_if(&value)) { 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()); return 1; } else { @@ -26,7 +26,9 @@ static int l_json_stringify(lua_State* L) { static int l_json_parse(lua_State* L) { auto string = lua_tostring(L, 1); auto element = json::parse("", string); - auto value = std::make_unique(element.release()); + auto value = std::make_unique( + dynamic::Map_sptr(element.release()) + ); scripting::state->pushvalue(*value); return 1; } diff --git a/src/logic/scripting/scripting.cpp b/src/logic/scripting/scripting.cpp index 866be129..2e025dc4 100644 --- a/src/logic/scripting/scripting.cpp +++ b/src/logic/scripting/scripting.cpp @@ -228,13 +228,13 @@ bool scripting::on_item_break_block(Player* player, const ItemDef* item, int x, void scripting::on_ui_open( UiDocument* layout, - std::vector> args + std::vector args ) { - auto argsptr = std::make_shared>>(std::move(args)); + auto argsptr = std::make_shared>(std::move(args)); std::string name = layout->getId() + ".open"; state->emit_event(name, [=] (lua::LuaState* state) { for (const auto& value : *argsptr) { - state->pushvalue(*value); + state->pushvalue(value); } return argsptr->size(); }); diff --git a/src/logic/scripting/scripting.hpp b/src/logic/scripting/scripting.hpp index c4ed691c..d3c37f83 100644 --- a/src/logic/scripting/scripting.hpp +++ b/src/logic/scripting/scripting.hpp @@ -75,7 +75,7 @@ namespace scripting { /// @brief Called on UI view show void on_ui_open( UiDocument* layout, - std::vector> args + std::vector args ); void on_ui_progress(UiDocument* layout, int workDone, int totalWork); diff --git a/src/objects/Player.cpp b/src/objects/Player.cpp index 7a85c722..edd8acec 100644 --- a/src/objects/Player.cpp +++ b/src/objects/Player.cpp @@ -198,7 +198,7 @@ std::unique_ptr Player::serialize() const { root->put("flight", flight); root->put("noclip", noclip); root->put("chosen-slot", chosenSlot); - root->put("inventory", inventory->serialize().release()); + root->put("inventory", inventory->serialize()); return root; } diff --git a/src/world/World.cpp b/src/world/World.cpp index 0d023d1d..887307b9 100644 --- a/src/world/World.cpp +++ b/src/world/World.cpp @@ -69,7 +69,7 @@ void World::write(Level* level) { auto& players = playerFile.putList("players"); for (auto object : level->objects) { if (std::shared_ptr player = std::dynamic_pointer_cast(object)) { - players.put(player->serialize().release()); + players.put(player->serialize()); } } } @@ -209,7 +209,7 @@ std::unique_ptr World::serialize() const { root->put("name", name); root->put("generator", generator); - root->put("seed", seed); + root->put("seed", static_cast(seed)); auto& timeobj = root->putMap("time"); timeobj.put("day-time", daytime);