Added serialization for structures

This commit is contained in:
2024-07-26 19:19:39 +03:00
parent 127192ddbe
commit b486453b59
2 changed files with 66 additions and 16 deletions

View File

@@ -1,4 +1,3 @@
#include <core/io/config_file.h>
#include <core/io/json.h> #include <core/io/json.h>
#include <core/os/file_access.h> #include <core/os/file_access.h>
#include <core/set.h> #include <core/set.h>
@@ -30,7 +29,8 @@ void StreamWorld::read_buildings_json(const String &buildings_path)
while (e) { while (e) {
struct building b; struct building b;
String key = e->get(); String key = e->get();
String id = json[key].get("id"); Dictionary entry = json[key];
String id = entry.get("id", "empty");
if (id == "empty") { if (id == "empty") {
e = e->next(); e = e->next();
continue; continue;
@@ -66,15 +66,23 @@ void StreamWorld::save_buildings_json(const String &buildings_path)
{ {
int i; int i;
String buildings_json = FileAccess::get_file_as_string(buildings_path); String buildings_json = FileAccess::get_file_as_string(buildings_path);
Variant json_v; String backup_path = buildings_path + ".bak";
String es; String store_path = buildings_path + ".new";
int eline; FileAccess *fa = FileAccess::open(backup_path, FileAccess::WRITE);
Error status = JSON::parse(buildings_json, json_v, es, eline); fa->store_string(buildings_json);
ERR_FAIL_COND_MSG(status != OK, "Can't parse json: " + es + fa->close();
" at line: " + itos(eline)); Dictionary json;
for (i = 0; i < (int)buildings.size(); i++) {
Dictionary json = json_v; String key;
for (i = 0; i < (int)buildings.size(); i++) VariantWriter::write_to_string(buildings[i].xform, key);
Dictionary dict = buildings[i].to_dict();
dict["index"] = i;
json[key] = dict;
}
String json_string = JSON::print(json, "\t", false);
fa = FileAccess::open(store_path, FileAccess::WRITE);
fa->store_string(json_string);
fa->close();
print_line("entries count: " + itos(buildings.size())); print_line("entries count: " + itos(buildings.size()));
} }
@@ -102,7 +110,7 @@ void StreamWorld::building::from_dict(building *b, const Dictionary &dict,
Array doors = from_string<Array>(doors_s); Array doors = from_string<Array>(doors_s);
b->doors.resize(doors.size()); b->doors.resize(doors.size());
for (i = 0; i < (int)doors.size(); i++) for (i = 0; i < (int)doors.size(); i++)
b->doors.write[i] = doors[i]; b->doors.write[i] = from_string<Transform>(doors[i]);
String aabb_s = dict.get("aabb", AABB()); String aabb_s = dict.get("aabb", AABB());
b->aabb = from_string<AABB>(aabb_s); b->aabb = from_string<AABB>(aabb_s);
Array worktime = dict.get("worktime", Array()); Array worktime = dict.get("worktime", Array());
@@ -115,9 +123,48 @@ void StreamWorld::building::from_dict(building *b, const Dictionary &dict,
b->worktime[1] = worktime[1]; b->worktime[1] = worktime[1];
} }
template <class T> static inline void v2a(Array &ret, const Vector<T> &data)
{
int i;
ret.resize(data.size());
for (i = 0; i < (int)data.size(); i++)
ret[i] = data[i];
}
Dictionary StreamWorld::building::to_dict() const Dictionary StreamWorld::building::to_dict() const
{ {
return Dictionary(); int i;
Dictionary ret;
ret["id"] = id;
ret["pattern_id"] = pattern_id;
Array r, w, g;
v2a(r, residents);
ret["residents"] = r;
v2a(w, workers);
ret["workers"] = w;
v2a(g, guests);
ret["guests"] = g;
Array d;
v2a(d, doors);
String doors_s;
Array d2;
d2.resize(d.size());
for (i = 0; i < (int)d.size(); i++) {
String tmp;
VariantWriter::write_to_string(d[i], tmp);
d2[i] = tmp;
}
VariantWriter::write_to_string(d2, doors_s);
ret["doors"] = doors_s;
String aabb_s;
VariantWriter::write_to_string(aabb, aabb_s);
ret["aabb"] = aabb_s;
Array wt;
wt.resize(2);
wt[0] = worktime[0];
wt[1] = worktime[1];
ret["worktime"] = wt;
return ret;
} }
void StreamWorld::create_tilemap() void StreamWorld::create_tilemap()
@@ -404,7 +451,9 @@ void StreamWorld::run_command(const String &command, const Array &args)
} else if (command == "buildings_undo") { } else if (command == "buildings_undo") {
/* TODO */ /* TODO */
} else if (command == "buildings_save") { } else if (command == "buildings_save") {
/* TODO */ String buildings_path =
config.get_value("buildings", "buildings_path");
save_buildings_json(buildings_path);
} else } else
print_error("No command " + command); print_error("No command " + command);
} }
@@ -486,7 +535,6 @@ StreamWorld::StreamWorld()
, view_distance(0) , view_distance(0)
, initialized(false) , initialized(false)
{ {
ConfigFile config;
Error result = config.load("res://config/stream.conf"); Error result = config.load("res://config/stream.conf");
ERR_FAIL_COND_MSG(result != OK, "Failed to load config"); ERR_FAIL_COND_MSG(result != OK, "Failed to load config");
Dictionary buildings_data = Dictionary buildings_data =

View File

@@ -5,6 +5,7 @@
#include <tuple> #include <tuple>
#include <algorithm> #include <algorithm>
#include <scene/3d/spatial.h> #include <scene/3d/spatial.h>
#include <core/io/config_file.h>
class VoxelViewer; class VoxelViewer;
class VoxelLodTerrain; class VoxelLodTerrain;
class StreamWorld : public Spatial { class StreamWorld : public Spatial {
@@ -13,6 +14,7 @@ private:
VoxelViewer *viewer; VoxelViewer *viewer;
VoxelLodTerrain *terrain; VoxelLodTerrain *terrain;
Node *current_scene; Node *current_scene;
ConfigFile config;
struct building { struct building {
String id; String id;
int pattern_id; int pattern_id;