From 366f1b3941315641bdcb0ee98465b4d2134eee86 Mon Sep 17 00:00:00 2001 From: Hop311 Date: Fri, 25 Aug 2023 23:25:12 +0100 Subject: Followup big dataloader commit --- src/openvic/dataloader/Dataloader.cpp | 136 ++++++++++++++++++++++++---------- 1 file changed, 95 insertions(+), 41 deletions(-) (limited to 'src/openvic/dataloader/Dataloader.cpp') diff --git a/src/openvic/dataloader/Dataloader.cpp b/src/openvic/dataloader/Dataloader.cpp index 90537c9..f2b725e 100644 --- a/src/openvic/dataloader/Dataloader.cpp +++ b/src/openvic/dataloader/Dataloader.cpp @@ -1,10 +1,10 @@ #include "Dataloader.hpp" +#include "openvic/GameManager.hpp" #include "openvic/utility/Logger.hpp" -#include "openvic//GameManager.hpp" -#include "openvic/dataloader/NodeTools.hpp" #include +#include using namespace OpenVic; using namespace ovdl::v2script; @@ -14,19 +14,26 @@ return_t Dataloader::set_roots(std::vector new_roots) { Logger::error("Overriding existing dataloader roots!"); roots.clear(); } + return_t ret = SUCCESS; for (std::reverse_iterator::const_iterator> it = new_roots.crbegin(); it != new_roots.crend(); ++it) { - if (std::filesystem::is_directory(*it)) { - Logger::info("Adding dataloader root: ", *it); - roots.push_back(*it); + if (std::find(roots.begin(), roots.end(), *it) == roots.end()) { + if (std::filesystem::is_directory(*it)) { + Logger::info("Adding dataloader root: ", *it); + roots.push_back(*it); + } else { + Logger::error("Invalid dataloader root (must be an existing directory): ", *it); + ret = FAILURE; + } } else { - Logger::error("Invalid dataloader root (must be an existing directory): ", *it); + Logger::error("Duplicate dataloader root: ", *it); + ret = FAILURE; } } if (roots.empty()) { Logger::error("Dataloader has no roots after attempting to add ", new_roots.size()); - return FAILURE; + ret = FAILURE; } - return SUCCESS; + return ret; } std::filesystem::path Dataloader::lookup_file(std::filesystem::path const& path) const { @@ -40,28 +47,52 @@ std::filesystem::path Dataloader::lookup_file(std::filesystem::path const& path) return {}; } -static bool contains_file_with_name(std::vector const& paths, std::filesystem::path const& name) { +const std::filesystem::path Dataloader::TXT = ".txt"; + +static bool contains_file_with_name(std::vector const& paths, + std::filesystem::path const& name) { + for (std::filesystem::path const& path : paths) { if (path.filename() == name) return true; } return false; } -std::vector Dataloader::lookup_files_in_dir(std::filesystem::path const& path) const { +std::vector Dataloader::lookup_files_in_dir(std::filesystem::path const& path, + std::filesystem::path const* extension) const { + std::vector ret; for (std::filesystem::path const& root : roots) { const std::filesystem::path composed = root / path; std::error_code ec; for (std::filesystem::directory_entry const& entry : std::filesystem::directory_iterator { composed, ec }) { - if (entry.is_regular_file() && !contains_file_with_name(ret, entry.path().filename())) { - ret.push_back(entry); + if (entry.is_regular_file()) { + const std::filesystem::path file = entry; + if (extension == nullptr || file.extension() == *extension) { + if (!contains_file_with_name(ret, file.filename())) { + ret.push_back(file); + } + } } } } return ret; } -static Parser parse_defines(std::filesystem::path const& path) { +return_t Dataloader::apply_to_files_in_dir(std::filesystem::path const& path, + std::function callback, + std::filesystem::path const* extension) const { + + return_t ret = SUCCESS; + for (std::filesystem::path const& file : lookup_files_in_dir(path, extension)) { + if (callback(file) != SUCCESS) { + ret = FAILURE; + } + } + return ret; +} + +Parser Dataloader::parse_defines(std::filesystem::path const& path) { Parser parser; std::string buffer; auto error_log_stream = ovdl::detail::CallbackStream { @@ -81,8 +112,8 @@ static Parser parse_defines(std::filesystem::path const& path) { Logger::error("Parser load errors:\n\n", buffer, "\n"); buffer.clear(); } - if (parser.has_fatal_error() || parser.has_error() || parser.has_warning()) { - Logger::error("Parser warnings/errors while loading ", path); + if (parser.has_fatal_error() || parser.has_error()) { + Logger::error("Parser errors while loading ", path); return parser; } parser.simple_parse(); @@ -90,51 +121,74 @@ static Parser parse_defines(std::filesystem::path const& path) { Logger::error("Parser parse errors:\n\n", buffer, "\n"); buffer.clear(); } - if (parser.has_fatal_error() || parser.has_error() || parser.has_warning()) { - Logger::error("Parser warnings/errors while parsing ", path); + if (parser.has_fatal_error() || parser.has_error()) { + Logger::error("Parser errors while parsing ", path); } return parser; } +Parser Dataloader::parse_defines_lookup(std::filesystem::path const& path) const { + return parse_defines(lookup_file(path)); +} + +return_t Dataloader::_load_pop_types(PopManager& pop_manager, std::filesystem::path const& pop_type_directory) const { + return_t ret = SUCCESS; + if (apply_to_files_in_dir(pop_type_directory, [&pop_manager](std::filesystem::path const& file) -> return_t { + return pop_manager.load_pop_type_file(file, parse_defines(file).get_file_node()); + }) != SUCCESS) { + Logger::error("Failed to load pop types!"); + ret = FAILURE; + } + pop_manager.lock_pop_types(); + return ret; +} + return_t Dataloader::load_defines(GameManager& game_manager) const { + static const std::filesystem::path good_file = "common/goods.txt"; + static const std::filesystem::path pop_type_directory = "poptypes"; static const std::filesystem::path graphical_culture_type_file = "common/graphicalculturetype.txt"; static const std::filesystem::path culture_file = "common/cultures.txt"; + static const std::filesystem::path religion_file = "common/religion.txt"; return_t ret = SUCCESS; - if (game_manager.pop_manager.culture_manager.load_graphical_culture_type_file(parse_defines( - lookup_file(graphical_culture_type_file)).get_file_node()) != SUCCESS) { + if (game_manager.good_manager.load_good_file(parse_defines_lookup(good_file).get_file_node()) != SUCCESS) { + Logger::error("Failed to load goods!"); + ret = FAILURE; + } + if (_load_pop_types(game_manager.pop_manager, pop_type_directory) != SUCCESS) { + Logger::error("Failed to load pop types!"); + ret = FAILURE; + } + if (game_manager.pop_manager.culture_manager.load_graphical_culture_type_file(parse_defines_lookup(graphical_culture_type_file).get_file_node()) != SUCCESS) { Logger::error("Failed to load graphical culture types!"); ret = FAILURE; } - if (game_manager.pop_manager.culture_manager.load_culture_file(parse_defines( - lookup_file(culture_file)).get_file_node()) != SUCCESS) { + if (game_manager.pop_manager.culture_manager.load_culture_file(parse_defines_lookup(culture_file).get_file_node()) != SUCCESS) { Logger::error("Failed to load cultures!"); ret = FAILURE; } + if (game_manager.pop_manager.religion_manager.load_religion_file(parse_defines_lookup(religion_file).get_file_node()) != SUCCESS) { + Logger::error("Failed to load religions!"); + ret = FAILURE; + } return ret; } -static return_t load_pop_history_file(GameManager& game_manager, std::filesystem::path const& path) { - return NodeTools::expect_dictionary(parse_defines(path).get_file_node(), [&game_manager](std::string_view province_key, ast::NodeCPtr province_node) -> return_t { - Province* province = game_manager.map.get_province_by_identifier(province_key); - if (province == nullptr) { - Logger::error("Invalid province id: ", province_key); - return FAILURE; - } - return NodeTools::expect_list(province_node, [&game_manager, &province](ast::NodeCPtr pop_node) -> return_t { - return game_manager.pop_manager.load_pop_into_province(*province, pop_node); - }); - }, true); -} - return_t Dataloader::load_pop_history(GameManager& game_manager, std::filesystem::path const& path) const { - return_t ret = SUCCESS; - for (std::filesystem::path const& file : lookup_files_in_dir(path)) { - if (load_pop_history_file(game_manager, file) != SUCCESS) { - ret = FAILURE; - } - } - return ret; + return apply_to_files_in_dir(path, [&game_manager](std::filesystem::path const& file) -> return_t { + return NodeTools::expect_dictionary(parse_defines(file).get_file_node(), + [&game_manager](std::string_view province_key, ast::NodeCPtr province_node) -> return_t { + Province* province = game_manager.map.get_province_by_identifier(province_key); + if (province == nullptr) { + Logger::error("Invalid province id: ", province_key); + return FAILURE; + } + return NodeTools::expect_list(province_node, [&game_manager, &province](ast::NodeCPtr pop_node) -> return_t { + return game_manager.pop_manager.load_pop_into_province(*province, pop_node); + } + ); + }, true); + }); } -- cgit v1.2.3-56-ga3b1