diff options
author | hop311 <hop3114@gmail.com> | 2023-10-31 02:11:47 +0100 |
---|---|---|
committer | hop311 <hop3114@gmail.com> | 2023-11-07 19:33:42 +0100 |
commit | c1b7cab254ac14a173477661047ad2492930ff8b (patch) | |
tree | 3fd965559fb97c7a2f2245952ab531afec84bc93 /src/openvic-simulation/dataloader | |
parent | e91ce707b2c0e80591b9fd1b6a5215e6e6989df8 (diff) |
History loading changes + PROPERTY macro
Diffstat (limited to 'src/openvic-simulation/dataloader')
-rw-r--r-- | src/openvic-simulation/dataloader/Dataloader.cpp | 127 | ||||
-rw-r--r-- | src/openvic-simulation/dataloader/Dataloader.hpp | 27 | ||||
-rw-r--r-- | src/openvic-simulation/dataloader/NodeTools.cpp | 9 | ||||
-rw-r--r-- | src/openvic-simulation/dataloader/NodeTools.hpp | 13 |
4 files changed, 83 insertions, 93 deletions
diff --git a/src/openvic-simulation/dataloader/Dataloader.cpp b/src/openvic-simulation/dataloader/Dataloader.cpp index 0094253..e98e63b 100644 --- a/src/openvic-simulation/dataloader/Dataloader.cpp +++ b/src/openvic-simulation/dataloader/Dataloader.cpp @@ -34,13 +34,18 @@ using namespace OpenVic; using namespace OpenVic::NodeTools; using namespace ovdl; -// Windows and Mac by default act like case insensitive filesystems -static constexpr bool path_equals(std::string_view lhs, std::string_view rhs) { -#if defined(_WIN32) || (defined(__APPLE__) && defined(__MACH__)) + +static constexpr bool path_equals_case_insensitive(std::string_view lhs, std::string_view rhs) { constexpr auto ichar_equals = [](unsigned char l, unsigned char r) { return std::tolower(l) == std::tolower(r); }; return std::equal(lhs.begin(), lhs.end(), rhs.begin(), rhs.end(), ichar_equals); +} + +// Windows and Mac by default act like case insensitive filesystems +static constexpr bool path_equals(std::string_view lhs, std::string_view rhs) { +#if defined(_WIN32) || (defined(__APPLE__) && defined(__MACH__)) + return path_equals_case_insensitive(lhs, rhs); #else return std::equal(lhs.begin(), lhs.end(), rhs.begin(), rhs.end()); #endif @@ -359,14 +364,36 @@ bool Dataloader::set_roots(path_vector_t const& new_roots) { return ret; } -fs::path Dataloader::lookup_file(fs::path const& path) const { +fs::path Dataloader::lookup_file(fs::path const& path, bool print_error) const { for (fs::path const& root : roots) { const fs::path composed = root / path; if (fs::is_regular_file(composed)) { return composed; } } - Logger::error("Lookup for ", path, " failed!"); + if (print_error) { + Logger::error("Lookup for ", path, " failed!"); + } + return {}; +} + +fs::path Dataloader::lookup_file_case_insensitive(fs::path const& path, bool print_error) const { + const std::string filename = path.filename().string(); + for (fs::path const& root : roots) { + const fs::path composed = root / path; + std::error_code ec; + for (fs::directory_entry const& entry : fs::directory_iterator { composed.parent_path(), ec }) { + if (entry.is_regular_file()) { + const fs::path file = entry; + if (path_equals_case_insensitive(file.filename().string(), filename)) { + return file; + } + } + } + } + if (print_error) { + Logger::error("Lookup for ", path, " failed!"); + } return {}; } @@ -398,8 +425,9 @@ 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, callback_t<fs::path const&> callback) - const { +bool Dataloader::apply_to_files_in_dir( + fs::path const& path, fs::path const& extension, callback_t<fs::path const&> callback +) const { bool ret = true; for (fs::path const& file : lookup_files_in_dir(path, extension)) { if (!callback(file)) { @@ -498,61 +526,37 @@ bool Dataloader::_load_units(UnitManager& unit_manager, GoodManager const& good_ return ret; } -bool Dataloader::_load_oobs(GameManager& game_manager) const { - static const fs::path oob_directory = "history/units"; - - /* used for countries with no defined initial OOB */ - game_manager.get_military_manager().get_deployment_manager().add_deployment( - "NULL", std::vector<Army>(), std::vector<Navy>(), std::vector<Leader>() - ); - - bool ret = apply_to_files_in_dir(oob_directory, ".txt", [&game_manager](fs::path const& file) -> bool { - if (file.filename() == "v2dd2.txt") { - return true; /* dev diary just stuck in there for no reason whatsoever */ - } - return game_manager.get_military_manager().get_deployment_manager().load_oob_file( - game_manager, file.filename().string(), parse_defines(file).get_file_node() - ); - }); - - /* we also load OOBs in top level subdirectories, for other start dates etc */ - for (auto root : roots) { - const fs::path path = root / oob_directory; - std::error_code ec; - for (fs::directory_entry const& entry : fs::directory_iterator { path, ec }) { - if (entry.is_directory()) { - ret &= apply_to_files_in_dir(entry, ".txt", [&entry, &game_manager](fs::path const& file) -> bool { - return game_manager.get_military_manager().get_deployment_manager().load_oob_file( - game_manager, (entry.path().filename() / file.filename()).string(), parse_defines(file).get_file_node() - ); - }); - } - } - } - - game_manager.get_military_manager().get_deployment_manager().lock_deployments(); - return ret; -} - bool Dataloader::_load_history(GameManager& game_manager) const { static const fs::path country_history_directory = "history/countries"; static const fs::path province_history_directory = "history/provinces"; /* Country History */ bool ret = apply_to_files_in_dir(country_history_directory, ".txt", [this, &game_manager](fs::path const& file) -> bool { - std::string tag = file.filename().string().substr(0, 3); - - if (!game_manager.get_country_manager().has_country_identifier(tag)) { - Logger::error("Error loading history for country ", tag, ": tag not defined!"); - return false; + const std::string filename = file.stem().string(); + // TODO - standardise rules on country idenifiers characters (probably letters + underscore) and enforce them + const size_t len = std::min(std::min(filename.find(" "), filename.find("-")), filename.length()); + const std::string_view country_id { filename.data(), len }; + + Country const* country = game_manager.get_country_manager().get_country_by_identifier(country_id); + if (country == nullptr) { + Logger::warning("Found history file for non-existent country: ", country_id); + return true; } return game_manager.get_history_manager().get_country_manager().load_country_history_file( - game_manager, tag, parse_defines(lookup_file(file)).get_file_node() + game_manager, *this, *country, parse_defines(lookup_file(file)).get_file_node() ); }); game_manager.get_history_manager().get_country_manager().lock_country_histories(); + { + DeploymentManager& deployment_manager = game_manager.get_military_manager().get_deployment_manager(); + deployment_manager.lock_deployments(); + if (deployment_manager.get_missing_oob_file_count() > 0) { + Logger::warning(deployment_manager.get_missing_oob_file_count(), " missing OOB files!"); + } + } + /* Province History */ for (auto root : roots) { const fs::path path = root / province_history_directory; @@ -560,16 +564,18 @@ bool Dataloader::_load_history(GameManager& game_manager) const { for (fs::directory_entry const& entry : fs::directory_iterator { path, ec }) { if (entry.is_directory()) { bool ret = apply_to_files_in_dir(entry, ".txt", [this, &game_manager](fs::path const& file) -> bool { - std::string province_id = file.filename().string(); - province_id = province_id.substr(0, province_id.find(" ")); + const std::string filename = file.stem().string(); + const size_t len = std::min(filename.find(" "), filename.length()); + const std::string_view province_id { filename.data(), len }; - if (!game_manager.get_map().has_province_identifier(province_id)) { - Logger::error("Error loading history for province ", province_id, ": province not defined!"); - return false; + Province const* province = game_manager.get_map().get_province_by_identifier(province_id); + if (province == nullptr) { + Logger::warning("Found history file for non-existent province: ", province_id); + return true; } return game_manager.get_history_manager().get_province_manager().load_province_history_file( - game_manager, province_id, parse_defines(lookup_file(file)).get_file_node() + game_manager, *province, parse_defines(lookup_file(file)).get_file_node() ); }); } @@ -808,10 +814,6 @@ bool Dataloader::load_defines(GameManager& game_manager) const { Logger::error("Failed to load bookmarks!"); ret = false; } - if (!_load_oobs(game_manager)) { - Logger::error("Failed to load orders of battle!"); - ret = false; - } if (!game_manager.get_country_manager().load_countries( game_manager, *this, countries_file.parent_path(), parse_defines(lookup_file(countries_file)).get_file_node() )) { @@ -828,10 +830,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 game_manager.get_map() - .expect_province_dictionary([&game_manager](Province& province, ast::NodeCPtr value) -> bool { + return game_manager.get_map().expect_province_dictionary( + [&game_manager](Province& province, ast::NodeCPtr value) -> bool { return province.load_pop_list(game_manager.get_pop_manager(), value); - })(parse_defines(file).get_file_node()); + } + )(parse_defines(file).get_file_node()); }); } diff --git a/src/openvic-simulation/dataloader/Dataloader.hpp b/src/openvic-simulation/dataloader/Dataloader.hpp index 508bf13..a8b8bb1 100644 --- a/src/openvic-simulation/dataloader/Dataloader.hpp +++ b/src/openvic-simulation/dataloader/Dataloader.hpp @@ -26,7 +26,6 @@ namespace OpenVic { bool _load_pop_types(PopManager& pop_manager, UnitManager const& unit_manager, GoodManager const& good_manager) const; bool _load_units(UnitManager& unit_manager, GoodManager const& good_manager) const; bool _load_map_dir(GameManager& game_manager) const; - bool _load_oobs(GameManager& game_manager) const; bool _load_history(GameManager& game_manager) const; public: @@ -64,7 +63,8 @@ namespace OpenVic { /* REQUIREMENTS: * DAT-24 */ - fs::path lookup_file(fs::path const& path) const; + fs::path lookup_file(fs::path const& path, bool print_error = true) const; + fs::path lookup_file_case_insensitive(fs::path const& path, bool print_error = true) 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, NodeTools::callback_t<fs::path const&> callback @@ -74,24 +74,13 @@ namespace OpenVic { 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 + 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" }; - 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 = NodeTools::callback_t<std::string_view, locale_t, std::string_view>; diff --git a/src/openvic-simulation/dataloader/NodeTools.cpp b/src/openvic-simulation/dataloader/NodeTools.cpp index 2f93bc2..27d0f95 100644 --- a/src/openvic-simulation/dataloader/NodeTools.cpp +++ b/src/openvic-simulation/dataloader/NodeTools.cpp @@ -289,7 +289,7 @@ node_callback_t NodeTools::expect_dictionary(key_value_callback_t callback) { bool NodeTools::add_key_map_entry( key_map_t& key_map, std::string_view key, dictionary_entry_t::expected_count_t expected_count, node_callback_t callback ) { - if (key_map.find(key) == key_map.end()) { + if (!key_map.contains(key)) { key_map.emplace(key, dictionary_entry_t { expected_count, callback }); return true; } @@ -318,7 +318,12 @@ key_value_callback_t NodeTools::dictionary_keys_callback(key_map_t& key_map, key Logger::error("Invalid repeat of dictionary key: ", key); return false; } - return entry.callback(value); + if (entry.callback(value)) { + return true; + } else { + Logger::error("Callback failed for dictionary key: ", key); + return false; + } }; } diff --git a/src/openvic-simulation/dataloader/NodeTools.hpp b/src/openvic-simulation/dataloader/NodeTools.hpp index 798976f..4d56488 100644 --- a/src/openvic-simulation/dataloader/NodeTools.hpp +++ b/src/openvic-simulation/dataloader/NodeTools.hpp @@ -66,7 +66,7 @@ namespace OpenVic { } node_callback_t expect_identifier(callback_t<std::string_view> callback); - node_callback_t expect_string(callback_t<std::string_view> callback, bool allow_empty = true); + node_callback_t expect_string(callback_t<std::string_view> callback, bool allow_empty = false); node_callback_t expect_identifier_or_string(callback_t<std::string_view> callback, bool allow_empty = false); node_callback_t expect_bool(callback_t<bool> callback); @@ -261,15 +261,8 @@ namespace OpenVic { }; } - template<std::integral T> - callback_t<T> assign_variable_callback_cast(auto& var) { - return [&var](T val) -> bool { - var = val; - return true; - }; - } - - template<std::signed_integral T> + template<typename T> + requires std::is_integral_v<T> || std::is_enum_v<T> callback_t<T> assign_variable_callback_cast(auto& var) { return [&var](T val) -> bool { var = val; |