diff options
Diffstat (limited to 'src/openvic-simulation/map/Map.cpp')
-rw-r--r-- | src/openvic-simulation/map/Map.cpp | 156 |
1 files changed, 110 insertions, 46 deletions
diff --git a/src/openvic-simulation/map/Map.cpp b/src/openvic-simulation/map/Map.cpp index fde3b3a..67e91cd 100644 --- a/src/openvic-simulation/map/Map.cpp +++ b/src/openvic-simulation/map/Map.cpp @@ -1,7 +1,9 @@ #include "Map.hpp" #include <cassert> +#include <cstddef> #include <unordered_set> +#include <vector> #include "openvic-simulation/economy/Good.hpp" #include "openvic-simulation/history/ProvinceHistory.hpp" @@ -108,42 +110,30 @@ void Map::lock_water_provinces() { Logger::info("Locked water provinces after registering ", water_provinces.size()); } -bool Map::add_region(std::string_view identifier, std::vector<std::string_view> const& province_identifiers) { +bool Map::add_region(std::string_view identifier, Region::provinces_t const& provinces) { if (identifier.empty()) { Logger::error("Invalid region identifier - empty!"); return false; } - Region::provinces_t provinces; - provinces.reserve(province_identifiers.size()); - bool meta = false, ret = true; - for (const std::string_view province_identifier : province_identifiers) { - Province* province = get_province_by_identifier(province_identifier); - if (province != nullptr) { - if (std::find(provinces.begin(), provinces.end(), province) != provinces.end()) { - Logger::error("Duplicate province identifier ", province_identifier, " in region ", identifier); - ret = false; - } else { - if (province->get_has_region()) { - meta = true; - } - provinces.push_back(province); - } - } else { - Logger::error("Invalid province identifier ", province_identifier, " for region ", identifier); - ret = false; - } - } if (provinces.empty()) { Logger::warning("No valid provinces in list for ", identifier); - return ret; + return true; } - if (!meta) { - for (Province* province : provinces) { - province->has_region = true; + const bool meta = std::any_of(provinces.begin(), provinces.end(), std::bind_front(&Province::get_has_region)); + + Region region { identifier, provinces.front()->get_colour(), meta }; + bool ret = region.add_provinces(provinces); + region.lock(); + if (regions.add_item(std::move(region))) { + if (!meta) { + for (Province const* province : provinces) { + remove_province_const(province)->has_region = true; + } } + } else { + ret = false; } - ret &= regions.add_item({ identifier, std::move(provinces), meta }); return ret; } @@ -387,36 +377,22 @@ bool Map::load_province_positions(BuildingTypeManager const& building_type_manag bool Map::load_region_file(ast::NodeCPtr root) { const bool ret = expect_dictionary_reserve_length(regions, [this](std::string_view region_identifier, ast::NodeCPtr region_node) -> bool { - std::vector<std::string_view> province_identifiers; + Region::provinces_t provinces; bool ret = expect_list_reserve_length( - province_identifiers, expect_identifier(vector_callback(province_identifiers)) + provinces, expect_province_identifier(vector_callback_pointer(provinces)) )(region_node); - ret &= add_region(region_identifier, province_identifiers); + ret &= add_region(region_identifier, provinces); return ret; } )(root); lock_regions(); - for (Region& region : regions.get_items()) { + for (Region const& 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 const* province : region.get_provinces()) { + remove_province_const(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; } @@ -670,3 +646,91 @@ bool Map::generate_and_load_province_adjacencies(std::vector<LineObject> const& ); return ret; } + +bool Map::load_climate_file(ModifierManager const& modifier_manager, ast::NodeCPtr root) { + bool ret = expect_dictionary_reserve_length(climates, [this, &modifier_manager](std::string_view identifier, ast::NodeCPtr node) -> bool { + if (identifier.empty()) { + Logger::error("Invalid climate identifier - empty!"); + return false; + } + + bool ret = true; + Climate* cur_climate = climates.get_item_by_identifier(identifier); + if (cur_climate == nullptr) { + ModifierValue values; + ret &= modifier_manager.expect_modifier_value(move_variable_callback(values))(node); + ret &= climates.add_item({ identifier, std::move(values) }); + } else { + ret &= expect_list_reserve_length(*cur_climate, expect_province_identifier( + [cur_climate, &identifier](Province& province) { + if (province.climate != cur_climate) { + cur_climate->add_province(&province); + if (province.climate != nullptr) { + Climate* old_climate = const_cast<Climate*>(province.climate); + old_climate->remove_province(&province); + Logger::warning( + "Province with id ", province.get_identifier(), + " found in multiple climates: ", identifier, + " and ", old_climate->get_identifier() + ); + } + province.climate = cur_climate; + } else { + Logger::warning( + "Province with id ", province.get_identifier(), + "defined twice in climate ", identifier + ); + } + return true; + } + ))(node); + cur_climate->lock(); + } + return ret; + })(root); + + lock_climates(); + + return ret; +} + +bool Map::load_continent_file(ModifierManager const& modifier_manager, ast::NodeCPtr root) { + bool ret = expect_dictionary_reserve_length(continents, [this, &modifier_manager](std::string_view identifier, ast::NodeCPtr node) -> bool { + if (identifier.empty()) { + Logger::error("Invalid continent identifier - empty!"); + return false; + } + + ModifierValue values; + ProvinceSetModifier::provinces_t prov_list; + bool ret = modifier_manager.expect_modifier_value_and_keys(move_variable_callback(values), + "provinces", ONE_EXACTLY, expect_list_reserve_length(prov_list, expect_province_identifier( + [&prov_list](Province const& province) -> bool { + if (province.continent == nullptr) { + prov_list.emplace_back(&province); + } + return true; + } + )) + )(node); + + Continent continent = { identifier, std::move(values) }; + continent.add_provinces(prov_list); + continent.lock(); + + if (continents.add_item(std::move(continent))) { + Continent const& moved_continent = continents.get_items().back(); + for (Province const* prov : moved_continent.get_provinces()) { + remove_province_const(prov)->continent = &moved_continent; + } + } else { + ret = false; + } + + return ret; + })(root); + + lock_continents(); + + return ret; +} |