ship layout blueprints

This commit is contained in:
2026-05-19 21:01:10 +02:00
parent d08bf5d37b
commit d397b9969a
14 changed files with 511 additions and 7 deletions

View File

@@ -0,0 +1,129 @@
#include "ShipLayoutBlueprintSerializer.h"
#include <sstream>
#include <stdexcept>
#include "toml.hpp"
#include "Rotation.h"
namespace
{
std::string rotationToString(Rotation r)
{
switch (r)
{
case Rotation::North: return "north";
case Rotation::East: return "east";
case Rotation::South: return "south";
case Rotation::West: return "west";
}
return "north";
}
Rotation parseRotation(const std::string& s)
{
if (s == "east") { return Rotation::East; }
if (s == "south") { return Rotation::South; }
if (s == "west") { return Rotation::West; }
return Rotation::North;
}
} // namespace
namespace ShipLayoutBlueprintSerializer
{
std::string serialize(const std::vector<ShipLayoutBlueprint>& blueprints)
{
toml::array bpArr;
for (const ShipLayoutBlueprint& bp : blueprints)
{
toml::array modArr;
for (const PlacedModule& pm : bp.modules)
{
toml::table modTbl;
modTbl.insert("type", pm.moduleId);
modTbl.insert("x", static_cast<int64_t>(pm.position.x()));
modTbl.insert("y", static_cast<int64_t>(pm.position.y()));
modTbl.insert("rotation", rotationToString(pm.rotation));
modArr.push_back(std::move(modTbl));
}
toml::table bpTbl;
bpTbl.insert("name", bp.name.toStdString());
bpTbl.insert("ship_type", bp.shipType);
bpTbl.insert("modules", std::move(modArr));
bpArr.push_back(std::move(bpTbl));
}
toml::table root;
root.insert("blueprint", std::move(bpArr));
std::ostringstream oss;
oss << root;
return oss.str();
}
std::vector<ShipLayoutBlueprint> deserialize(const std::string& tomlContent)
{
toml::table root;
try
{
root = toml::parse(tomlContent);
}
catch (const toml::parse_error& e)
{
std::ostringstream msg;
msg << "TOML parse error: " << e.description() << " at " << e.source().begin;
throw std::runtime_error(msg.str());
}
std::vector<ShipLayoutBlueprint> result;
const toml::array* bpArr = root["blueprint"].as_array();
if (!bpArr) { return result; }
for (std::size_t i = 0; i < bpArr->size(); ++i)
{
const toml::table* bpTbl = (*bpArr)[i].as_table();
if (!bpTbl) { continue; }
const std::optional<std::string> name = (*bpTbl)["name"].value<std::string>();
const std::optional<std::string> shipType = (*bpTbl)["ship_type"].value<std::string>();
if (!name || name->empty() || !shipType || shipType->empty()) { continue; }
ShipLayoutBlueprint bp;
bp.name = QString::fromStdString(*name);
bp.shipType = *shipType;
const toml::array* modArr = (*bpTbl)["modules"].as_array();
if (modArr)
{
for (std::size_t j = 0; j < modArr->size(); ++j)
{
const toml::table* modTbl = (*modArr)[j].as_table();
if (!modTbl) { continue; }
const std::optional<std::string> type = (*modTbl)["type"].value<std::string>();
const std::optional<int64_t> x = (*modTbl)["x"].value<int64_t>();
const std::optional<int64_t> y = (*modTbl)["y"].value<int64_t>();
const std::optional<std::string> rotStr = (*modTbl)["rotation"].value<std::string>();
if (!type || !x || !y || !rotStr) { continue; }
PlacedModule pm;
pm.moduleId = *type;
pm.position = QPoint(static_cast<int>(*x), static_cast<int>(*y));
pm.rotation = parseRotation(*rotStr);
bp.modules.push_back(std::move(pm));
}
}
result.push_back(std::move(bp));
}
return result;
}
} // namespace ShipLayoutBlueprintSerializer