From f95902fdd85f86c10b9c300099c67312fc81f11b Mon Sep 17 00:00:00 2001 From: Hop311 Date: Sat, 16 Sep 2023 16:27:41 +0100 Subject: Scaffolding for `positions.txt` + modifier loading --- src/openvic-simulation/Modifier.cpp | 21 ++++++++++++++++ src/openvic-simulation/Modifier.hpp | 5 ++++ src/openvic-simulation/dataloader/Dataloader.cpp | 28 ++++++++++++---------- src/openvic-simulation/dataloader/Dataloader.hpp | 6 +++-- src/openvic-simulation/dataloader/NodeTools.hpp | 1 + src/openvic-simulation/map/Map.cpp | 21 +++++++++++++++- src/openvic-simulation/map/Map.hpp | 2 ++ src/openvic-simulation/map/Province.cpp | 6 +++++ src/openvic-simulation/map/Province.hpp | 2 ++ src/openvic-simulation/pop/Culture.cpp | 9 +++++-- src/openvic-simulation/pop/Pop.cpp | 4 ++-- .../types/IdentifierRegistry.hpp | 6 ++--- src/openvic-simulation/types/Vector.hpp | 1 + 13 files changed, 90 insertions(+), 22 deletions(-) (limited to 'src/openvic-simulation') diff --git a/src/openvic-simulation/Modifier.cpp b/src/openvic-simulation/Modifier.cpp index d2e21c6..46bba48 100644 --- a/src/openvic-simulation/Modifier.cpp +++ b/src/openvic-simulation/Modifier.cpp @@ -1,6 +1,7 @@ #include "Modifier.hpp" using namespace OpenVic; +using namespace OpenVic::NodeTools; ModifierEffect::ModifierEffect(const std::string_view new_identifier, bool new_positive_good) : HasIdentifier { new_identifier }, positive_good { new_positive_good } {} @@ -114,3 +115,23 @@ bool ModifierManager::add_modifier(const std::string_view identifier, ModifierVa } return modifiers.add_item({ identifier, std::move(values), icon }); } + +node_callback_t ModifierManager::expect_modifier_value(callback_t callback) const { + return [this, callback](ast::NodeCPtr root) -> bool { + ModifierValue modifier; + bool ret = expect_dictionary( + [this, &modifier](std::string_view key, ast::NodeCPtr value) -> bool { + ModifierEffect const* effect = get_modifier_effect_by_identifier(key); + if (effect != nullptr) { + return expect_fixed_point( + assign_variable_callback(modifier.values[effect]) + )(value); + } + Logger::error("Invalid modifier effect: ", key); + return false; + } + )(root); + ret &= callback(std::move(modifier)); + return ret; + }; +} diff --git a/src/openvic-simulation/Modifier.hpp b/src/openvic-simulation/Modifier.hpp index eb63788..acdadfe 100644 --- a/src/openvic-simulation/Modifier.hpp +++ b/src/openvic-simulation/Modifier.hpp @@ -25,6 +25,8 @@ namespace OpenVic { }; struct ModifierValue { + friend struct ModifierManager; + using effect_map_t = std::map; private: effect_map_t values; @@ -57,6 +59,7 @@ namespace OpenVic { using icon_t = uint8_t; private: + /* A modifier can have no icon (zero). */ const icon_t icon; Modifier(const std::string_view new_identifier, ModifierValue&& new_values, icon_t new_icon); @@ -92,5 +95,7 @@ namespace OpenVic { bool add_modifier(const std::string_view identifier, ModifierValue&& values, Modifier::icon_t icon); IDENTIFIER_REGISTRY_ACCESSORS(Modifier, modifier) + + NodeTools::node_callback_t expect_modifier_value(NodeTools::callback_t callback) const; }; } diff --git a/src/openvic-simulation/dataloader/Dataloader.cpp b/src/openvic-simulation/dataloader/Dataloader.cpp index e85f499..eae3f84 100644 --- a/src/openvic-simulation/dataloader/Dataloader.cpp +++ b/src/openvic-simulation/dataloader/Dataloader.cpp @@ -50,7 +50,6 @@ fs::path Dataloader::lookup_file(fs::path const& path) const { } static bool contains_file_with_name(Dataloader::path_vector_t const& paths, fs::path const& name) { - for (fs::path const& path : paths) { if (path.filename() == name) return true; } @@ -76,8 +75,7 @@ Dataloader::path_vector_t Dataloader::lookup_files_in_dir(fs::path const& path, return ret; } -bool Dataloader::apply_to_files_in_dir(fs::path const& path, fs::path const& extension, std::function callback) const { - +bool Dataloader::apply_to_files_in_dir(fs::path const& path, fs::path const& extension, callback_t callback) const { bool ret = true; for (fs::path const& file : lookup_files_in_dir(path, extension)) { ret &= callback(file); @@ -140,6 +138,12 @@ static csv::Windows1252Parser _parse_csv(fs::path const& path) { return _run_ovdl_parser(path); } +static callback_t _parse_defines_callback(node_callback_t callback) { + return [callback](fs::path const& path) -> bool { + return callback(_parse_defines(path).get_file_node()); + }; +} + bool Dataloader::_load_pop_types(PopManager& pop_manager, fs::path const& pop_type_directory) const { const bool ret = apply_to_files_in_dir(pop_type_directory, ".txt", [&pop_manager](fs::path const& file) -> bool { @@ -226,6 +230,11 @@ bool Dataloader::_load_map_dir(Map& map, fs::path const& map_directory) const { ret = false; } + if (!map.load_province_positions(_parse_defines(lookup_file(map_directory / positions)).get_file_node())) { + Logger::error("Failed to load province positions file!"); + ret = false; + } + if (!map.load_region_file(_parse_defines(lookup_file(map_directory / region)).get_file_node())) { Logger::error("Failed to load region file!"); ret = false; @@ -281,16 +290,11 @@ bool Dataloader::load_defines(GameManager& game_manager) const { bool Dataloader::load_pop_history(GameManager& game_manager, fs::path const& path) const { return apply_to_files_in_dir(path, ".txt", [&game_manager](fs::path const& file) -> bool { - return expect_dictionary( - [&game_manager](std::string_view province_key, ast::NodeCPtr province_node) -> bool { - Province* province = game_manager.map.get_province_by_identifier(province_key); - if (province == nullptr) { - Logger::error("Invalid province id: ", province_key); - return false; - } - return province->load_pop_list(game_manager.pop_manager, province_node); + return _parse_defines_callback(game_manager.map.expect_province_dictionary( + [&game_manager](Province& province, ast::NodeCPtr value) -> bool { + return province.load_pop_list(game_manager.pop_manager, value); } - )(_parse_defines(file).get_file_node()); + ))(file); } ); } diff --git a/src/openvic-simulation/dataloader/Dataloader.hpp b/src/openvic-simulation/dataloader/Dataloader.hpp index 2b358b6..b07248e 100644 --- a/src/openvic-simulation/dataloader/Dataloader.hpp +++ b/src/openvic-simulation/dataloader/Dataloader.hpp @@ -4,6 +4,8 @@ #include #include +#include "openvic-simulation/dataloader/NodeTools.hpp" + namespace OpenVic { namespace fs = std::filesystem; @@ -33,7 +35,7 @@ namespace OpenVic { fs::path lookup_file(fs::path const& path) const; path_vector_t lookup_files_in_dir(fs::path const& path, fs::path const& extension) const; bool apply_to_files_in_dir(fs::path const& path, fs::path const& extension, - std::function callback) const; + NodeTools::callback_t callback) const; bool load_defines(GameManager& game_manager) const; bool load_pop_history(GameManager& game_manager, fs::path const& path) const; @@ -46,7 +48,7 @@ namespace OpenVic { }; /* Args: key, locale, localisation */ - using localisation_callback_t = std::function; + using localisation_callback_t = NodeTools::callback_t; bool load_localisation_files(localisation_callback_t callback, fs::path const& localisation_dir = "localisation"); }; } diff --git a/src/openvic-simulation/dataloader/NodeTools.hpp b/src/openvic-simulation/dataloader/NodeTools.hpp index a68e922..8508087 100644 --- a/src/openvic-simulation/dataloader/NodeTools.hpp +++ b/src/openvic-simulation/dataloader/NodeTools.hpp @@ -20,6 +20,7 @@ namespace OpenVic { constexpr bool success_callback(ast::NodeCPtr) { return true; } using key_value_callback_t = callback_t; + constexpr bool key_value_success_callback(std::string_view, ast::NodeCPtr) { return true; } node_callback_t expect_identifier(callback_t callback); node_callback_t expect_string(callback_t callback); diff --git a/src/openvic-simulation/map/Map.cpp b/src/openvic-simulation/map/Map.cpp index e8178e9..29bec7b 100644 --- a/src/openvic-simulation/map/Map.cpp +++ b/src/openvic-simulation/map/Map.cpp @@ -428,7 +428,7 @@ bool Map::setup(GoodManager const& good_manager, BuildingManager const& building for (Province& province : provinces.get_items()) { province.clear_pops(); // Set all land provinces to have an RGO based on their index to test them - if (!province.get_water() && !good_manager.get_good_count() > 0) + if (!province.get_water() && good_manager.get_good_count() > 0) province.rgo = good_manager.get_good_by_index(province.get_index() % good_manager.get_good_count()); ret &= building_manager.generate_province_buildings(province); } @@ -476,6 +476,17 @@ static bool parse_province_colour(colour_t& colour, std::array callback) { + return expect_dictionary([this, callback](std::string_view key, ast::NodeCPtr value) -> bool { + Province* province = get_province_by_identifier(key); + if (province != nullptr) { + return callback(*province, value); + } + Logger::error("Invalid province identifier: ", key); + return false; + }); +} + bool Map::load_province_definitions(std::vector const& lines) { if (lines.empty()) { Logger::error("No header or entries in province definition file!"); @@ -512,6 +523,14 @@ bool Map::load_province_definitions(std::vector const& lines) { return ret; } +bool Map::load_province_positions(ast::NodeCPtr root) { + return expect_province_dictionary( + [](Province& province, ast::NodeCPtr node) -> bool { + return province.load_positions(node); + } + )(root); +} + bool Map::load_region_file(ast::NodeCPtr root) { const bool ret = expect_dictionary_reserve_length( regions, diff --git a/src/openvic-simulation/map/Map.hpp b/src/openvic-simulation/map/Map.hpp index d5157ef..0e00055 100644 --- a/src/openvic-simulation/map/Map.hpp +++ b/src/openvic-simulation/map/Map.hpp @@ -112,7 +112,9 @@ namespace OpenVic { void update_state(Date const& today); void tick(Date const& today); + NodeTools::node_callback_t expect_province_dictionary(NodeTools::callback_t callback); bool load_province_definitions(std::vector const& lines); + bool load_province_positions(ast::NodeCPtr root); bool load_region_file(ast::NodeCPtr root); }; } diff --git a/src/openvic-simulation/map/Province.cpp b/src/openvic-simulation/map/Province.cpp index 49a9bfc..5a3543b 100644 --- a/src/openvic-simulation/map/Province.cpp +++ b/src/openvic-simulation/map/Province.cpp @@ -34,6 +34,12 @@ Province::life_rating_t Province::get_life_rating() const { return life_rating; } +bool Province::load_positions(ast::NodeCPtr root) { + // TODO - implement province position loading + // (root is the dictionary after the province identifier) + return true; +} + bool Province::add_building(Building&& building) { return buildings.add_item(std::move(building)); } diff --git a/src/openvic-simulation/map/Province.hpp b/src/openvic-simulation/map/Province.hpp index ca8138f..d4e34c5 100644 --- a/src/openvic-simulation/map/Province.hpp +++ b/src/openvic-simulation/map/Province.hpp @@ -43,6 +43,8 @@ namespace OpenVic { bool get_has_region() const; bool get_water() const; life_rating_t get_life_rating() const; + bool load_positions(ast::NodeCPtr root); + bool add_building(Building&& building); IDENTIFIER_REGISTRY_ACCESSORS(Building, building) void reset_buildings(); diff --git a/src/openvic-simulation/pop/Culture.cpp b/src/openvic-simulation/pop/Culture.cpp index bf14df9..7e78b68 100644 --- a/src/openvic-simulation/pop/Culture.cpp +++ b/src/openvic-simulation/pop/Culture.cpp @@ -1,5 +1,7 @@ #include "Culture.hpp" +#include + #include "openvic-simulation/dataloader/NodeTools.hpp" using namespace OpenVic; @@ -128,7 +130,7 @@ bool CultureManager::_load_culture_group(size_t& total_expected_cultures, }, "unit", ZERO_OR_ONE, [this, &total_expected_cultures, &unit_graphical_culture_type](ast::NodeCPtr node) -> bool { total_expected_cultures--; - return expect_graphical_culture_type(unit_graphical_culture_type)(node); + return expect_graphical_culture_type_identifier(unit_graphical_culture_type)(node); }, "union", ZERO_OR_ONE, [&total_expected_cultures](ast::NodeCPtr) -> bool { total_expected_cultures--; @@ -207,7 +209,10 @@ bool CultureManager::load_culture_file(ast::NodeCPtr root) { CultureGroup const* culture_group = get_culture_group_by_identifier(culture_group_key); return expect_dictionary( [this, culture_group](std::string_view key, ast::NodeCPtr value) -> bool { - if (key == "leader" || key == "unit" || key == "union" || key == "is_overseas") return true; + static const std::set> reserved_keys = { + "leader", "unit", "union", "is_overseas" + }; + if (reserved_keys.find(key) != reserved_keys.end()) return true; return _load_culture(culture_group, key, value); } )(culture_group_value); diff --git a/src/openvic-simulation/pop/Pop.cpp b/src/openvic-simulation/pop/Pop.cpp index 1c11b80..26699c3 100644 --- a/src/openvic-simulation/pop/Pop.cpp +++ b/src/openvic-simulation/pop/Pop.cpp @@ -142,8 +142,8 @@ bool PopManager::load_pop_into_province(Province& province, const std::string_vi Pop::pop_size_t size = 0; bool ret = expect_dictionary_keys( - "culture", ONE_EXACTLY, culture_manager.expect_culture(culture), - "religion", ONE_EXACTLY, religion_manager.expect_religion(religion), + "culture", ONE_EXACTLY, culture_manager.expect_culture_identifier(culture), + "religion", ONE_EXACTLY, religion_manager.expect_religion_identifier(religion), "size", ONE_EXACTLY, expect_uint(assign_variable_callback_uint("pop size", size)), "militancy", ZERO_OR_ONE, success_callback, "rebel_type", ZERO_OR_ONE, success_callback diff --git a/src/openvic-simulation/types/IdentifierRegistry.hpp b/src/openvic-simulation/types/IdentifierRegistry.hpp index 3f73a2c..8dabd46 100644 --- a/src/openvic-simulation/types/IdentifierRegistry.hpp +++ b/src/openvic-simulation/types/IdentifierRegistry.hpp @@ -171,7 +171,7 @@ namespace OpenVic { return items; } - NodeTools::node_callback_t expect_item(T const*& ret) const { + NodeTools::node_callback_t expect_item_identifier(T const*& ret) const { return NodeTools::expect_identifier( [this, &ret](std::string_view identifier) -> bool { ret = get_item_by_identifier(identifier); @@ -193,8 +193,8 @@ namespace OpenVic { return plural.size(); } \ std::vector const& get_##plural() const { \ return plural.get_items(); } \ - NodeTools::node_callback_t expect_##singular(type const*& ret) const { \ - return plural.expect_item(ret); } + NodeTools::node_callback_t expect_##singular##_identifier(type const*& ret) const { \ + return plural.expect_item_identifier(ret); } #define IDENTIFIER_REGISTRY_ACCESSORS(type, name) IDENTIFIER_REGISTRY_ACCESSORS_CUSTOM_PLURAL(type, name, name##s) } diff --git a/src/openvic-simulation/types/Vector.hpp b/src/openvic-simulation/types/Vector.hpp index fdf7d70..66f8d2b 100644 --- a/src/openvic-simulation/types/Vector.hpp +++ b/src/openvic-simulation/types/Vector.hpp @@ -27,6 +27,7 @@ namespace OpenVic { constexpr friend vec2_t operator-(vec2_t const& arg); constexpr friend vec2_t operator-(vec2_t const& left, vec2_t const& right); constexpr vec2_t& operator-=(vec2_t const& right); + constexpr friend std::ostream& operator<<(std::ostream& stream, vec2_t const& value); }; -- cgit v1.2.3-56-ga3b1