From bf99cd0694ab5acdfe5b14d972c484349787686f Mon Sep 17 00:00:00 2001 From: Malte Langkabel Date: Mon, 3 Aug 2026 22:31:39 +0200 Subject: [PATCH] extract loadShips into ConfigLoaderShips.cpp Continues the ConfigLoader.cpp domain split. parseRotationString and parsePlacedModules are only used by loadShips, so they move along as domain-local anonymous-namespace helpers rather than into TomlHelpers. Pure move; no logic change. Co-Authored-By: Claude Claude-Session: https://claude.ai/code/session_01YHcUerKAZKWNvSKJxYKbnG --- src/lib/config/CMakeLists.txt | 1 + src/lib/config/ConfigLoader.cpp | 123 ------------------------- src/lib/config/ConfigLoaderShips.cpp | 133 +++++++++++++++++++++++++++ 3 files changed, 134 insertions(+), 123 deletions(-) create mode 100644 src/lib/config/ConfigLoaderShips.cpp diff --git a/src/lib/config/CMakeLists.txt b/src/lib/config/CMakeLists.txt index 16975ed..0ce29e9 100644 --- a/src/lib/config/CMakeLists.txt +++ b/src/lib/config/CMakeLists.txt @@ -24,6 +24,7 @@ SET(SRCS ${CMAKE_CURRENT_SOURCE_DIR}/ConfigLoaderWorld.cpp ${CMAKE_CURRENT_SOURCE_DIR}/ConfigLoaderBuildings.cpp ${CMAKE_CURRENT_SOURCE_DIR}/ConfigLoaderRecipes.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/ConfigLoaderShips.cpp ${CMAKE_CURRENT_SOURCE_DIR}/SurfaceMask.cpp ${CMAKE_CURRENT_SOURCE_DIR}/BlueprintSerializer.cpp ${CMAKE_CURRENT_SOURCE_DIR}/ShipLayoutBlueprintSerializer.cpp diff --git a/src/lib/config/ConfigLoader.cpp b/src/lib/config/ConfigLoader.cpp index 5b23bf8..01c9f35 100644 --- a/src/lib/config/ConfigLoader.cpp +++ b/src/lib/config/ConfigLoader.cpp @@ -7,135 +7,12 @@ #include #include -#include - #include "toml.hpp" -#include "Rotation.h" -#include "ShipLayout.h" #include "TomlHelpers.h" -namespace -{ - -Rotation parseRotationString(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; -} - -std::vector parsePlacedModules(const toml::array& arr, - const std::string& file, - const std::string& path) -{ - std::vector result; - result.reserve(arr.size()); - for (std::size_t i = 0; i < arr.size(); ++i) - { - const std::string elemPath = path + "[" + std::to_string(i) + "]"; - const toml::table* t = arr[i].as_table(); - if (t == nullptr) { continue; } - toml::table& mt = const_cast(*t); - - const std::optional type = mt["type"].value(); - const std::optional x = mt["x"].value(); - const std::optional y = mt["y"].value(); - const std::optional rot = mt["rotation"].value(); - if (!type || !x || !y || !rot) { continue; } - - PlacedModule pm; - pm.moduleId = *type; - pm.position = QPoint(static_cast(*x), static_cast(*y)); - pm.rotation = parseRotationString(*rot); - result.push_back(std::move(pm)); - } - return result; -} - -} // namespace - - // --- Per-file loaders ----------------------------------------------------- -ShipsConfig ConfigLoader::loadShips(const std::string& path) -{ - const std::string file = "ships.toml"; - toml::table tbl = parseFile(path, file); - - ShipsConfig cfg; - const toml::array& arr = requireArray(tbl["ship"], file, "ship"); - - for (std::size_t i = 0; i < arr.size(); ++i) - { - const std::string elemPath = "ship[" + std::to_string(i) + "]"; - const toml::table* st = arr[i].as_table(); - if (st == nullptr) - { - throw makeError(file, elemPath, "not a table"); - } - toml::table& mt = const_cast(*st); - - ShipDef def; - def.id = requireString(mt["id"], file, elemPath + ".id"); - def.layout = requireStringArray(mt["layout"], file, elemPath + ".layout"); - - // Schematic - { - const std::string bpPath = elemPath + ".schematic"; - const toml::table& bpTable = requireTable(mt["schematic"], file, bpPath); - toml::table& bpMt = const_cast(bpTable); - - const toml::array& materials = requireArray(bpMt["materials"], file, bpPath + ".materials"); - def.schematic.materials = parseIngredients(materials, file, bpPath + ".materials"); - def.schematic.productionTimeSeconds = requireDouble( - bpMt["production_time_seconds"], file, bpPath + ".production_time_seconds"); - } - - // Health - { - const std::string hPath = elemPath + ".health"; - const toml::table& hTable = requireTable(mt["health"], file, hPath); - toml::table& hMt = const_cast(hTable); - def.health.hp = static_cast(requireDouble(hMt["hp"], file, hPath + ".hp")); - } - - // Movement - { - const std::string mPath = elemPath + ".movement"; - const toml::table& mTable = requireTable(mt["movement"], file, mPath); - toml::table& mMt = const_cast(mTable); - def.movement.speed_mps = static_cast(requireDouble(mMt["speed_mps"], file, mPath + ".speed_mps")); - def.movement.mainAcceleration_mpss = static_cast(requireDouble(mMt["main_acceleration_mpss"], file, mPath + ".main_acceleration_mpss")); - def.movement.maneuveringAcceleration_mpss = static_cast(requireDouble(mMt["maneuvering_acceleration_mpss"], file, mPath + ".maneuvering_acceleration_mpss")); - def.movement.angularAcceleration_radpss = static_cast(requireDouble(mMt["angular_acceleration_radpss"], file, mPath + ".angular_acceleration_radpss")); - def.movement.maxRotationSpeed_radps = static_cast(requireDouble(mMt["max_rotation_speed_radps"], file, mPath + ".max_rotation_speed_radps")); - } - - // Sensor - { - const std::string snsPath = elemPath + ".sensor"; - const toml::table& snsTable = requireTable(mt["sensor"], file, snsPath); - toml::table& snsMt = const_cast(snsTable); - def.sensor.sensorRange_m = static_cast(requireDouble(snsMt["sensor_range_m"], file, snsPath + ".sensor_range_m")); - } - - // Optional: default_modules (REQ-WAV-DEFAULT-MODULES) - if (mt.contains("default_modules")) - { - const toml::array& modArr = requireArray(mt["default_modules"], file, - elemPath + ".default_modules"); - def.defaultModules = parsePlacedModules(modArr, file, - elemPath + ".default_modules"); - } - - cfg.ships.push_back(std::move(def)); - } - - return cfg; -} - StationsConfig ConfigLoader::loadStations(const std::string& path) { const std::string file = "stations.toml"; diff --git a/src/lib/config/ConfigLoaderShips.cpp b/src/lib/config/ConfigLoaderShips.cpp new file mode 100644 index 0000000..41557b9 --- /dev/null +++ b/src/lib/config/ConfigLoaderShips.cpp @@ -0,0 +1,133 @@ +#include "ConfigLoader.h" + +#include +#include +#include +#include +#include + +#include + +#include "toml.hpp" + +#include "Rotation.h" +#include "ShipLayout.h" +#include "TomlHelpers.h" + +namespace +{ + +Rotation parseRotationString(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; +} + +std::vector parsePlacedModules(const toml::array& arr, + const std::string& file, + const std::string& path) +{ + std::vector result; + result.reserve(arr.size()); + for (std::size_t i = 0; i < arr.size(); ++i) + { + const std::string elemPath = path + "[" + std::to_string(i) + "]"; + const toml::table* t = arr[i].as_table(); + if (t == nullptr) { continue; } + toml::table& mt = const_cast(*t); + + const std::optional type = mt["type"].value(); + const std::optional x = mt["x"].value(); + const std::optional y = mt["y"].value(); + const std::optional rot = mt["rotation"].value(); + if (!type || !x || !y || !rot) { continue; } + + PlacedModule pm; + pm.moduleId = *type; + pm.position = QPoint(static_cast(*x), static_cast(*y)); + pm.rotation = parseRotationString(*rot); + result.push_back(std::move(pm)); + } + return result; +} + +} // namespace + +ShipsConfig ConfigLoader::loadShips(const std::string& path) +{ + const std::string file = "ships.toml"; + toml::table tbl = parseFile(path, file); + + ShipsConfig cfg; + const toml::array& arr = requireArray(tbl["ship"], file, "ship"); + + for (std::size_t i = 0; i < arr.size(); ++i) + { + const std::string elemPath = "ship[" + std::to_string(i) + "]"; + const toml::table* st = arr[i].as_table(); + if (st == nullptr) + { + throw makeError(file, elemPath, "not a table"); + } + toml::table& mt = const_cast(*st); + + ShipDef def; + def.id = requireString(mt["id"], file, elemPath + ".id"); + def.layout = requireStringArray(mt["layout"], file, elemPath + ".layout"); + + // Schematic + { + const std::string bpPath = elemPath + ".schematic"; + const toml::table& bpTable = requireTable(mt["schematic"], file, bpPath); + toml::table& bpMt = const_cast(bpTable); + + const toml::array& materials = requireArray(bpMt["materials"], file, bpPath + ".materials"); + def.schematic.materials = parseIngredients(materials, file, bpPath + ".materials"); + def.schematic.productionTimeSeconds = requireDouble( + bpMt["production_time_seconds"], file, bpPath + ".production_time_seconds"); + } + + // Health + { + const std::string hPath = elemPath + ".health"; + const toml::table& hTable = requireTable(mt["health"], file, hPath); + toml::table& hMt = const_cast(hTable); + def.health.hp = static_cast(requireDouble(hMt["hp"], file, hPath + ".hp")); + } + + // Movement + { + const std::string mPath = elemPath + ".movement"; + const toml::table& mTable = requireTable(mt["movement"], file, mPath); + toml::table& mMt = const_cast(mTable); + def.movement.speed_mps = static_cast(requireDouble(mMt["speed_mps"], file, mPath + ".speed_mps")); + def.movement.mainAcceleration_mpss = static_cast(requireDouble(mMt["main_acceleration_mpss"], file, mPath + ".main_acceleration_mpss")); + def.movement.maneuveringAcceleration_mpss = static_cast(requireDouble(mMt["maneuvering_acceleration_mpss"], file, mPath + ".maneuvering_acceleration_mpss")); + def.movement.angularAcceleration_radpss = static_cast(requireDouble(mMt["angular_acceleration_radpss"], file, mPath + ".angular_acceleration_radpss")); + def.movement.maxRotationSpeed_radps = static_cast(requireDouble(mMt["max_rotation_speed_radps"], file, mPath + ".max_rotation_speed_radps")); + } + + // Sensor + { + const std::string snsPath = elemPath + ".sensor"; + const toml::table& snsTable = requireTable(mt["sensor"], file, snsPath); + toml::table& snsMt = const_cast(snsTable); + def.sensor.sensorRange_m = static_cast(requireDouble(snsMt["sensor_range_m"], file, snsPath + ".sensor_range_m")); + } + + // Optional: default_modules (REQ-WAV-DEFAULT-MODULES) + if (mt.contains("default_modules")) + { + const toml::array& modArr = requireArray(mt["default_modules"], file, + elemPath + ".default_modules"); + def.defaultModules = parsePlacedModules(modArr, file, + elemPath + ".default_modules"); + } + + cfg.ships.push_back(std::move(def)); + } + + return cfg; +}