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++) {
auto value = list->get(i);
switch (static_cast<dynamic::valtype>(value->value.index())) {
switch (static_cast<dynamic::valtype>(value.index())) {
case dynamic::valtype::string:
processPreload(tag, std::get<std::string>(value->value), nullptr);
processPreload(tag, std::get<std::string>(value), nullptr);
break;
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");
processPreload(tag, name, map);
processPreload(tag, name, map.get());
break;
}
default:

View File

@ -9,24 +9,24 @@
using namespace json;
using namespace dynamic;
static void to_binary(ByteBuilder& builder, const Value* value) {
switch (static_cast<valtype>(value->value.index())) {
static void to_binary(ByteBuilder& builder, const Value& value) {
switch (static_cast<valtype>(value.index())) {
case valtype::none:
throw std::runtime_error("none value is not implemented");
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());
break;
}
case valtype::list:
builder.put(BJSON_TYPE_LIST);
for (auto& element : std::get<List*>(value->value)->values) {
to_binary(builder, element.get());
for (auto& element : std::get<List_sptr>(value)->values) {
to_binary(builder, element);
}
builder.put(BJSON_END);
break;
case valtype::integer: {
auto val = std::get<integer_t>(value->value);
auto val = std::get<integer_t>(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<number_t>(value->value));
builder.putFloat64(std::get<number_t>(value));
break;
case valtype::boolean:
builder.put(BJSON_TYPE_FALSE + std::get<bool>(value->value));
builder.put(BJSON_TYPE_FALSE + std::get<bool>(value));
break;
case valtype::string:
builder.put(BJSON_TYPE_STRING);
builder.put(std::get<std::string>(value->value));
builder.put(std::get<std::string>(value));
break;
}
}
@ -73,7 +73,7 @@ std::vector<ubyte> 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<ubyte> json::to_binary(const Map* obj, bool compress) {
return builder.build();
}
static std::unique_ptr<Value> 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<integer_t>(reader.get());
break;
return static_cast<integer_t>(reader.get());
case BJSON_TYPE_INT16:
val = static_cast<integer_t>(reader.getInt16());
break;
return static_cast<integer_t>(reader.getInt16());
case BJSON_TYPE_INT32:
val = static_cast<integer_t>(reader.getInt32());
break;
return static_cast<integer_t>(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<Value>(val);
}
static std::unique_ptr<List> array_from_binary(ByteReader& reader) {
auto array = std::make_unique<List>();
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<List> array_from_binary(ByteReader& reader) {
static std::unique_ptr<Map> object_from_binary(ByteReader& reader) {
auto obj = std::make_unique<Map>();
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<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) {
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());
} else {
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)) {
std::unique_ptr<Map> obj (*map);
value->value = (Map*)nullptr;
return obj;
if (auto map = std::get_if<Map_sptr>(&value)) {
return *map;
} else {
throw std::runtime_error("root value is not an object");
}

View File

@ -27,7 +27,7 @@ namespace json {
const int BJSON_TYPE_CDOCUMENT = 0x1F;
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_

View File

@ -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<Map*>(&value->value)) {
stringifyObj(*map, ss, indent, indentstr, nice);
if (auto map = std::get_if<Map_sptr>(&value)) {
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;
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<bool>(&value->value)) {
} else if (auto flag = std::get_if<bool>(&value)) {
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;
} else if (auto num = std::get_if<integer_t>(&value->value)) {
} else if (auto num = std::get_if<integer_t>(&value)) {
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);
}
}
@ -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<List> Parser::parseList() {
return arr;
}
std::unique_ptr<Value> 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<integer_t>(num);
return std::get<integer_t>(num);
} else {
val = std::get<number_t>(num);
return std::get<number_t>(num);
}
return std::make_unique<Value>(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<Value>(val);
return Map_sptr(parseObject().release());
}
if (next == '[') {
val = parseList().release();
return std::make_unique<Value>(val);
return List_sptr(parseList().release());
}
if (is_digit(next)) {
number_u num;
if (parseNumber(1, num)) {
val = std::get<integer_t>(num);
return std::get<integer_t>(num);
} else {
val = std::get<number_t>(num);
return std::get<number_t>(num);
}
return std::make_unique<Value>(val);
}
if (next == '"' || next == '\'') {
pos++;
val = parseString(next);
return std::make_unique<Value>(val);
return parseString(next);
}
throw error("unexpected character '"+std::string({next})+"'");
}

View File

@ -4,6 +4,7 @@
#include "commons.hpp"
#include "binary_json.hpp"
#include "../data/dynamic.hpp"
#include "../typedefs.hpp"
#include <vector>
@ -12,17 +13,11 @@
#include <stdexcept>
#include <unordered_map>
namespace dynamic {
class Map;
class List;
class Value;
}
namespace json {
class Parser : public BasicParser {
std::unique_ptr<dynamic::List> parseList();
std::unique_ptr<dynamic::Map> parseObject();
std::unique_ptr<dynamic::Value> parseValue();
dynamic::Value parseValue();
public:
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 itemsFolder = folder/ContentPack::ITEMS_FOLDER;
std::unique_ptr<dynamic::Map> 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<dynamic::Map>();
}
bool modified = false;

View File

@ -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<valtype>(val->value.index())) {
case valtype::string: return std::get<std::string>(val->value);
case valtype::boolean: return std::get<bool>(val->value) ? "true" : "false";
case valtype::number: return std::to_string(std::get<double>(val->value));
case valtype::integer: return std::to_string(std::get<int64_t>(val->value));
const auto& value = values[index];
switch (static_cast<valtype>(value.index())) {
case valtype::string: return std::get<std::string>(value);
case valtype::boolean: return std::get<bool>(value) ? "true" : "false";
case valtype::number: return std::to_string(std::get<double>(value));
case valtype::integer: return std::to_string(std::get<int64_t>(value));
default:
throw std::runtime_error("type error");
}
}
number_t List::num(size_t index) const {
const auto& val = values[index];
switch (static_cast<valtype>(val->value.index())) {
case valtype::number: return std::get<number_t>(val->value);
case valtype::integer: return std::get<integer_t>(val->value);
case valtype::string: return std::stoll(std::get<std::string>(val->value));
case valtype::boolean: return std::get<bool>(val->value);
const auto& value = values[index];
switch (static_cast<valtype>(value.index())) {
case valtype::number: return std::get<number_t>(value);
case valtype::integer: return std::get<integer_t>(value);
case valtype::string: return std::stoll(std::get<std::string>(value));
case valtype::boolean: return std::get<bool>(value);
default:
throw std::runtime_error("type error");
}
}
integer_t List::integer(size_t index) const {
const auto& val = values[index];
switch (static_cast<valtype>(val->value.index())) {
case valtype::number: return std::get<number_t>(val->value);
case valtype::integer: return std::get<integer_t>(val->value);
case valtype::string: return std::stoll(std::get<std::string>(val->value));
case valtype::boolean: return std::get<bool>(val->value);
const auto& value = values[index];
switch (static_cast<valtype>(value.index())) {
case valtype::number: return std::get<number_t>(value);
case valtype::integer: return std::get<integer_t>(value);
case valtype::string: return std::stoll(std::get<std::string>(value));
case valtype::boolean: return std::get<bool>(value);
default:
throw std::runtime_error("type error");
}
}
Map* List::map(size_t index) const {
if (auto* val = std::get_if<Map*>(&values[index]->value)) {
return *val;
if (auto* val = std::get_if<Map_sptr>(&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<List*>(&values[index]->value)) {
return *val;
if (auto* val = std::get_if<List_sptr>(&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<valtype>(val->value.index())) {
case valtype::integer: return std::get<integer_t>(val->value);
case valtype::boolean: return std::get<bool>(val->value);
const auto& value = values[index];
switch (static_cast<valtype>(value.index())) {
case valtype::integer: return std::get<integer_t>(value);
case valtype::boolean: return std::get<bool>(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> 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<List>();
put(arr);
return *arr;
}
Map& List::putMap() {
Map* map = new Map();
auto map = std::make_shared<Map>();
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<valtype>(val->value.index())) {
case valtype::string: return std::get<std::string>(val->value);
case valtype::boolean: return std::get<bool>(val->value) ? "true" : "false";
case valtype::number: return std::to_string(std::get<number_t>(val->value));
case valtype::integer: return std::to_string(std::get<integer_t>(val->value));
auto& value = found->second;
switch (static_cast<valtype>(value.index())) {
case valtype::string: return std::get<std::string>(value);
case valtype::boolean: return std::get<bool>(value) ? "true" : "false";
case valtype::number: return std::to_string(std::get<number_t>(value));
case valtype::integer: return std::to_string(std::get<integer_t>(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<valtype>(val->value.index())) {
case valtype::number: return std::get<number_t>(val->value);
case valtype::integer: return std::get<integer_t>(val->value);
case valtype::string: return std::stoull(std::get<std::string>(val->value));
case valtype::boolean: return std::get<bool>(val->value);
auto& value = found->second;
switch (static_cast<valtype>(value.index())) {
case valtype::number: return std::get<number_t>(value);
case valtype::integer: return std::get<integer_t>(value);
case valtype::string: return std::stoull(std::get<std::string>(value));
case valtype::boolean: return std::get<bool>(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<valtype>(val->value.index())) {
case valtype::number: return std::get<number_t>(val->value);
case valtype::integer: return std::get<integer_t>(val->value);
case valtype::string: return std::stoull(std::get<std::string>(val->value));
case valtype::boolean: return std::get<bool>(val->value);
auto& value = found->second;
switch (static_cast<valtype>(value.index())) {
case valtype::number: return std::get<number_t>(value);
case valtype::integer: return std::get<integer_t>(value);
case valtype::string: return std::stoull(std::get<std::string>(value));
case valtype::boolean: return std::get<bool>(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<valtype>(val->value.index())) {
case valtype::integer: return std::get<integer_t>(val->value);
case valtype::boolean: return std::get<bool>(val->value);
auto& value = found->second;
switch (static_cast<valtype>(value.index())) {
case valtype::integer: return std::get<integer_t>(value);
case valtype::boolean: return std::get<bool>(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<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));
}
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));
}
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<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));
}
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<Map*>(&found->second->value)) {
return *val;
if (auto* val = std::get_if<Map_sptr>(&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<List*>(found->second->value);
return std::get<List_sptr>(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> 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<List>();
put(key, arr);
return *arr;
}
Map& Map::putMap(std::string key) {
Map* obj = new Map();
auto obj = std::make_shared<Map>();
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<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 {
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<Map>;
using List_sptr = std::shared_ptr<List>;
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> value_of(const valvalue& value);
std::unique_ptr<Value> value_of(std::unique_ptr<Map> value);
class List {
public:
std::vector<std::unique_ptr<Value>> values;
~List();
std::vector<Value> 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<typename T>
List& put(T value) {
return put(std::make_unique<Value>(value));
List& put(std::unique_ptr<Map> value) {
return put(Map_sptr(value.release()));
}
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) const;
Value* getValueWriteable(size_t index);
List& putList();
Map& putMap();
@ -75,8 +68,7 @@ namespace dynamic {
class Map {
public:
std::unordered_map<std::string, std::unique_ptr<Value>> values;
~Map();
std::unordered_map<std::string, Value> values;
template<typename T>
T get(const std::string& key) const {
@ -101,27 +93,25 @@ namespace dynamic {
return get(key, static_cast<integer_t>(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<typename T>
Map& put(std::string key, T value) {
return put(key, std::make_unique<Value>(value));
Map& put(std::string key, std::unique_ptr<Map> value) {
return put(key, Map_sptr(value.release()));
}
Map& put(std::string key, uint64_t value) {
return put(key, value_of(static_cast<integer_t>(value)));
Map& put(std::string key, std::unique_ptr<List> value) {
return put(key, List_sptr(value.release()));
}
Map& put(std::string key, std::unique_ptr<Value> value);
Map& put(std::string key, const Value& value);
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)
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;
}
}

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());
}
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);
try {
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;
std::unique_ptr<ubyte[]> bytes (files::read_bytes(file, size));
return std::unique_ptr<dynamic::Map>(
json::from_binary(bytes.get(), size)
);
return json::from_binary(bytes.get(), size);
}
std::vector<std::string> files::read_list(fs::path filename) {

View File

@ -64,8 +64,8 @@ namespace files {
/// @brief Read JSON or BJSON file
/// @param file *.json or *.bjson file
std::unique_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_json(fs::path file);
std::shared_ptr<dynamic::Map> read_binary_json(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);
}
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);
if (found == map.end()) {
throw std::runtime_error("setting '"+name+"' does not exist");
}
auto setting = found->second;
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)) {
return dynamic::value_of((integer_t)integer->get());
return static_cast<integer_t>(integer->get());
} 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)) {
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<class T>
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);
} else if (auto num = std::get_if<number_t>(&value.value)) {
} else if (auto num = std::get_if<number_t>(&value)) {
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);
} 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");

View File

@ -22,8 +22,8 @@ class SettingsHandler {
public:
SettingsHandler(EngineSettings& settings);
std::unique_ptr<dynamic::Value> 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;

View File

@ -387,10 +387,10 @@ void Hud::add(HudElement element) {
auto document = element.getDocument();
if (document) {
auto inventory = invview ? invview->getInventory() : nullptr;
std::vector<std::unique_ptr<Value>> args;
args.push_back(value_of(inventory ? inventory.get()->getId() : 0));
std::vector<Value> args;
args.push_back(inventory ? inventory.get()->getId() : 0);
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(
element.getDocument(),

View File

@ -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<dynamic::Map*>(&langInfo->value)) {
if (auto mapptr = std::get_if<dynamic::Map_sptr>(&langInfo)) {
name = (*mapptr)->get("name", "none"s);
} else {
continue;

View File

@ -37,7 +37,7 @@ gui::page_loader_func menus::create_page_loader(Engine* engine) {
return [=](const std::string& query) {
using namespace dynamic;
std::vector<std::unique_ptr<Value>> args;
std::vector<Value> 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<Map>();
auto map = std::make_shared<Map>();
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<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 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> task, std::
auto menu = engine->getGUI()->getMenu();
menu->reset();
std::vector<std::unique_ptr<Value>> 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<Container>(doc->getRoot())->listenInterval(0.01f, [=]() {
task->update();

View File

@ -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 <string>
@ -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<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"");

View File

@ -72,7 +72,7 @@ static void show_content_missing(
std::shared_ptr<ContentLUT> lut
) {
using namespace dynamic;
auto root = std::make_unique<Map>();
auto root = std::make_shared<Map>();
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<std::unique_ptr<dynamic::Value>> args;
args.emplace_back(std::make_unique<Value>(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) {

View File

@ -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<bool>(&value.value)) {
if (auto* flag = std::get_if<bool>(&value)) {
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);
} else if (auto* num = std::get_if<number_t>(&value.value)) {
} else if (auto* num = std::get_if<number_t>(&value)) {
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());
} else if (List* const* listptr = std::get_if<List*>(&value.value)) {
} else if (auto listptr = std::get_if<List_sptr>(&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<Map*>(&value.value)) {
} else if (auto mapptr = std::get_if<Map_sptr>(&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<dynamic::Value> 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<Value>(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<List>();
auto list = std::make_shared<List>();
for (int i = 1; i <= len; i++) {
lua_rawgeti(L, idx, i);
list->put(tovalue(-1));
lua_pop(L, 1);
}
return std::make_unique<Value>(list.release());
return list;
} else {
// table
auto map = std::make_unique<Map>();
auto map = std::make_shared<Map>();
lua_pushvalue(L, idx);
lua_pushnil(L);
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, 1);
return std::make_unique<Value>(map.release());
return map;
}
}
default:

View File

@ -52,7 +52,7 @@ namespace lua {
luanumber tonumber(int idx);
glm::vec2 tovec2(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);
bool isstring(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) {
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;
}

View File

@ -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<dynamic::Map*>(&value->value)) {
if (auto mapptr = std::get_if<dynamic::Map_sptr>(&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>", 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);
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(
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";
state->emit_event(name, [=] (lua::LuaState* state) {
for (const auto& value : *argsptr) {
state->pushvalue(*value);
state->pushvalue(value);
}
return argsptr->size();
});

View File

@ -75,7 +75,7 @@ namespace scripting {
/// @brief Called on UI view show
void on_ui_open(
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);

View File

@ -198,7 +198,7 @@ std::unique_ptr<dynamic::Map> 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;
}

View File

@ -69,7 +69,7 @@ void World::write(Level* level) {
auto& players = playerFile.putList("players");
for (auto object : level->objects) {
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("generator", generator);
root->put("seed", seed);
root->put("seed", static_cast<integer_t>(seed));
auto& timeobj = root->putMap("time");
timeobj.put("day-time", daytime);