implement save and load blueprints
This commit is contained in:
136
src/lib/config/BlueprintSerializer.cpp
Normal file
136
src/lib/config/BlueprintSerializer.cpp
Normal file
@@ -0,0 +1,136 @@
|
||||
#include "BlueprintSerializer.h"
|
||||
|
||||
#include <sstream>
|
||||
#include <stdexcept>
|
||||
|
||||
#include "toml.hpp"
|
||||
|
||||
#include "BuildingType.h"
|
||||
#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 BlueprintSerializer
|
||||
{
|
||||
|
||||
std::string serialize(const std::vector<Blueprint>& blueprints)
|
||||
{
|
||||
toml::array bpArr;
|
||||
for (const Blueprint& bp : blueprints)
|
||||
{
|
||||
toml::array bldArr;
|
||||
for (const BlueprintBuilding& b : bp.buildings)
|
||||
{
|
||||
toml::table bldTbl;
|
||||
bldTbl.insert("type", buildingTypeId(b.type));
|
||||
bldTbl.insert("rotation", rotationToString(b.rotation));
|
||||
bldTbl.insert("offset_x", static_cast<int64_t>(b.offset.x()));
|
||||
bldTbl.insert("offset_y", static_cast<int64_t>(b.offset.y()));
|
||||
bldTbl.insert("recipe_id", b.recipeId);
|
||||
bldArr.push_back(std::move(bldTbl));
|
||||
}
|
||||
|
||||
toml::table bpTbl;
|
||||
bpTbl.insert("name", bp.name.toStdString());
|
||||
bpTbl.insert("buildings", std::move(bldArr));
|
||||
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<Blueprint> 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<Blueprint> 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)
|
||||
{
|
||||
throw std::runtime_error("blueprint[" + std::to_string(i) + "] is not a table");
|
||||
}
|
||||
|
||||
Blueprint bp;
|
||||
bp.name = QString::fromStdString((*bpTbl)["name"].value_or(std::string{}));
|
||||
|
||||
const toml::array* bldArr = (*bpTbl)["buildings"].as_array();
|
||||
if (bldArr)
|
||||
{
|
||||
for (std::size_t j = 0; j < bldArr->size(); ++j)
|
||||
{
|
||||
const toml::table* bldTbl = (*bldArr)[j].as_table();
|
||||
if (!bldTbl)
|
||||
{
|
||||
throw std::runtime_error(
|
||||
"blueprint[" + std::to_string(i) + "].buildings[" +
|
||||
std::to_string(j) + "] is not a table");
|
||||
}
|
||||
|
||||
const std::string typeStr = (*bldTbl)["type"].value_or(std::string{});
|
||||
const std::optional<BuildingType> parsedType = parseBuildingType(typeStr);
|
||||
if (!parsedType)
|
||||
{
|
||||
throw std::runtime_error("unknown building type: '" + typeStr + "'");
|
||||
}
|
||||
|
||||
BlueprintBuilding bb;
|
||||
bb.type = *parsedType;
|
||||
bb.rotation = parseRotation((*bldTbl)["rotation"].value_or(std::string{}));
|
||||
bb.offset.setX(static_cast<int>((*bldTbl)["offset_x"].value_or(int64_t{0})));
|
||||
bb.offset.setY(static_cast<int>((*bldTbl)["offset_y"].value_or(int64_t{0})));
|
||||
bb.recipeId = (*bldTbl)["recipe_id"].value_or(std::string{});
|
||||
bp.buildings.push_back(std::move(bb));
|
||||
}
|
||||
}
|
||||
|
||||
result.push_back(std::move(bp));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
} // namespace BlueprintSerializer
|
||||
14
src/lib/config/BlueprintSerializer.h
Normal file
14
src/lib/config/BlueprintSerializer.h
Normal file
@@ -0,0 +1,14 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "Blueprint.h"
|
||||
|
||||
namespace BlueprintSerializer
|
||||
{
|
||||
|
||||
std::string serialize(const std::vector<Blueprint>& blueprints);
|
||||
std::vector<Blueprint> deserialize(const std::string& tomlContent);
|
||||
|
||||
} // namespace BlueprintSerializer
|
||||
@@ -9,6 +9,7 @@ SET(HDRS
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/GameConfig.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/ConfigLoader.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/SurfaceMask.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/BlueprintSerializer.h
|
||||
PARENT_SCOPE
|
||||
)
|
||||
|
||||
@@ -17,6 +18,7 @@ SET(SRCS
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/Formula.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/ConfigLoader.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/SurfaceMask.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/BlueprintSerializer.cpp
|
||||
PARENT_SCOPE
|
||||
)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user