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/map/Map.cpp | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) (limited to 'src/openvic-simulation/map/Map.cpp') 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, -- cgit v1.2.3-56-ga3b1 From 5549753a6ae909b1a65f52a1cc67ef2b5efae55a Mon Sep 17 00:00:00 2001 From: Hop311 Date: Sun, 17 Sep 2023 15:08:11 +0100 Subject: Futher scaffolding for province positions loading --- src/openvic-simulation/dataloader/Dataloader.cpp | 8 ++++-- src/openvic-simulation/dataloader/Dataloader.hpp | 2 +- src/openvic-simulation/dataloader/NodeTools.cpp | 31 +++++++++++++++++---- src/openvic-simulation/dataloader/NodeTools.hpp | 35 ++++++++++++------------ src/openvic-simulation/map/Map.cpp | 6 ++-- src/openvic-simulation/map/Map.hpp | 2 +- src/openvic-simulation/map/Province.cpp | 2 +- src/openvic-simulation/map/Province.hpp | 2 +- 8 files changed, 56 insertions(+), 32 deletions(-) (limited to 'src/openvic-simulation/map/Map.cpp') diff --git a/src/openvic-simulation/dataloader/Dataloader.cpp b/src/openvic-simulation/dataloader/Dataloader.cpp index eae3f84..2d2f59f 100644 --- a/src/openvic-simulation/dataloader/Dataloader.cpp +++ b/src/openvic-simulation/dataloader/Dataloader.cpp @@ -157,7 +157,9 @@ bool Dataloader::_load_pop_types(PopManager& pop_manager, fs::path const& pop_ty return ret; } -bool Dataloader::_load_map_dir(Map& map, fs::path const& map_directory) const { +bool Dataloader::_load_map_dir(GameManager& game_manager, fs::path const& map_directory) const { + Map& map = game_manager.map; + static const fs::path defaults_filename = "default.map"; static const std::string default_definitions = "definition.csv"; static const std::string default_provinces = "provinces.bmp"; @@ -230,7 +232,7 @@ 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())) { + if (!map.load_province_positions(game_manager.building_manager, _parse_defines(lookup_file(map_directory / positions)).get_file_node())) { Logger::error("Failed to load province positions file!"); ret = false; } @@ -279,7 +281,7 @@ bool Dataloader::load_defines(GameManager& game_manager) const { Logger::error("Failed to load religions!"); ret = false; } - if (!_load_map_dir(game_manager.map, map_directory)) { + if (!_load_map_dir(game_manager, map_directory)) { Logger::error("Failed to load map!"); ret = false; } diff --git a/src/openvic-simulation/dataloader/Dataloader.hpp b/src/openvic-simulation/dataloader/Dataloader.hpp index b07248e..6741361 100644 --- a/src/openvic-simulation/dataloader/Dataloader.hpp +++ b/src/openvic-simulation/dataloader/Dataloader.hpp @@ -21,7 +21,7 @@ namespace OpenVic { path_vector_t roots; bool _load_pop_types(PopManager& pop_manager, fs::path const& pop_type_directory) const; - bool _load_map_dir(Map& map, fs::path const& map_directory) const; + bool _load_map_dir(GameManager& game_manager, fs::path const& map_directory) const; public: Dataloader() = default; diff --git a/src/openvic-simulation/dataloader/NodeTools.cpp b/src/openvic-simulation/dataloader/NodeTools.cpp index 63a97ad..7dd6e16 100644 --- a/src/openvic-simulation/dataloader/NodeTools.cpp +++ b/src/openvic-simulation/dataloader/NodeTools.cpp @@ -19,20 +19,20 @@ static node_callback_t _expect_type(callback_t callback) { }; } -template +template requires(std::derived_from) -static callback_t abstract_string_node_callback(callback_t callback) { +static callback_t _abstract_string_node_callback(callback_t callback) { return [callback](T const& node) -> bool { return callback(node._name); }; } node_callback_t NodeTools::expect_identifier(callback_t callback) { - return _expect_type(abstract_string_node_callback(callback)); + return _expect_type(_abstract_string_node_callback(callback)); } node_callback_t NodeTools::expect_string(callback_t callback) { - return _expect_type(abstract_string_node_callback(callback)); + return _expect_type(_abstract_string_node_callback(callback)); } node_callback_t NodeTools::expect_identifier_or_string(callback_t callback) { @@ -43,7 +43,7 @@ node_callback_t NodeTools::expect_identifier_or_string(callback_tcast_to(); } if (cast_node != nullptr) { - return abstract_string_node_callback(callback)(*cast_node); + return _abstract_string_node_callback(callback)(*cast_node); } Logger::error("Invalid node type ", node->get_type(), " when expecting ", ast::IdentifierNode::get_type_static(), " or ", ast::StringNode::get_type_static()); } else { @@ -148,6 +148,27 @@ node_callback_t NodeTools::expect_date(callback_t callback) { ); } +template)> +node_callback_t _expect_vec2(callback_t> callback) { + return [callback](ast::NodeCPtr node) -> bool { + vec2_t vec; + bool ret = expect_dictionary_keys( + "x", ONE_EXACTLY, expect_func(assign_variable_callback(vec.x)), + "y", ONE_EXACTLY, expect_func(assign_variable_callback(vec.y)) + )(node); + ret &= callback(vec); + return ret; + }; +} + +node_callback_t NodeTools::expect_ivec2(callback_t callback) { + return _expect_vec2(callback); +} + +node_callback_t NodeTools::expect_fvec2(callback_t callback) { + return _expect_vec2(callback); +} + node_callback_t NodeTools::expect_assign(key_value_callback_t callback) { return _expect_type( [callback](ast::AssignNode const& assign_node) -> bool { diff --git a/src/openvic-simulation/dataloader/NodeTools.hpp b/src/openvic-simulation/dataloader/NodeTools.hpp index 8508087..bb75ffe 100644 --- a/src/openvic-simulation/dataloader/NodeTools.hpp +++ b/src/openvic-simulation/dataloader/NodeTools.hpp @@ -6,7 +6,7 @@ #include "openvic-simulation/types/Colour.hpp" #include "openvic-simulation/types/Date.hpp" -#include "openvic-simulation/types/fixed_point/FixedPoint.hpp" +#include "openvic-simulation/types/Vector.hpp" namespace OpenVic { namespace ast = ovdl::v2script::ast; @@ -31,6 +31,8 @@ namespace OpenVic { node_callback_t expect_fixed_point(callback_t callback); node_callback_t expect_colour(callback_t callback); node_callback_t expect_date(callback_t callback); + node_callback_t expect_ivec2(callback_t callback); + node_callback_t expect_fvec2(callback_t callback); node_callback_t expect_assign(key_value_callback_t callback); using length_callback_t = std::function; @@ -134,32 +136,31 @@ namespace OpenVic { }; } - template - requires(std::integral) - callback_t assign_variable_callback_uint(const std::string_view name, T& var) { - return [&var, name](uint64_t val) -> bool { - if (val <= std::numeric_limits::max()) { + template + requires(std::integral, std::integral) + callback_t _assign_variable_callback_int(const std::string_view name, T& var) { + return [&var, name](I val) -> bool { + if (std::numeric_limits::lowest() <= val && val <= std::numeric_limits::max()) { var = val; return true; } - Logger::error("Invalid ", name, ": ", val, " (valid range: [0, ", static_cast(std::numeric_limits::max()), "])"); + Logger::error("Invalid ", name, ": ", val, " (valid range: [", + static_cast(std::numeric_limits::lowest()), ", ", + static_cast(std::numeric_limits::max()), "])"); return false; }; } + template + requires(std::integral) + callback_t assign_variable_callback_uint(const std::string_view name, T& var) { + return _assign_variable_callback_int(name, var); + } + template requires(std::integral) callback_t assign_variable_callback_int(const std::string_view name, T& var) { - return [&var, name](int64_t val) -> bool { - if (std::numeric_limits::lowest() <= val && val <= std::numeric_limits::max()) { - var = val; - return true; - } - Logger::error("Invalid ", name, ": ", val, " (valid range: [", - static_cast(std::numeric_limits::lowest()), ", ", - static_cast(std::numeric_limits::max()), "])"); - return false; - }; + return _assign_variable_callback_int(name, var); } } } diff --git a/src/openvic-simulation/map/Map.cpp b/src/openvic-simulation/map/Map.cpp index 29bec7b..6fbdc4f 100644 --- a/src/openvic-simulation/map/Map.cpp +++ b/src/openvic-simulation/map/Map.cpp @@ -523,10 +523,10 @@ bool Map::load_province_definitions(std::vector const& lines) { return ret; } -bool Map::load_province_positions(ast::NodeCPtr root) { +bool Map::load_province_positions(BuildingManager const& building_manager, ast::NodeCPtr root) { return expect_province_dictionary( - [](Province& province, ast::NodeCPtr node) -> bool { - return province.load_positions(node); + [&building_manager](Province& province, ast::NodeCPtr node) -> bool { + return province.load_positions(building_manager, node); } )(root); } diff --git a/src/openvic-simulation/map/Map.hpp b/src/openvic-simulation/map/Map.hpp index 0e00055..5cba8da 100644 --- a/src/openvic-simulation/map/Map.hpp +++ b/src/openvic-simulation/map/Map.hpp @@ -114,7 +114,7 @@ namespace OpenVic { 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_province_positions(BuildingManager const& building_manager, 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 5a3543b..775c0a4 100644 --- a/src/openvic-simulation/map/Province.cpp +++ b/src/openvic-simulation/map/Province.cpp @@ -34,7 +34,7 @@ Province::life_rating_t Province::get_life_rating() const { return life_rating; } -bool Province::load_positions(ast::NodeCPtr root) { +bool Province::load_positions(BuildingManager const& building_manager, ast::NodeCPtr root) { // TODO - implement province position loading // (root is the dictionary after the province identifier) return true; diff --git a/src/openvic-simulation/map/Province.hpp b/src/openvic-simulation/map/Province.hpp index d4e34c5..bf407ae 100644 --- a/src/openvic-simulation/map/Province.hpp +++ b/src/openvic-simulation/map/Province.hpp @@ -43,7 +43,7 @@ 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 load_positions(BuildingManager const& building_manager, ast::NodeCPtr root); bool add_building(Building&& building); IDENTIFIER_REGISTRY_ACCESSORS(Building, building) -- cgit v1.2.3-56-ga3b1 From 72add97c47f0d17fc0019bb4cfec7506740a9c7d Mon Sep 17 00:00:00 2001 From: Hop311 Date: Mon, 18 Sep 2023 00:16:05 +0100 Subject: Province adjacency scaffolding --- src/openvic-simulation/dataloader/Dataloader.cpp | 4 +- src/openvic-simulation/dataloader/NodeTools.hpp | 8 ++ src/openvic-simulation/economy/Good.cpp | 2 +- src/openvic-simulation/economy/Good.hpp | 2 +- src/openvic-simulation/map/Map.cpp | 103 +++++++-------------- src/openvic-simulation/map/Map.hpp | 17 +--- src/openvic-simulation/pop/Culture.cpp | 2 +- src/openvic-simulation/pop/Pop.cpp | 4 +- .../types/IdentifierRegistry.hpp | 58 ++++++++++-- 9 files changed, 101 insertions(+), 99 deletions(-) (limited to 'src/openvic-simulation/map/Map.cpp') diff --git a/src/openvic-simulation/dataloader/Dataloader.cpp b/src/openvic-simulation/dataloader/Dataloader.cpp index 2d2f59f..a30983b 100644 --- a/src/openvic-simulation/dataloader/Dataloader.cpp +++ b/src/openvic-simulation/dataloader/Dataloader.cpp @@ -252,7 +252,7 @@ bool Dataloader::_load_map_dir(GameManager& game_manager, fs::path const& map_di } bool Dataloader::load_defines(GameManager& game_manager) const { - static const fs::path good_file = "common/goods.txt"; + static const fs::path goods_file = "common/goods.txt"; static const fs::path pop_type_directory = "poptypes"; static const fs::path graphical_culture_type_file = "common/graphicalculturetype.txt"; static const fs::path culture_file = "common/cultures.txt"; @@ -261,7 +261,7 @@ bool Dataloader::load_defines(GameManager& game_manager) const { bool ret = true; - if (!game_manager.good_manager.load_good_file(_parse_defines(lookup_file(good_file)).get_file_node())) { + if (!game_manager.good_manager.load_goods_file(_parse_defines(lookup_file(goods_file)).get_file_node())) { Logger::error("Failed to load goods!"); ret = false; } diff --git a/src/openvic-simulation/dataloader/NodeTools.hpp b/src/openvic-simulation/dataloader/NodeTools.hpp index bb75ffe..51bbfa9 100644 --- a/src/openvic-simulation/dataloader/NodeTools.hpp +++ b/src/openvic-simulation/dataloader/NodeTools.hpp @@ -162,5 +162,13 @@ namespace OpenVic { callback_t assign_variable_callback_int(const std::string_view name, T& var) { return _assign_variable_callback_int(name, var); } + + template + callback_t assign_variable_callback_pointer(T const*& var) { + return [&var](T const& val) -> bool { + var = &val; + return true; + }; + } } } diff --git a/src/openvic-simulation/economy/Good.cpp b/src/openvic-simulation/economy/Good.cpp index 6edf631..8675369 100644 --- a/src/openvic-simulation/economy/Good.cpp +++ b/src/openvic-simulation/economy/Good.cpp @@ -92,7 +92,7 @@ void GoodManager::reset_to_defaults() { good.reset_to_defaults(); } -bool GoodManager::load_good_file(ast::NodeCPtr root) { +bool GoodManager::load_goods_file(ast::NodeCPtr root) { size_t total_expected_goods = 0; bool ret = expect_dictionary_reserve_length( good_categories, diff --git a/src/openvic-simulation/economy/Good.hpp b/src/openvic-simulation/economy/Good.hpp index ce97cad..6c237b1 100644 --- a/src/openvic-simulation/economy/Good.hpp +++ b/src/openvic-simulation/economy/Good.hpp @@ -74,6 +74,6 @@ namespace OpenVic { IDENTIFIER_REGISTRY_ACCESSORS(Good, good) void reset_to_defaults(); - bool load_good_file(ast::NodeCPtr root); + bool load_goods_file(ast::NodeCPtr root); }; } diff --git a/src/openvic-simulation/map/Map.cpp b/src/openvic-simulation/map/Map.cpp index 6fbdc4f..0173ab6 100644 --- a/src/openvic-simulation/map/Map.cpp +++ b/src/openvic-simulation/map/Map.cpp @@ -54,10 +54,6 @@ bool Map::add_province(const std::string_view identifier, colour_t colour) { return provinces.add_item(std::move(new_province)); } -void Map::lock_provinces() { - provinces.lock(); -} - bool Map::set_water_province(const std::string_view identifier) { if (water_provinces.is_locked()) { Logger::error("The map's water provinces have already been locked!"); @@ -133,36 +129,6 @@ bool Map::add_region(const std::string_view identifier, std::vectorget_has_region()) { - Logger::error("Province in non-meta region without has_region set: ", province->get_identifier()); - province->has_region = true; - } - province->region = ®ion; - } - } - } - for (Province& province : provinces.get_items()) { - const bool region_null = province.get_region() == nullptr; - if (province.get_has_region() == region_null) { - Logger::error("Province has_region / region mismatch: has_region = ", province.get_has_region(), ", region = ", province.get_region()); - province.has_region = !region_null; - } - } -} - -size_t Map::get_province_count() const { - return provinces.size(); -} - -std::vector const& Map::get_provinces() const { - return provinces.get_items(); -} - Province* Map::get_province_by_index(Province::index_t index) { return index != Province::NULL_INDEX ? provinces.get_item_by_index(index - 1) : nullptr; } @@ -171,14 +137,6 @@ Province const* Map::get_province_by_index(Province::index_t index) const { return index != Province::NULL_INDEX ? provinces.get_item_by_index(index - 1) : nullptr; } -Province* Map::get_province_by_identifier(const std::string_view identifier) { - return provinces.get_item_by_identifier(identifier); -} - -Province const* Map::get_province_by_identifier(const std::string_view identifier) const { - return provinces.get_item_by_identifier(identifier); -} - Province::index_t Map::get_index_from_colour(colour_t colour) const { const colour_index_map_t::const_iterator it = colour_index_map.find(colour); if (it != colour_index_map.end()) return it->second; @@ -224,22 +182,6 @@ Province const* Map::get_selected_province() const { return get_province_by_index(get_selected_province_index()); } -Region* Map::get_region_by_identifier(const std::string_view identifier) { - return regions.get_item_by_identifier(identifier); -} - -Region const* Map::get_region_by_identifier(const std::string_view identifier) const { - return regions.get_item_by_identifier(identifier); -} - -size_t Map::get_region_count() const { - return regions.size(); -} - -std::vector const& Map::get_regions() const { - return regions.get_items(); -} - static colour_t colour_at(uint8_t const* colour_data, int32_t idx) { idx *= 3; return (colour_data[idx] << 16) | (colour_data[idx + 1] << 8) | colour_data[idx + 2]; @@ -344,6 +286,9 @@ bool Map::generate_province_shape_image(size_t new_width, size_t new_height, uin Logger::error("Province image is missing ", missing, " province colours"); ret = false; } + + ret &= _generate_province_adjacencies(); + return ret; } @@ -427,9 +372,6 @@ bool Map::setup(GoodManager const& good_manager, BuildingManager const& building bool ret = true; 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) - province.rgo = good_manager.get_good_by_index(province.get_index() % good_manager.get_good_count()); ret &= building_manager.generate_province_buildings(province); } return ret; @@ -476,17 +418,6 @@ 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!"); @@ -548,5 +479,33 @@ bool Map::load_region_file(ast::NodeCPtr root) { } )(root); lock_regions(); + for (Region& region : regions.get_items()) { + if (!region.meta) { + for (Province* province : region.get_provinces()) { + if (!province->get_has_region()) { + Logger::error("Province in non-meta region without has_region set: ", province->get_identifier()); + province->has_region = true; + } + province->region = ®ion; + } + } + } + for (Province& province : provinces.get_items()) { + const bool region_null = province.get_region() == nullptr; + if (province.get_has_region() == region_null) { + Logger::error("Province has_region / region mismatch: has_region = ", province.get_has_region(), ", region = ", province.get_region()); + province.has_region = !region_null; + } + } return ret; } + +bool Map::_generate_province_adjacencies() { + /* TODO - generate default province adjacencies + * variables available for use: + * - width, height + * - province_shape_image, so the index at (x,y) is: + * province_shape_image[x + y * width].index + */ + return true; +} diff --git a/src/openvic-simulation/map/Map.hpp b/src/openvic-simulation/map/Map.hpp index 5cba8da..163a21f 100644 --- a/src/openvic-simulation/map/Map.hpp +++ b/src/openvic-simulation/map/Map.hpp @@ -61,24 +61,23 @@ namespace OpenVic { Pop::pop_size_t highest_province_population, total_map_population; Province::index_t get_index_from_colour(colour_t colour) const; + bool _generate_province_adjacencies(); public: Map(); bool add_province(const std::string_view identifier, colour_t colour); - void lock_provinces(); + IDENTIFIER_REGISTRY_ACCESSORS(Province, province) + IDENTIFIER_REGISTRY_NON_CONST_ACCESSORS(Province, province) bool set_water_province(const std::string_view identifier); bool set_water_province_list(std::vector const& list); void lock_water_provinces(); bool add_region(const std::string_view identifier, std::vector const& province_identifiers); - void lock_regions(); + IDENTIFIER_REGISTRY_ACCESSORS(Region, region) + IDENTIFIER_REGISTRY_NON_CONST_ACCESSORS(Region, region) - size_t get_province_count() const; - std::vector const& get_provinces() const; Province* get_province_by_index(Province::index_t index); Province const* get_province_by_index(Province::index_t index) const; - Province* get_province_by_identifier(const std::string_view identifier); - Province const* get_province_by_identifier(const std::string_view identifier) const; Province::index_t get_province_index_at(size_t x, size_t y) const; bool set_max_provinces(Province::index_t new_max_provinces); Province::index_t get_max_provinces() const; @@ -86,11 +85,6 @@ namespace OpenVic { Province::index_t get_selected_province_index() const; Province const* get_selected_province() const; - Region* get_region_by_identifier(const std::string_view identifier); - Region const* get_region_by_identifier(const std::string_view identifier) const; - size_t get_region_count() const; - std::vector const& get_regions() const; - bool generate_province_shape_image(size_t new_width, size_t new_height, uint8_t const* colour_data, uint8_t const* terrain_data, terrain_variant_map_t const& terrain_variant_map, bool detailed_errors); size_t get_width() const; @@ -112,7 +106,6 @@ 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(BuildingManager const& building_manager, ast::NodeCPtr root); bool load_region_file(ast::NodeCPtr root); diff --git a/src/openvic-simulation/pop/Culture.cpp b/src/openvic-simulation/pop/Culture.cpp index 7e78b68..dadc0a6 100644 --- a/src/openvic-simulation/pop/Culture.cpp +++ b/src/openvic-simulation/pop/Culture.cpp @@ -130,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_identifier(unit_graphical_culture_type)(node); + return expect_graphical_culture_type_identifier(assign_variable_callback_pointer(unit_graphical_culture_type))(node); }, "union", ZERO_OR_ONE, [&total_expected_cultures](ast::NodeCPtr) -> bool { total_expected_cultures--; diff --git a/src/openvic-simulation/pop/Pop.cpp b/src/openvic-simulation/pop/Pop.cpp index 26699c3..8feead9 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_identifier(culture), - "religion", ONE_EXACTLY, religion_manager.expect_religion_identifier(religion), + "culture", ONE_EXACTLY, culture_manager.expect_culture_identifier(assign_variable_callback_pointer(culture)), + "religion", ONE_EXACTLY, religion_manager.expect_religion_identifier(assign_variable_callback_pointer(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 8dabd46..c79e51b 100644 --- a/src/openvic-simulation/types/IdentifierRegistry.hpp +++ b/src/openvic-simulation/types/IdentifierRegistry.hpp @@ -171,30 +171,72 @@ namespace OpenVic { return items; } - NodeTools::node_callback_t expect_item_identifier(T const*& ret) const { + NodeTools::node_callback_t expect_item_identifier(NodeTools::callback_t callback) { return NodeTools::expect_identifier( - [this, &ret](std::string_view identifier) -> bool { - ret = get_item_by_identifier(identifier); - if (ret != nullptr) return true; + [this, callback](std::string_view identifier) -> bool { + T* item = get_item_by_identifier(identifier); + if (item != nullptr) return callback(*item); Logger::error("Invalid ", name, ": ", identifier); return false; } ); } + + NodeTools::node_callback_t expect_item_identifier(NodeTools::callback_t callback) const { + return NodeTools::expect_identifier( + [this, callback](std::string_view identifier) -> bool { + T const* item = get_item_by_identifier(identifier); + if (item != nullptr) return callback(*item); + Logger::error("Invalid ", name, ": ", identifier); + return false; + } + ); + } + + NodeTools::node_callback_t expect_item_dictionary(NodeTools::callback_t callback) { + return NodeTools::expect_dictionary([this, callback](std::string_view key, ast::NodeCPtr value) -> bool { + T* item = get_item_by_identifier(key); + if (item != nullptr) { + return callback(*item, value); + } + Logger::error("Invalid ", name, " identifier: ", key); + return false; + }); + } + + NodeTools::node_callback_t expect_item_dictionary(NodeTools::callback_t callback) const { + return NodeTools::expect_dictionary([this, callback](std::string_view key, ast::NodeCPtr value) -> bool { + T const* item = get_item_by_identifier(key); + if (item != nullptr) { + return callback(*item, value); + } + Logger::error("Invalid ", name, " identifier: ", key); + return false; + }); + } }; #define IDENTIFIER_REGISTRY_ACCESSORS_CUSTOM_PLURAL(type, singular, plural) \ void lock_##plural() { plural.lock(); } \ - type const* get_##singular##_by_index(size_t index) const { \ - return plural.get_item_by_index(index); } \ type const* get_##singular##_by_identifier(const std::string_view identifier) const { \ return plural.get_item_by_identifier(identifier); } \ size_t get_##singular##_count() const { \ return plural.size(); } \ std::vector const& get_##plural() const { \ return plural.get_items(); } \ - NodeTools::node_callback_t expect_##singular##_identifier(type const*& ret) const { \ - return plural.expect_item_identifier(ret); } + NodeTools::node_callback_t expect_##singular##_identifier(NodeTools::callback_t callback) const { \ + return plural.expect_item_identifier(callback); } \ + NodeTools::node_callback_t expect_##singular##_dictionary(NodeTools::callback_t callback) const { \ + return plural.expect_item_dictionary(callback); } + +#define IDENTIFIER_REGISTRY_NON_CONST_ACCESSORS_CUSTOM_PLURAL(type, singular, plural) \ + type* get_##singular##_by_identifier(const std::string_view identifier) { \ + return plural.get_item_by_identifier(identifier); } \ + NodeTools::node_callback_t expect_##singular##_identifier(NodeTools::callback_t callback) { \ + return plural.expect_item_identifier(callback); } \ + NodeTools::node_callback_t expect_##singular##_dictionary(NodeTools::callback_t callback) { \ + return plural.expect_item_dictionary(callback); } #define IDENTIFIER_REGISTRY_ACCESSORS(type, name) IDENTIFIER_REGISTRY_ACCESSORS_CUSTOM_PLURAL(type, name, name##s) +#define IDENTIFIER_REGISTRY_NON_CONST_ACCESSORS(type, name) IDENTIFIER_REGISTRY_NON_CONST_ACCESSORS_CUSTOM_PLURAL(type, name, name##s) } -- cgit v1.2.3-56-ga3b1