From 5f3e1f3b1b021cbee243236ad8947f203d0416be Mon Sep 17 00:00:00 2001 From: Hop311 Date: Thu, 14 Sep 2023 09:34:54 +0100 Subject: Region + localisation loading --- src/openvic-simulation/dataloader/Dataloader.cpp | 47 +++++++++++++++++++++--- src/openvic-simulation/dataloader/Dataloader.hpp | 16 +++++++- src/openvic-simulation/map/Map.cpp | 24 ++++++++++++ src/openvic-simulation/map/Map.hpp | 1 + src/openvic-simulation/pop/Pop.hpp | 2 +- 5 files changed, 83 insertions(+), 7 deletions(-) (limited to 'src/openvic-simulation') diff --git a/src/openvic-simulation/dataloader/Dataloader.cpp b/src/openvic-simulation/dataloader/Dataloader.cpp index 82957fc..c409e1d 100644 --- a/src/openvic-simulation/dataloader/Dataloader.cpp +++ b/src/openvic-simulation/dataloader/Dataloader.cpp @@ -50,6 +50,7 @@ fs::path Dataloader::lookup_file(fs::path const& path) const { } const fs::path Dataloader::TXT = ".txt"; +const fs::path Dataloader::CSV = ".csv"; static bool contains_file_with_name(Dataloader::path_vector_t const& paths, fs::path const& name) { @@ -88,11 +89,11 @@ bool Dataloader::apply_to_files_in_dir(fs::path const& path, std::function Parser, bool (Parser::*parse_func)()> +template Parser, bool (*parse_func)(Parser&)> static Parser _run_ovdl_parser(fs::path const& path) { Parser parser; std::string buffer; - auto error_log_stream = ovdl::detail::CallbackStream { + auto error_log_stream = detail::CallbackStream { [](void const* s, std::streamsize n, void* user_data) -> std::streamsize { if (s != nullptr && n > 0 && user_data != nullptr) { static_cast(user_data)->append(static_cast(s), n); @@ -114,7 +115,7 @@ static Parser _run_ovdl_parser(fs::path const& path) { Logger::error("Parser errors while loading ", path); return parser; } - if (!(parser.*parse_func)()) { + if (!parse_func(parser)) { Logger::error("Parse function returned false!"); } if (!buffer.empty()) { @@ -127,12 +128,20 @@ static Parser _run_ovdl_parser(fs::path const& path) { return parser; } +static bool _v2script_parse(v2script::Parser& parser) { + return parser.simple_parse(); +} + static v2script::Parser _parse_defines(fs::path const& path) { - return _run_ovdl_parser(path); + return _run_ovdl_parser(path); +} + +static bool _csv_parse(csv::Windows1252Parser& parser) { + return parser.parse_csv(); } static csv::Windows1252Parser _parse_csv(fs::path const& path) { - return _run_ovdl_parser(path); + return _run_ovdl_parser(path); } bool Dataloader::_load_pop_types(PopManager& pop_manager, fs::path const& pop_type_directory) const { @@ -221,6 +230,11 @@ bool Dataloader::_load_map_dir(Map& map, fs::path const& map_directory) const { 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; + } + if (!map.set_water_province_list(water_province_identifiers)) { Logger::error("Failed to set water provinces!"); ret = false; @@ -284,3 +298,26 @@ bool Dataloader::load_pop_history(GameManager& game_manager, fs::path const& pat } ); } + +static bool _load_localisation_file(Dataloader::localisation_callback_t callback, std::vector const& lines) { + bool ret = true; + for (csv::LineObject const& line : lines) { + const std::string_view key = line.get_value_for(0); + if (!key.empty()) { + const size_t max_entry = std::min(line.value_count() - 1, Dataloader::_LocaleCount); + for (size_t i = 0; i < max_entry; ++i) { + const std::string_view entry = line.get_value_for(i + 1); + if (!entry.empty()) { + ret &= callback(key, static_cast(i), entry); + } + } + } + } + return ret; +} + +bool Dataloader::load_localisation_files(localisation_callback_t callback, fs::path const& localisation_dir) { + return apply_to_files_in_dir(localisation_dir, [callback](fs::path path) -> bool { + return _load_localisation_file(callback, _parse_csv(path).get_lines()); + }, &CSV); +} diff --git a/src/openvic-simulation/dataloader/Dataloader.hpp b/src/openvic-simulation/dataloader/Dataloader.hpp index efada89..d93ca39 100644 --- a/src/openvic-simulation/dataloader/Dataloader.hpp +++ b/src/openvic-simulation/dataloader/Dataloader.hpp @@ -27,13 +27,27 @@ namespace OpenVic { /* In reverse-load order, so base defines first and final loaded mod last */ bool set_roots(path_vector_t new_roots); + /* REQUIREMENTS: + * DAT-24 + */ fs::path lookup_file(fs::path const& path) const; - static const fs::path TXT; + static const fs::path TXT, CSV; path_vector_t lookup_files_in_dir(fs::path const& path, fs::path const* extension = &TXT) const; bool apply_to_files_in_dir(fs::path const& path, std::function callback, fs::path const* extension = &TXT) const; bool load_defines(GameManager& game_manager) const; bool load_pop_history(GameManager& game_manager, fs::path const& path) const; + + enum locale_t : size_t { + English, French, German, Polish, Spanish, Italian, Swedish, Czech, Hungarian, Dutch, Portugese, Russian, Finnish, _LocaleCount + }; + static constexpr char const* locale_names[_LocaleCount] = { + "en_GB", "fr_FR", "de_DE", "pl_PL", "es_ES", "it_IT", "sv_SE", "cs_CZ", "hu_HU", "nl_NL", "pt_PT", "ru_RU", "fi_FI" + }; + + /* Args: key, locale, localisation */ + using localisation_callback_t = std::function; + bool load_localisation_files(localisation_callback_t callback, fs::path const& localisation_dir = "localisation"); }; } diff --git a/src/openvic-simulation/map/Map.cpp b/src/openvic-simulation/map/Map.cpp index 728fc42..74764d2 100644 --- a/src/openvic-simulation/map/Map.cpp +++ b/src/openvic-simulation/map/Map.cpp @@ -7,6 +7,7 @@ #include "openvic-simulation/utility/Logger.hpp" using namespace OpenVic; +using namespace OpenVic::NodeTools; Mapmode::Mapmode(const std::string_view new_identifier, index_t new_index, colour_func_t new_colour_func) : HasIdentifier { new_identifier }, @@ -503,3 +504,26 @@ bool Map::load_province_definitions(std::vector const& lines) { lock_provinces(); return ret; } + +/* TODO - add support for non-state province groupings used by some mods + * (currently they trigger "province already in other region" errors). + */ +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 province_identifiers; + bool ret = expect_list_reserve_length( + province_identifiers, + expect_identifier([&province_identifiers](std::string_view identifier) -> bool { + province_identifiers.push_back(identifier); + return true; + }) + )(region_node); + ret &= add_region(region_identifier, province_identifiers); + return ret; + } + )(root); + lock_regions(); + return ret; +} diff --git a/src/openvic-simulation/map/Map.hpp b/src/openvic-simulation/map/Map.hpp index 71719e2..d5157ef 100644 --- a/src/openvic-simulation/map/Map.hpp +++ b/src/openvic-simulation/map/Map.hpp @@ -113,5 +113,6 @@ namespace OpenVic { void tick(Date const& today); bool load_province_definitions(std::vector const& lines); + bool load_region_file(ast::NodeCPtr root); }; } diff --git a/src/openvic-simulation/pop/Pop.hpp b/src/openvic-simulation/pop/Pop.hpp index e70bc0b..1dc1d32 100644 --- a/src/openvic-simulation/pop/Pop.hpp +++ b/src/openvic-simulation/pop/Pop.hpp @@ -9,7 +9,7 @@ namespace OpenVic { struct PopType; /* REQUIREMENTS: - * POP-18, POP-19, POP-20, POP-21 + * POP-18, POP-19, POP-20, POP-21, POP-34, POP-35, POP-36, POP-37 */ struct Pop { friend struct PopManager; -- cgit v1.2.3-56-ga3b1