widelands-dev team mailing list archive
-
widelands-dev team
-
Mailing list archive
-
Message #15162
[Merge] lp:~widelands-dev/widelands/json_writer into lp:widelands
GunChleoc has proposed merging lp:~widelands-dev/widelands/json_writer into lp:widelands.
Commit message:
Refactor website binaries to use a real tree data structure for writing JSON
Requested reviews:
Widelands Developers (widelands-dev)
For more details, see:
https://code.launchpad.net/~widelands-dev/widelands/json_writer/+merge/357908
Getting rid of some spaghetti code. Only affects the website, not Widelands itself.
--
Your team Widelands Developers is requested to review the proposed merge of lp:~widelands-dev/widelands/json_writer into lp:widelands.
=== modified file 'src/website/CMakeLists.txt'
--- src/website/CMakeLists.txt 2018-08-14 20:42:18 +0000
+++ src/website/CMakeLists.txt 2018-10-27 16:48:10 +0000
@@ -1,3 +1,5 @@
+add_subdirectory(json)
+
wl_library(website_common
SRCS
website_common.cc
@@ -23,6 +25,7 @@
graphic_surface
io_fileread
io_filesystem
+ json
logic
map_io_map_loader
website_common
@@ -38,6 +41,7 @@
graphic
io_fileread
io_filesystem
+ json
logic
logic_tribe_basic_info
website_common
=== added directory 'src/website/json'
=== added file 'src/website/json/CMakeLists.txt'
--- src/website/json/CMakeLists.txt 1970-01-01 00:00:00 +0000
+++ src/website/json/CMakeLists.txt 2018-10-27 16:48:10 +0000
@@ -0,0 +1,10 @@
+wl_library(json
+ SRCS
+ json.cc
+ json.h
+ value.cc
+ value.h
+ DEPENDS
+ io_fileread
+ io_filesystem
+)
=== added file 'src/website/json/json.cc'
--- src/website/json/json.cc 1970-01-01 00:00:00 +0000
+++ src/website/json/json.cc 2018-10-27 16:48:10 +0000
@@ -0,0 +1,135 @@
+/*
+ * Copyright (C) 2018 by the Widelands Development Team
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "io/filewrite.h"
+#include "website/json/json.h"
+
+// ########################## JSON Element #############################
+
+namespace JSON {
+const std::string JSON::Element::tab_ = " ";
+
+JSON::Object* Element::add_object(const std::string& key) {
+ children_.push_back(std::unique_ptr<JSON::Object>(new JSON::Object(key, level_ + 1)));
+ return dynamic_cast<JSON::Object*>(children_.back().get());
+}
+
+JSON::Array* Element::add_array(const std::string& key) {
+ children_.push_back(std::unique_ptr<JSON::Array>(new JSON::Array(key, level_ + 1)));
+ return dynamic_cast<JSON::Array*>(children_.back().get());
+}
+
+void Element::add_bool(const std::string& key, bool value) {
+ values_.push_back(std::make_pair(key, std::unique_ptr<JSON::Value>(new JSON::Boolean(value))));
+}
+
+void Element::add_double(const std::string& key, double value) {
+ values_.push_back(std::make_pair(key, std::unique_ptr<JSON::Value>(new JSON::Double(value))));
+}
+void Element::add_int(const std::string& key, int value) {
+ values_.push_back(std::make_pair(key, std::unique_ptr<JSON::Value>(new JSON::Int(value))));
+}
+void Element::add_empty(const std::string& key) {
+ values_.push_back(std::make_pair(key, std::unique_ptr<JSON::Value>(new JSON::Empty())));
+}
+void Element::add_string(const std::string& key, const std::string& value) {
+ values_.push_back(std::make_pair(key, std::unique_ptr<JSON::Value>(new JSON::String(value))));
+}
+
+void Element::write_to_file(FileSystem& fs, const std::string& filename) const {
+ FileWrite file_writer;
+ file_writer.text(as_string());
+ file_writer.write(fs, filename);
+}
+
+std::string Element::as_string() const {
+ return "{\n" + children_as_string() + "}\n";
+}
+
+std::string Element::values_as_string(const std::string& tabs) const {
+ std::string result = "";
+ if (!values_.empty()) {
+ for (size_t i = 0; i < values_.size() - 1; ++i) {
+ const auto& element = values_.at(i);
+ const std::string element_as_string = element.second->as_string();
+ result +=
+ tabs + tab_ + key_to_string(element.first, element_as_string.empty()) + element_as_string + ",\n";
+ }
+ const auto& element = values_.at(values_.size() - 1);
+ const std::string element_as_string = element.second->as_string();
+ result += tabs + tab_ + key_to_string(element.first, element_as_string.empty()) + element_as_string +
+ (children_.empty() ? "\n" : ",\n");
+ }
+ return result;
+}
+
+std::string Element::children_as_string() const {
+ std::string result = "";
+ if (!children_.empty()) {
+ for (size_t i = 0; i < children_.size() - 1; ++i) {
+ result += children_.at(i)->as_string() + ",\n";
+ }
+ result += children_.at(children_.size() - 1)->as_string() + "\n";
+ }
+ return result;
+}
+
+std::string Element::key_to_string(const std::string& value, bool value_is_empty) {
+ return "\"" + value + (value_is_empty ? "\"" : "\": ");
+}
+
+// ########################## JSON Object #############################
+
+Object::Object(const std::string key, int level) : JSON::Element(key, level) {
+}
+
+std::string Object::as_string() const {
+ std::string result = "";
+ std::string tabs = "";
+ for (int i = 0; i < level_; ++i) {
+ tabs += tab_;
+ }
+
+ result += tabs + (key_.empty() ? "" : key_to_string(key_)) + "{\n";
+ result += values_as_string(tabs);
+ result += children_as_string();
+ result += tabs + "}";
+ return result;
+}
+
+// ########################## JSON Array #############################
+
+Array::Array(const std::string key, int level) : JSON::Element(key, level) {
+}
+
+std::string Array::as_string() const {
+ std::string result = "";
+ std::string tabs = "";
+ for (int i = 0; i < level_; ++i) {
+ tabs += tab_;
+ }
+
+ result += tabs + key_to_string(key_) + "[\n";
+ result += values_as_string(tabs);
+ result += children_as_string();
+ result += tabs + "]";
+ return result;
+}
+
+} // namespace JSON
=== added file 'src/website/json/json.h'
--- src/website/json/json.h 1970-01-01 00:00:00 +0000
+++ src/website/json/json.h 2018-10-27 16:48:10 +0000
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2018 by the Widelands Development Team
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef WL_WEBSITE_JSON_JSON_H
+#define WL_WEBSITE_JSON_JSON_H
+
+#include <cassert>
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "io/filesystem/filesystem.h"
+#include "website/json/value.h"
+
+namespace JSON {
+
+class Array;
+class Object;
+
+class Element {
+protected:
+ // Constructor for child node
+ explicit Element(const std::string key, int level) : key_(key), level_(level) {
+ }
+
+public:
+ // Constructor for root node
+ explicit Element() : JSON::Element("", 0) {
+ }
+
+ JSON::Object* add_object(const std::string& key = "");
+ JSON::Array* add_array(const std::string& key);
+ void add_bool(const std::string& key, bool value);
+ void add_double(const std::string& key, double value);
+ void add_int(const std::string& key, int value);
+ void add_empty(const std::string& key);
+ void add_string(const std::string& key, const std::string& value);
+
+ void write_to_file(FileSystem& fs, const std::string& filename) const;
+
+ virtual std::string as_string() const;
+
+protected:
+ static const std::string tab_;
+
+ std::string values_as_string(const std::string& tabs) const;
+ std::string children_as_string() const;
+ static std::string key_to_string(const std::string& value, bool value_is_empty = false);
+
+ std::string key_;
+ const int level_;
+ std::vector<std::unique_ptr<JSON::Element>> children_;
+ std::vector<std::pair<std::string, std::unique_ptr<JSON::Value>>> values_;
+};
+
+class Object : public Element {
+ friend class JSON::Element;
+
+protected:
+ // Constructor for child node
+ explicit Object(const std::string key, int level);
+
+public:
+ // Constructor for root node
+ explicit Object() : JSON::Element("", 0) {
+ }
+ std::string as_string() const override;
+};
+
+class Array : public Element {
+ friend class JSON::Element;
+protected:
+ // Constructor for child node
+ explicit Array(const std::string key, int level);
+
+public:
+ std::string as_string() const override;
+};
+} // namespace JSON
+#endif // end of include guard: WL_WEBSITE_JSON_JSON_H
=== added file 'src/website/json/value.cc'
--- src/website/json/value.cc 1970-01-01 00:00:00 +0000
+++ src/website/json/value.cc 2018-10-27 16:48:10 +0000
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2018 by the Widelands Development Team
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "website/json/value.h"
+
+#include <sstream>
+
+namespace JSON {
+
+Boolean::Boolean(bool value) : bool_value(value) {
+}
+std::string Boolean::as_string() const {
+ return bool_value ? "true" : "false";
+}
+
+Double::Double(double value) : double_value(value) {
+}
+std::string Double::as_string() const {
+ std::ostringstream strs;
+ strs << double_value;
+ return strs.str();
+}
+
+Int::Int(int value) : int_value(value) {}
+std::string Int::as_string() const {
+ std::ostringstream strs;
+ strs << int_value;
+ return strs.str();
+}
+
+std::string Empty::as_string() const {
+ return "";
+}
+
+String::String(std::string value) : string_value(value) {}
+std::string String::as_string() const {
+ return "\"" + string_value + "\"";
+}
+
+} // namespace JSON
=== added file 'src/website/json/value.h'
--- src/website/json/value.h 1970-01-01 00:00:00 +0000
+++ src/website/json/value.h 2018-10-27 16:48:10 +0000
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2018 by the Widelands Development Team
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef WL_WEBSITE_JSON_VALUE_H
+#define WL_WEBSITE_JSON_VALUE_H
+
+#include <string>
+
+namespace JSON {
+
+/// Value types for JSON
+struct Value {
+ Value() = default;
+ virtual std::string as_string() const = 0;
+};
+
+struct Boolean : Value {
+ explicit Boolean(bool value);
+ std::string as_string() const override;
+private:
+ const bool bool_value;
+};
+
+struct Double : Value {
+ explicit Double(double value);
+ std::string as_string() const override;
+private:
+ const double double_value;
+};
+
+struct Empty : Value {
+ Empty() = default;
+ std::string as_string() const override;
+};
+
+struct Int : Value {
+ explicit Int(int value);
+ std::string as_string() const override;
+private:
+ const int int_value;
+};
+
+struct String : Value {
+ explicit String(std::string value);
+ std::string as_string() const override;
+private:
+ const std::string string_value;
+};
+
+} // namespace JSON
+#endif // end of include guard: WL_WEBSITE_JSON_VALUE_H
=== modified file 'src/website/map_info.cc'
--- src/website/map_info.cc 2018-08-14 20:42:18 +0000
+++ src/website/map_info.cc 2018-10-27 16:48:10 +0000
@@ -36,6 +36,7 @@
#include "logic/editor_game_base.h"
#include "logic/map.h"
#include "map_io/widelands_map_loader.h"
+#include "website/json/json.h"
#include "website/website_common.h"
using namespace Widelands;
@@ -83,48 +84,20 @@
// Write JSON.
{
- FileWrite fw;
-
- const auto write_string = [&fw](const std::string& s) { fw.data(s.c_str(), s.size()); };
- const auto write_key_value = [&write_string](
- const std::string& key, const std::string& quoted_value) {
- write_string((boost::format("\"%s\": %s") % key % quoted_value).str());
- };
- const auto write_key_value_string = [&write_key_value](
- const std::string& key, const std::string& value) {
- std::string quoted_value = value;
- boost::replace_all(quoted_value, "\"", "\\\"");
- write_key_value(key, "\"" + value + "\"");
- };
- const auto write_key_value_int = [&write_key_value](
- const std::string& key, const int value) {
- write_key_value(key, boost::lexical_cast<std::string>(value));
- };
- write_string("{\n ");
- write_key_value_string("name", map->get_name());
- write_string(",\n ");
- write_key_value_string("author", map->get_author());
- write_string(",\n ");
- write_key_value_string("description", map->get_description());
- write_string(",\n ");
- write_key_value_string("hint", map->get_hint());
- write_string(",\n ");
- write_key_value_int("width", map->get_width());
- write_string(",\n ");
- write_key_value_int("height", map->get_height());
- write_string(",\n ");
- write_key_value_int("nr_players", map->get_nrplayers());
- write_string(",\n ");
+ std::unique_ptr<JSON::Object> json(new JSON::Object());
+ json->add_string("name", map->get_name());
+ json->add_string("author", map->get_author());
+ json->add_string("description", map->get_description());
+ json->add_string("hint", map->get_hint());
+ json->add_int("width", map->get_width());
+ json->add_int("height", map->get_height());
+ json->add_int("nr_players", map->get_nrplayers());
const std::string world_name =
static_cast<Widelands::WidelandsMapLoader*>(ml.get())->old_world_name();
- write_key_value_string("world_name", world_name);
- write_string(",\n ");
- write_key_value_string("minimap", map_path + ".png");
- write_string("\n");
-
- write_string("}\n");
- fw.write(*in_out_filesystem, (map_file + ".json").c_str());
+ json->add_string("world_name", world_name);
+ json->add_string("minimap", map_path + ".png");
+ json->write_to_file(*in_out_filesystem, (map_file + ".json").c_str());
}
egbase.cleanup_objects();
} catch (std::exception& e) {
=== modified file 'src/website/map_object_info.cc'
--- src/website/map_object_info.cc 2018-08-14 20:42:18 +0000
+++ src/website/map_object_info.cc 2018-10-27 16:48:10 +0000
@@ -35,6 +35,7 @@
#include "logic/map_objects/tribes/tribe_basic_info.h"
#include "logic/map_objects/tribes/tribes.h"
#include "logic/map_objects/world/world.h"
+#include "website/json/json.h"
#include "website/website_common.h"
using namespace Widelands;
@@ -43,95 +44,12 @@
/*
==========================================================
- SPECIALIZED FILEWRITE
- ==========================================================
- */
-
-// Defines some convenience writing functions for the JSON format
-class JSONFileWrite : public FileWrite {
-public:
- JSONFileWrite() : FileWrite(), level_(0) {
- }
-
- void write_string(const std::string& s, bool use_indent = false) {
- std::string writeme = s;
- if (use_indent) {
- for (int i = 0; i < level_; ++i) {
- writeme = (boost::format(" %s") % writeme).str();
- }
- }
- data(writeme.c_str(), writeme.size());
- }
- void write_key(const std::string& key) {
- write_string((boost::format("\"%s\":\n") % key).str(), true);
- }
- void write_value_string(const std::string& quoted_value) {
- write_string((boost::format("\"%s\"") % quoted_value).str(), true);
- }
- void write_key_value(const std::string& key, const std::string& quoted_value) {
- write_string((boost::format("\"%s\": %s") % key % quoted_value).str(), true);
- }
- void write_key_value_string(const std::string& key, const std::string& value) {
- std::string quoted_value = value;
- boost::replace_all(quoted_value, "\"", "\\\"");
- write_key_value(key, "\"" + value + "\"");
- }
- void write_key_value_int(const std::string& key, const int value) {
- write_key_value(key, boost::lexical_cast<std::string>(value));
- }
- void open_brace() {
- write_string("{\n", true);
- ++level_;
- }
- // JSON hates a final comma. This defaults to having NO comma.
- void close_brace(bool precede_newline = false, int current = 0, int total = 0) {
- --level_;
- if (precede_newline) {
- write_string("\n");
- }
- if (current < total - 1) {
- write_string("},\n", true);
- } else {
- write_string("}", true);
- }
- }
- void open_array(const std::string& name) {
- write_string((boost::format("\"%s\":[\n") % name).str(), true);
- ++level_;
- }
- // JSON hates a final comma. This defaults to having NO comma.
- void close_array(int current = 0, int total = 0) {
- --level_;
- write_string("\n");
- if (current < total - 1) {
- write_string("],\n", true);
- } else {
- write_string("]\n", true);
- }
- }
- // JSON hates a final comma. This defaults to having a comma.
- void close_element(int current = -2, int total = 0) {
- if (current < total - 1) {
- write_string(",\n");
- }
- }
-
-private:
- int level_;
-};
-
-/*
- ==========================================================
BUILDINGS
==========================================================
*/
void write_buildings(const TribeDescr& tribe, EditorGameBase& egbase, FileSystem* out_filesystem) {
-
log("\n==================\nWriting buildings:\n==================\n");
- JSONFileWrite fw;
- fw.open_brace(); // Main
- fw.open_array("buildings"); // Buildings
// We don't want any partially finished buildings
std::vector<const BuildingDescr*> buildings;
@@ -143,144 +61,92 @@
}
}
- // Now write
+ std::unique_ptr<JSON::Element> json(new JSON::Element());
+ JSON::Array* json_buildings_array = json->add_array("buildings");
for (size_t i = 0; i < buildings.size(); ++i) {
const BuildingDescr& building = *buildings[i];
log(" %s", building.name().c_str());
- fw.open_brace(); // Building
-
- fw.write_key_value_string("name", building.name());
- fw.close_element();
- fw.write_key_value_string("descname", building.descname());
- fw.close_element();
- fw.write_key_value_string("icon", building.representative_image_filename());
- fw.close_element();
-
- // Conditional stuff in between, so we won't run into trouble with the commas.
+
+ JSON::Object* json_building = json_buildings_array->add_object();
+ json_building->add_string("name", building.name());
+ json_building->add_string("descname", building.descname());
+ json_building->add_string("icon", building.representative_image_filename());
// Buildcost
if (building.is_buildable()) {
- fw.open_array("buildcost"); // Buildcost
- size_t buildcost_counter = 0;
+ JSON::Array* json_builcost_array = json_building->add_array("buildcost");
for (WareAmount buildcost : building.buildcost()) {
const WareDescr& ware = *tribe.get_ware_descr(buildcost.first);
- fw.open_brace(); // Buildcost
- fw.write_key_value_string("name", ware.name());
- fw.close_element();
- fw.write_key_value_int("amount", buildcost.second);
- fw.close_brace(true, buildcost_counter, building.buildcost().size()); // Buildcost
- ++buildcost_counter;
+ JSON::Object* json_builcost = json_builcost_array->add_object();
+ json_builcost->add_string("name", ware.name());
+ json_builcost->add_int("amount", buildcost.second);
}
- fw.close_array(1, 5); // Buildcost - we need a comma
}
if (building.is_enhanced()) {
- fw.write_key_value_string(
+ json_building->add_string(
"enhanced", tribe.get_building_descr(building.enhanced_from())->name());
- fw.close_element();
}
if (building.enhancement() != INVALID_INDEX) {
- fw.write_key_value_string(
+ json_building->add_string(
"enhancement", tribe.get_building_descr(building.enhancement())->name());
- fw.close_element();
}
if (upcast(ProductionSiteDescr const, productionsite, &building)) {
- // Produces
+ // Produces wares
if (productionsite->output_ware_types().size() > 0) {
- fw.open_array("produced_wares"); // Produces
- size_t produces_counter = 0;
+ JSON::Array* json_wares_array = json_building->add_array("produced_wares");
for (DescriptionIndex ware_index : productionsite->output_ware_types()) {
- fw.write_value_string(tribe.get_ware_descr(ware_index)->name());
- fw.close_element(produces_counter, productionsite->output_ware_types().size());
- ++produces_counter;
+ json_wares_array->add_empty(tribe.get_ware_descr(ware_index)->name());
}
- fw.close_array(1, 5); // Produces - we need a comma
}
+ // Produces workers
if (productionsite->output_worker_types().size() > 0) {
- fw.open_array("produced_workers"); // Produces
- size_t produces_counter = 0;
+ JSON::Array* json_workers_array = json_building->add_array("produced_workers");
for (DescriptionIndex worker_index : productionsite->output_worker_types()) {
- fw.write_value_string(tribe.get_worker_descr(worker_index)->name());
- fw.close_element(produces_counter, productionsite->output_worker_types().size());
- ++produces_counter;
+ json_workers_array->add_empty(tribe.get_worker_descr(worker_index)->name());
}
- fw.close_array(1, 5); // Produces - we need a comma
}
// Consumes
if (productionsite->input_wares().size() > 0) {
- fw.open_array("stored_wares"); // Consumes
- size_t consumes_counter = 0;
+ JSON::Array* json_wares_array = json_building->add_array("stored_wares");
for (WareAmount input : productionsite->input_wares()) {
const WareDescr& ware = *tribe.get_ware_descr(input.first);
- fw.open_brace(); // Input
- fw.write_key_value_string("name", ware.name());
- fw.close_element();
- fw.write_key_value_int("amount", input.second);
- fw.close_brace(
- true, consumes_counter, productionsite->input_wares().size()); // Input
- ++consumes_counter;
+ JSON::Object* json_input = json_wares_array->add_object();
+ json_input->add_string("name", ware.name());
+ json_input->add_int("amount", input.second);
}
- fw.close_array(1, 5); // Consumes - we need a comma
}
- fw.open_array("workers"); // Workers
- size_t worker_counter = 0;
+ // Workers
+ JSON::Array* json_workers_array = json_building->add_array("workers");
for (WareAmount input : productionsite->working_positions()) {
const WorkerDescr& worker = *tribe.get_worker_descr(input.first);
- fw.open_brace(); // Worker
- fw.write_key_value_string("name", worker.name());
- fw.close_element();
- fw.write_key_value_int("amount", input.second);
- fw.close_brace(
- true, worker_counter, productionsite->working_positions().size()); // Worker
- ++worker_counter;
+ JSON::Object* json_input = json_workers_array->add_object();
+ json_input->add_string("name", worker.name());
+ json_input->add_int("amount", input.second);
}
- fw.close_array(1, 5); // Workers - we need a comma
} else if (upcast(MilitarySiteDescr const, militarysite, &building)) {
- fw.write_key_value_int("conquers", militarysite->get_conquers());
- fw.close_element();
- fw.write_key_value_int("max_soldiers", militarysite->get_max_number_of_soldiers());
- fw.close_element();
- fw.write_key_value_int("heal_per_second", militarysite->get_heal_per_second());
- fw.close_element();
+ json_building->add_int("conquers", militarysite->get_conquers());
+ json_building->add_int("max_soldiers", militarysite->get_max_number_of_soldiers());
+ json_building->add_int("heal_per_second", militarysite->get_heal_per_second());
}
- switch (building.type()) {
- case MapObjectType::PRODUCTIONSITE:
- fw.write_key_value_string("type", "productionsite");
- break;
- case MapObjectType::WAREHOUSE:
- fw.write_key_value_string("type", "warehouse");
- break;
- case MapObjectType::MARKET:
- fw.write_key_value_string("type", "market");
- break;
- case MapObjectType::MILITARYSITE:
- fw.write_key_value_string("type", "militarysite");
- break;
- case MapObjectType::TRAININGSITE:
- fw.write_key_value_string("type", "trainingsite");
- break;
- default:
- NEVER_HERE();
- }
- fw.close_element();
+ json_building->add_string("type", to_string(building.type()));
// Size
if (building.type() == MapObjectType::WAREHOUSE && !building.is_buildable() &&
!building.is_enhanced()) {
- fw.write_key_value_string("size", "headquarters");
+ json_building->add_string("size", "headquarters");
} else if (building.get_ismine()) {
- fw.write_key_value_string("size", "mine");
+ json_building->add_string("size", "mine");
} else if (building.get_isport()) {
- fw.write_key_value_string("size", "port");
+ json_building->add_string("size", "port");
} else {
- fw.write_key_value_string("size", BaseImmovable::size_to_string(building.get_size()));
+ json_building->add_string("size", BaseImmovable::size_to_string(building.get_size()));
}
- fw.close_element();
// Helptext
try {
@@ -290,16 +156,13 @@
cr->push_arg(building.helptext_script());
cr->resume();
const std::string help_text = cr->pop_string();
- fw.write_key_value_string("helptext", help_text);
+ json_building->add_string("helptext", help_text);
} catch (LuaError& err) {
- fw.write_key_value_string("helptext", err.what());
+ json_building->add_string("helptext", err.what());
}
-
- fw.close_brace(true, i, buildings.size()); // Building
}
- fw.close_array(); // Buildings
- fw.close_brace(); // Main
- fw.write(*out_filesystem, (boost::format("%s_buildings.json") % tribe.name()).str().c_str());
+
+ json->write_to_file(*out_filesystem, (boost::format("%s_buildings.json") % tribe.name()).str().c_str());
log("\n");
}
@@ -311,22 +174,16 @@
void write_wares(const TribeDescr& tribe, EditorGameBase& egbase, FileSystem* out_filesystem) {
log("\n===============\nWriting wares:\n===============\n");
- JSONFileWrite fw;
- fw.open_brace(); // Main
- fw.open_array("wares"); // Wares
- size_t counter = 0;
- const size_t no_of_wares = tribe.wares().size();
+ std::unique_ptr<JSON::Element> json(new JSON::Element());
+ JSON::Array* json_wares_array = json->add_array("wares");
for (DescriptionIndex ware_index : tribe.wares()) {
const WareDescr& ware = *tribe.get_ware_descr(ware_index);
log(" %s", ware.name().c_str());
- fw.open_brace();
- fw.write_key_value_string("name", ware.name());
- fw.close_element();
- fw.write_key_value_string("descname", ware.descname());
- fw.close_element();
- fw.write_key_value_string("icon", ware.icon_filename());
- fw.close_element();
+ JSON::Object* json_ware = json_wares_array->add_object();
+ json_ware->add_string("name", ware.name());
+ json_ware->add_string("descname", ware.descname());
+ json_ware->add_string("icon", ware.icon_filename());
// Helptext
try {
@@ -337,17 +194,13 @@
cr->push_arg(ware.helptext_script());
cr->resume();
const std::string help_text = cr->pop_string();
- fw.write_key_value_string("helptext", help_text);
+ json_ware->add_string("helptext", help_text);
} catch (LuaError& err) {
- fw.write_key_value_string("helptext", err.what());
+ json_ware->add_string("helptext", err.what());
}
- fw.close_brace(true, counter, no_of_wares); // Ware
- ++counter;
}
- fw.close_array(); // Wares
- fw.close_brace(); // Main
- fw.write(*out_filesystem, (boost::format("%s_wares.json") % tribe.name()).str().c_str());
+ json->write_to_file(*out_filesystem, (boost::format("%s_wares.json") % tribe.name()).str().c_str());
log("\n");
}
@@ -359,22 +212,16 @@
void write_workers(const TribeDescr& tribe, EditorGameBase& egbase, FileSystem* out_filesystem) {
log("\n================\nWriting workers:\n================\n");
- JSONFileWrite fw;
- fw.open_brace(); // Main
- fw.open_array("workers"); // Workers
- size_t counter = 0;
- const size_t no_of_workers = tribe.workers().size();
+ std::unique_ptr<JSON::Element> json(new JSON::Element());
+ JSON::Array* json_workers_array = json->add_array("workers");
for (DescriptionIndex worker_index : tribe.workers()) {
const WorkerDescr& worker = *tribe.get_worker_descr(worker_index);
log(" %s", worker.name().c_str());
- fw.open_brace();
- fw.write_key_value_string("name", worker.name());
- fw.close_element();
- fw.write_key_value_string("descname", worker.descname());
- fw.close_element();
- fw.write_key_value_string("icon", worker.icon_filename());
- fw.close_element();
+ JSON::Object* json_worker = json_workers_array->add_object();
+ json_worker->add_string("name", worker.name());
+ json_worker->add_string("descname", worker.descname());
+ json_worker->add_string("icon", worker.icon_filename());
// Helptext
try {
@@ -384,28 +231,20 @@
cr->push_arg(worker.helptext_script());
cr->resume();
const std::string help_text = cr->pop_string();
- fw.write_key_value_string("helptext", help_text);
+ json_worker->add_string("helptext", help_text);
} catch (LuaError& err) {
- fw.write_key_value_string("helptext", err.what());
+ json_worker->add_string("helptext", err.what());
}
if (worker.becomes() != INVALID_INDEX) {
- fw.close_element();
const WorkerDescr& becomes = *tribe.get_worker_descr(worker.becomes());
- fw.write_key("becomes");
- fw.open_brace();
- fw.write_key_value_string("name", becomes.name());
- fw.close_element();
- fw.write_key_value_int("experience", worker.get_needed_experience());
- fw.close_brace(true);
+ JSON::Object* json_becomes = json_worker->add_object("becomes");
+ json_becomes->add_string("name", becomes.name());
+ json_becomes->add_int("experience", worker.get_needed_experience());
}
- fw.close_brace(true, counter, no_of_workers); // Worker
- ++counter;
}
- fw.close_array(); // Workers
- fw.close_brace(); // Main
- fw.write(*out_filesystem, (boost::format("%s_workers.json") % tribe.name()).str().c_str());
+ json->write_to_file(*out_filesystem, (boost::format("%s_workers.json") % tribe.name()).str().c_str());
log("\n");
}
@@ -415,22 +254,17 @@
==========================================================
*/
-void add_tribe_info(const Widelands::TribeBasicInfo& tribe_info, JSONFileWrite* fw) {
- fw->write_key_value_string("name", tribe_info.name);
- fw->close_element();
- fw->write_key_value_string("descname", tribe_info.descname);
- fw->close_element();
- fw->write_key_value_string("author", tribe_info.author);
- fw->close_element();
- fw->write_key_value_string("tooltip", tribe_info.tooltip);
- fw->close_element();
- fw->write_key_value_string("icon", tribe_info.icon);
+void add_tribe_info(const Widelands::TribeBasicInfo& tribe_info, JSON::Element* json_tribe) {
+ json_tribe->add_string("name", tribe_info.name);
+ json_tribe->add_string("descname", tribe_info.descname);
+ json_tribe->add_string("author", tribe_info.author);
+ json_tribe->add_string("tooltip", tribe_info.tooltip);
+ json_tribe->add_string("icon", tribe_info.icon);
}
void write_tribes(EditorGameBase& egbase, FileSystem* out_filesystem) {
- JSONFileWrite fw;
- fw.open_brace(); // Main
- fw.open_array("tribes"); // Tribes
+ std::unique_ptr<JSON::Element> json(new JSON::Element());
+ JSON::Array* json_tribes_array = json->add_array("tribes");
/// Tribes
egbase.mutable_tribes()->postload(); // Make sure that all values have been set.
@@ -442,28 +276,22 @@
log("\n\n=========================\nWriting tribe: %s\n=========================\n",
tribe_info.name.c_str());
- fw.open_brace(); // TribeDescr
- add_tribe_info(tribe_info, &fw);
- fw.close_brace(true, tribe_index, tribeinfos.size()); // TribeDescr
+ // Main file
+ JSON::Object* json_tribe = json_tribes_array->add_object();
+ add_tribe_info(tribe_info, json_tribe);
// These go in separate files
-
- JSONFileWrite fw_tribe;
- fw_tribe.open_brace(); // TribeDescr
- add_tribe_info(tribe_info, &fw_tribe);
- fw_tribe.close_brace(true); // TribeDescr
- fw_tribe.write(
- *out_filesystem, (boost::format("tribe_%s.json") % tribe_info.name).str().c_str());
+ std::unique_ptr<JSON::Object> json_tribe_for_file(new JSON::Object());
+ add_tribe_info(tribe_info, json_tribe_for_file.get());
+ json_tribe_for_file->write_to_file(*out_filesystem, (boost::format("tribe_%s.json") % tribe_info.name).str().c_str());
const TribeDescr& tribe = *tribes.get_tribe_descr(tribes.tribe_index(tribe_info.name));
-
write_buildings(tribe, egbase, out_filesystem);
write_wares(tribe, egbase, out_filesystem);
write_workers(tribe, egbase, out_filesystem);
}
- fw.close_array(); // Tribes
- fw.close_brace(); // Main
- fw.write(*out_filesystem, "tribes.json");
+
+ json->write_to_file(*out_filesystem, "tribes.json");
}
} // namespace
Follow ups
-
[Merge] lp:~widelands-dev/widelands/json_writer into lp:widelands
From: noreply, 2019-02-09
-
Re: [Merge] lp:~widelands-dev/widelands/json_writer into lp:widelands
From: GunChleoc, 2019-02-09
-
Re: [Merge] lp:~widelands-dev/widelands/json_writer into lp:widelands
From: kaputtnik, 2019-02-09
-
Re: [Merge] lp:~widelands-dev/widelands/json_writer into lp:widelands
From: Klaus Halfmann, 2019-02-09
-
Re: [Merge] lp:~widelands-dev/widelands/json_writer into lp:widelands
From: GunChleoc, 2019-02-09
-
Re: [Merge] lp:~widelands-dev/widelands/json_writer into lp:widelands
From: Klaus Halfmann, 2019-01-13
-
[Merge] lp:~widelands-dev/widelands/json_writer into lp:widelands
From: bunnybot, 2019-01-13
-
[Merge] lp:~widelands-dev/widelands/json_writer into lp:widelands
From: bunnybot, 2019-01-12
-
Re: [Merge] lp:~widelands-dev/widelands/json_writer into lp:widelands
From: kaputtnik, 2018-10-31
-
[Merge] lp:~widelands-dev/widelands/json_writer into lp:widelands
From: bunnybot, 2018-10-30
-
[Merge] lp:~widelands-dev/widelands/json_writer into lp:widelands
From: bunnybot, 2018-10-27