dynamic::Value simplified
This commit is contained in:
parent
8e83a07094
commit
a4c21984d5
@ -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:
|
||||||
|
|||||||
@ -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");
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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_
|
||||||
|
|||||||
@ -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})+"'");
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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);
|
||||||
|
|
||||||
|
|||||||
@ -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;
|
||||||
|
|||||||
@ -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());
|
|
||||||
}
|
|
||||||
|
|||||||
@ -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);
|
||||||
|
|
||||||
|
|||||||
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -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) {
|
||||||
|
|||||||
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -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");
|
||||||
|
|||||||
@ -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;
|
||||||
|
|||||||
@ -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(),
|
||||||
|
|||||||
@ -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;
|
||||||
|
|||||||
@ -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();
|
||||||
|
|
||||||
|
|||||||
@ -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"");
|
||||||
|
|||||||
@ -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) {
|
||||||
|
|||||||
@ -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:
|
||||||
|
|||||||
@ -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);
|
||||||
|
|||||||
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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();
|
||||||
});
|
});
|
||||||
|
|||||||
@ -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);
|
||||||
|
|||||||
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -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);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user