diff options
Diffstat (limited to 'src/openvic-simulation/dataloader')
-rw-r--r-- | src/openvic-simulation/dataloader/Dataloader.cpp | 187 | ||||
-rw-r--r-- | src/openvic-simulation/dataloader/Dataloader.hpp | 34 | ||||
-rw-r--r-- | src/openvic-simulation/dataloader/NodeTools.cpp | 47 | ||||
-rw-r--r-- | src/openvic-simulation/dataloader/NodeTools.hpp | 7 |
4 files changed, 202 insertions, 73 deletions
diff --git a/src/openvic-simulation/dataloader/Dataloader.cpp b/src/openvic-simulation/dataloader/Dataloader.cpp index 8a5f27e..b7984de 100644 --- a/src/openvic-simulation/dataloader/Dataloader.cpp +++ b/src/openvic-simulation/dataloader/Dataloader.cpp @@ -261,7 +261,7 @@ static bool _lua_parse(v2script::Parser& parser) { return parser.lua_defines_parse(); } -ovdl::v2script::Parser Dataloader::parse_lua_defines(fs::path const& path) { +v2script::Parser Dataloader::parse_lua_defines(fs::path const& path) { return _run_ovdl_parser<v2script::Parser, &_lua_parse>(path); } @@ -273,6 +273,14 @@ csv::Windows1252Parser Dataloader::parse_csv(fs::path const& path) { return _run_ovdl_parser<csv::Windows1252Parser, &_csv_parse>(path); } +v2script::Parser& Dataloader::parse_defines_cached(fs::path const& path) { + return cached_parsers.emplace_back(parse_defines(path)); +} + +void Dataloader::free_cache() { + cached_parsers.clear(); +} + bool Dataloader::_load_interface_files(UIManager& ui_manager) const { static constexpr std::string_view interface_directory = "interface/"; @@ -291,8 +299,7 @@ bool Dataloader::_load_interface_files(UIManager& ui_manager) const { }; for (std::string_view const& gui_file : gui_files) { if (!ui_manager.load_gui_file( - gui_file, - parse_defines(lookup_file(append_string_views(interface_directory, gui_file))).get_file_node() + gui_file, parse_defines(lookup_file(append_string_views(interface_directory, gui_file))).get_file_node() )) { Logger::error("Failed to load interface gui file: ", gui_file); ret = false; @@ -303,19 +310,21 @@ bool Dataloader::_load_interface_files(UIManager& ui_manager) const { return ret; } -bool Dataloader::_load_pop_types(GameManager& game_manager) const { +bool Dataloader::_load_pop_types(GameManager& game_manager) { PopManager& pop_manager = game_manager.get_pop_manager(); UnitManager const& unit_manager = game_manager.get_military_manager().get_unit_manager(); GoodManager const& good_manager = game_manager.get_economy_manager().get_good_manager(); + IdeologyManager const& ideology_manager = game_manager.get_politics_manager().get_ideology_manager(); static constexpr std::string_view pop_type_directory = "poptypes"; const path_vector_t pop_type_files = lookup_files_in_dir(pop_type_directory, ".txt"); pop_manager.reserve_pop_types(pop_type_files.size()); + bool ret = apply_to_files( pop_type_files, - [&pop_manager, &unit_manager, &good_manager](fs::path const& file) -> bool { + [this, &pop_manager, &unit_manager, &good_manager, &ideology_manager](fs::path const& file) -> bool { return pop_manager.load_pop_type_file( - file.stem().string(), unit_manager, good_manager, parse_defines(file).get_file_node() + file.stem().string(), unit_manager, good_manager, ideology_manager, parse_defines_cached(file).get_file_node() ); } ); @@ -332,6 +341,10 @@ bool Dataloader::_load_pop_types(GameManager& game_manager) const { } ret &= pop_manager.generate_modifiers(game_manager.get_modifier_manager()); + + static constexpr std::string_view pop_type_chances_file = "common/pop_types.txt"; + ret &= pop_manager.load_pop_type_chances_file(parse_defines_cached(lookup_file(pop_type_chances_file)).get_file_node()); + return ret; } @@ -339,16 +352,19 @@ bool Dataloader::_load_units(GameManager& game_manager) const { static constexpr std::string_view units_directory = "units"; UnitManager& unit_manager = game_manager.get_military_manager().get_unit_manager(); + bool ret = apply_to_files( lookup_files_in_dir(units_directory, ".txt"), [&game_manager, &unit_manager](fs::path const& file) -> bool { - return unit_manager.load_unit_file(game_manager.get_economy_manager().get_good_manager(), parse_defines(file).get_file_node()); + return unit_manager.load_unit_file( + game_manager.get_economy_manager().get_good_manager(), parse_defines(file).get_file_node() + ); } ); unit_manager.lock_units(); - if(!unit_manager.generate_modifiers(game_manager.get_modifier_manager())) { + if (!unit_manager.generate_modifiers(game_manager.get_modifier_manager())) { Logger::error("Failed to generate unit-based modifiers!"); ret = false; } @@ -360,9 +376,10 @@ bool Dataloader::_load_goods(GameManager& game_manager) const { static constexpr std::string_view goods_file = "common/goods.txt"; GoodManager& good_manager = game_manager.get_economy_manager().get_good_manager(); + bool ret = good_manager.load_goods_file(parse_defines(lookup_file(goods_file)).get_file_node()); - if(!good_manager.generate_modifiers(game_manager.get_modifier_manager())) { + if (!good_manager.generate_modifiers(game_manager.get_modifier_manager())) { Logger::error("Failed to generate good-based modifiers!"); ret = false; } @@ -370,15 +387,15 @@ bool Dataloader::_load_goods(GameManager& game_manager) const { return ret; } -bool Dataloader::_load_rebel_types(GameManager& game_manager) const { +bool Dataloader::_load_rebel_types(GameManager& game_manager) { static constexpr std::string_view rebel_types_file = "common/rebel_types.txt"; PoliticsManager& politics_manager = game_manager.get_politics_manager(); RebelManager& rebel_manager = politics_manager.get_rebel_manager(); - bool ret = politics_manager.load_rebels_file(parse_defines(lookup_file(rebel_types_file)).get_file_node()); + bool ret = politics_manager.load_rebels_file(parse_defines_cached(lookup_file(rebel_types_file)).get_file_node()); - if(!rebel_manager.generate_modifiers(game_manager.get_modifier_manager())) { + if (!rebel_manager.generate_modifiers(game_manager.get_modifier_manager())) { Logger::error("Failed to generate rebel type-based modifiers!"); ret &= false; } @@ -386,7 +403,7 @@ bool Dataloader::_load_rebel_types(GameManager& game_manager) const { return ret; } -bool Dataloader::_load_technologies(GameManager& game_manager) const { +bool Dataloader::_load_technologies(GameManager& game_manager) { static constexpr std::string_view technology_file = "common/technology.txt"; TechnologyManager& technology_manager = game_manager.get_research_manager().get_technology_manager(); @@ -395,32 +412,32 @@ bool Dataloader::_load_technologies(GameManager& game_manager) const { const v2script::Parser technology_file_parser = parse_defines(lookup_file(technology_file)); - if(!technology_manager.load_technology_file_areas(technology_file_parser.get_file_node())) { + if (!technology_manager.load_technology_file_areas(technology_file_parser.get_file_node())) { Logger::error("Failed to load technology areas and folders!"); ret = false; } ModifierManager& modifier_manager = game_manager.get_modifier_manager(); - if(!technology_manager.generate_modifiers(modifier_manager)) { + if (!technology_manager.generate_modifiers(modifier_manager)) { Logger::error("Failed to generate technollogy-based modifiers!"); ret = false; } - if(!technology_manager.load_technology_file_schools(modifier_manager, technology_file_parser.get_file_node())) { + if (!technology_manager.load_technology_file_schools(modifier_manager, technology_file_parser.get_file_node())) { Logger::error("Failed to load technology schools!"); ret = false; } static constexpr std::string_view technologies_directory = "technologies"; - if(!apply_to_files( + if (!apply_to_files( lookup_files_in_dir(technologies_directory, ".txt"), - [&game_manager, &technology_manager, &modifier_manager](fs::path const& file) -> bool { + [this, &game_manager, &technology_manager, &modifier_manager](fs::path const& file) -> bool { return technology_manager.load_technologies_file( modifier_manager, game_manager.get_military_manager().get_unit_manager(), game_manager.get_economy_manager().get_building_type_manager(), - parse_defines(file).get_file_node() + parse_defines_cached(file).get_file_node() ); } )) { @@ -432,20 +449,20 @@ bool Dataloader::_load_technologies(GameManager& game_manager) const { return ret; } -bool Dataloader::_load_inventions(GameManager& game_manager) const { +bool Dataloader::_load_inventions(GameManager& game_manager) { static constexpr std::string_view inventions_directory = "inventions"; InventionManager& invention_manager = game_manager.get_research_manager().get_invention_manager(); bool ret = apply_to_files( lookup_files_in_dir(inventions_directory, ".txt"), - [&game_manager, &invention_manager](fs::path const& file) -> bool { + [this, &game_manager, &invention_manager](fs::path const& file) -> bool { return invention_manager.load_inventions_file( game_manager.get_modifier_manager(), game_manager.get_military_manager().get_unit_manager(), game_manager.get_economy_manager().get_building_type_manager(), game_manager.get_crime_manager(), - parse_defines(file).get_file_node() + parse_defines_cached(file).get_file_node() ); } ); @@ -455,14 +472,15 @@ bool Dataloader::_load_inventions(GameManager& game_manager) const { return ret; } -bool Dataloader::_load_decisions(GameManager& game_manager) const { +bool Dataloader::_load_decisions(GameManager& game_manager) { static constexpr std::string_view decisions_directory = "decisions"; + DecisionManager& decision_manager = game_manager.get_decision_manager(); bool ret = apply_to_files( lookup_files_in_dir(decisions_directory, ".txt"), - [&decision_manager](fs::path const& file) -> bool { - return decision_manager.load_decision_file(parse_defines(file).get_file_node()); + [this, &decision_manager](fs::path const& file) -> bool { + return decision_manager.load_decision_file(parse_defines_cached(file).get_file_node()); } ); @@ -551,6 +569,7 @@ bool Dataloader::_load_history(GameManager& game_manager, bool unused_history_fi game_manager.get_history_manager().get_province_manager().lock_province_histories(game_manager.get_map(), false); + /* Diplomacy History */ static constexpr std::string_view diplomacy_history_directory = "history/diplomacy"; ret &= apply_to_files( lookup_files_in_dir(diplomacy_history_directory, ".txt"), @@ -560,11 +579,15 @@ bool Dataloader::_load_history(GameManager& game_manager, bool unused_history_fi ); } ); + + /* War History */ static constexpr std::string_view war_history_directory = "history/wars"; ret &= apply_to_files( lookup_files_in_dir(war_history_directory, ".txt"), [this, &game_manager](fs::path const& file) -> bool { - return game_manager.get_history_manager().get_diplomacy_manager().load_war_history_file(game_manager, parse_defines(file).get_file_node()); + return game_manager.get_history_manager().get_diplomacy_manager().load_war_history_file( + game_manager, parse_defines(file).get_file_node() + ); } ); game_manager.get_history_manager().get_diplomacy_manager().lock_diplomatic_history(); @@ -572,7 +595,7 @@ bool Dataloader::_load_history(GameManager& game_manager, bool unused_history_fi return ret; } -bool Dataloader::_load_events(GameManager& game_manager) const { +bool Dataloader::_load_events(GameManager& game_manager) { static constexpr std::string_view events_directory = "events"; const bool ret = apply_to_files( lookup_files_in_dir(events_directory, ".txt"), @@ -595,15 +618,15 @@ bool Dataloader::_load_map_dir(GameManager& game_manager) const { static constexpr std::string_view default_provinces = "provinces.bmp"; static constexpr std::string_view default_positions = "positions.txt"; static constexpr std::string_view default_terrain = "terrain.bmp"; - static constexpr std::string_view default_rivers = "rivers.bmp"; // TODO + static constexpr std::string_view default_rivers = "rivers.bmp"; // TODO - load rivers into map pixel data static constexpr std::string_view default_terrain_definition = "terrain.txt"; - static constexpr std::string_view default_tree_definition = "trees.txt"; // TODO - static constexpr std::string_view default_continent = "continent.txt"; // TODO + static constexpr std::string_view default_tree_definition = "trees.txt"; /* Tree textures and density values (unused). */ + static constexpr std::string_view default_continent = "continent.txt"; static constexpr std::string_view default_adjacencies = "adjacencies.csv"; static constexpr std::string_view default_region = "region.txt"; - static constexpr std::string_view default_region_sea = "region_sea.txt"; // TODO - static constexpr std::string_view default_province_flag_sprite = "province_flag_sprites"; // TODO - static constexpr std::string_view climate_file = "climate.txt"; // TODO + static constexpr std::string_view default_region_sea = "region_sea.txt"; /* Some empty province sets (unused). */ + static constexpr std::string_view default_province_flag_sprite = "province_flag_sprites"; /* Canal sprite/model names. */ + static constexpr std::string_view climate_file = "climate.txt"; /* Parser stored so the filename string_views persist until the end of this function. */ const v2script::Parser parser = parse_defines(lookup_file(append_string_views(map_directory, defaults_filename))); @@ -720,7 +743,12 @@ bool Dataloader::_load_map_dir(GameManager& game_manager) const { return ret; } -bool Dataloader::load_defines(GameManager& game_manager) const { +bool Dataloader::load_defines(GameManager& game_manager) { + if (roots.empty()) { + Logger::error("Cannot load defines - Dataloader has no roots!"); + return false; + } + static constexpr std::string_view defines_file = "common/defines.lua"; static constexpr std::string_view buildings_file = "common/buildings.txt"; static constexpr std::string_view bookmark_file = "common/bookmarks.txt"; @@ -768,10 +796,6 @@ bool Dataloader::load_defines(GameManager& game_manager) const { Logger::error("Failed to load units!"); ret = false; } - if (!_load_pop_types(game_manager)) { - Logger::error("Failed to load pop types!"); - ret = false; - } if (!game_manager.get_pop_manager().get_culture_manager().load_graphical_culture_type_file( parse_defines(lookup_file(graphical_culture_type_file)).get_file_node() )) { @@ -791,7 +815,7 @@ bool Dataloader::load_defines(GameManager& game_manager) const { ret = false; } if (!game_manager.get_politics_manager().get_ideology_manager().load_ideology_file( - parse_defines(lookup_file(ideology_file)).get_file_node() + parse_defines_cached(lookup_file(ideology_file)).get_file_node() )) { Logger::error("Failed to load ideologies!"); ret = false; @@ -802,15 +826,25 @@ bool Dataloader::load_defines(GameManager& game_manager) const { Logger::error("Failed to load government types!"); ret = false; } + if (!_load_pop_types(game_manager)) { + Logger::error("Failed to load pop types!"); + ret = false; + } if (!game_manager.get_politics_manager().load_issues_file( game_manager.get_modifier_manager(), - parse_defines(lookup_file(issues_file)).get_file_node() + parse_defines_cached(lookup_file(issues_file)).get_file_node() + )) { + Logger::error("Failed to load issues and reforms!"); + ret = false; + } + if (!game_manager.get_pop_manager().load_delayed_parse_pop_type_data( + game_manager.get_politics_manager().get_issue_manager() )) { - Logger::error("Failed to load issues!"); + Logger::error("Failed to load delayed parse pop type data (promotion and issue weights)!"); ret = false; } if (!game_manager.get_economy_manager().load_production_types_file(game_manager.get_pop_manager(), - parse_defines(lookup_file(production_types_file)).get_file_node() + parse_defines_cached(lookup_file(production_types_file)).get_file_node() )) { Logger::error("Failed to load production types!"); ret = false; @@ -830,7 +864,7 @@ bool Dataloader::load_defines(GameManager& game_manager) const { } if (!game_manager.get_politics_manager().load_national_foci_file( game_manager.get_pop_manager(), game_manager.get_economy_manager().get_good_manager(), - game_manager.get_modifier_manager(), parse_defines(lookup_file(national_foci_file)).get_file_node() + game_manager.get_modifier_manager(), parse_defines_cached(lookup_file(national_foci_file)).get_file_node() )) { Logger::error("Failed to load national foci!"); ret = false; @@ -842,7 +876,7 @@ bool Dataloader::load_defines(GameManager& game_manager) const { ret = false; } if (!game_manager.get_crime_manager().load_crime_modifiers( - game_manager.get_modifier_manager(), parse_defines(lookup_file(crime_modifiers_file)).get_file_node() + game_manager.get_modifier_manager(), parse_defines_cached(lookup_file(crime_modifiers_file)).get_file_node() )) { Logger::error("Failed to load crime modifiers!"); ret = false; @@ -860,7 +894,7 @@ bool Dataloader::load_defines(GameManager& game_manager) const { ret = false; } if (!game_manager.get_modifier_manager().load_triggered_modifiers( - parse_defines(lookup_file(triggered_modifiers_file)).get_file_node() + parse_defines_cached(lookup_file(triggered_modifiers_file)).get_file_node() )) { Logger::error("Failed to load triggered modifiers!"); ret = false; @@ -879,8 +913,8 @@ bool Dataloader::load_defines(GameManager& game_manager) const { Logger::error("Failed to load leader traits!"); ret = false; } - if (!game_manager.get_military_manager().get_wargoal_manager().load_wargoal_file( - parse_defines(lookup_file(cb_types_file)).get_file_node() + if (!game_manager.get_military_manager().get_wargoal_type_manager().load_wargoal_file( + parse_defines_cached(lookup_file(cb_types_file)).get_file_node() )) { Logger::error("Failed to load wargoals!"); ret = false; @@ -920,6 +954,65 @@ bool Dataloader::load_defines(GameManager& game_manager) const { ret = false; } + parse_scripts(game_manager); + + free_cache(); + + return ret; +} + +bool Dataloader::parse_scripts(GameManager& game_manager) const { + bool ret = true; + + if (!game_manager.get_pop_manager().parse_scripts(game_manager)) { + Logger::error("Failed to parse pop scripts!"); + ret = false; + } + if (!game_manager.get_politics_manager().get_ideology_manager().parse_scripts(game_manager)) { + Logger::error("Failed to parse ideology scripts!"); + ret = false; + } + if (!game_manager.get_politics_manager().get_issue_manager().parse_scripts(game_manager)) { + Logger::error("Failed to parse reform scripts!"); + ret = false; + } + if (!game_manager.get_economy_manager().get_production_type_manager().parse_scripts(game_manager)) { + Logger::error("Failed to parse production type scripts!"); + ret = false; + } + if (!game_manager.get_politics_manager().get_rebel_manager().parse_scripts(game_manager)) { + Logger::error("Failed to parse rebel type scripts!"); + ret = false; + } + if (!game_manager.get_research_manager().get_technology_manager().parse_scripts(game_manager)) { + Logger::error("Failed to parse technology scripts!"); + ret = false; + } + if (!game_manager.get_crime_manager().parse_scripts(game_manager)) { + Logger::error("Failed to parse crime scripts!"); + ret = false; + } + if (!game_manager.get_modifier_manager().parse_scripts(game_manager)) { + Logger::error("Failed to parse triggered modifier scripts!"); + ret = false; + } + if (!game_manager.get_research_manager().get_invention_manager().parse_scripts(game_manager)) { + Logger::error("Failed to parse invention scripts!"); + ret = false; + } + if (!game_manager.get_military_manager().get_wargoal_type_manager().parse_scripts(game_manager)) { + Logger::error("Failed to parse wargoal type scripts!"); + ret = false; + } + if (!game_manager.get_decision_manager().parse_scripts(game_manager)) { + Logger::error("Failed to parse decision scripts!"); + ret = false; + } + if (!game_manager.get_event_manager().parse_scripts(game_manager)) { + Logger::error("Failed to parse event scripts!"); + ret = false; + } + return ret; } diff --git a/src/openvic-simulation/dataloader/Dataloader.hpp b/src/openvic-simulation/dataloader/Dataloader.hpp index 107c93a..069ccec 100644 --- a/src/openvic-simulation/dataloader/Dataloader.hpp +++ b/src/openvic-simulation/dataloader/Dataloader.hpp @@ -18,17 +18,18 @@ namespace OpenVic { private: path_vector_t roots; + std::vector<ovdl::v2script::Parser> cached_parsers; bool _load_interface_files(UIManager& ui_manager) const; - bool _load_pop_types(GameManager& game_manager) const; + bool _load_pop_types(GameManager& game_manager); bool _load_units(GameManager& game_manager) const; bool _load_goods(GameManager& game_manager) const; - bool _load_rebel_types(GameManager& game_manager) const; - bool _load_technologies(GameManager& game_manager) const; - bool _load_inventions(GameManager& game_manager) const; - bool _load_events(GameManager& game_manager) const; + bool _load_rebel_types(GameManager& game_manager); + bool _load_technologies(GameManager& game_manager); + bool _load_inventions(GameManager& game_manager); + bool _load_events(GameManager& game_manager); bool _load_map_dir(GameManager& game_manager) const; - bool _load_decisions(GameManager& game_manager) const; + bool _load_decisions(GameManager& game_manager); bool _load_history(GameManager& game_manager, bool unused_history_file_warnings) const; /* _DirIterator is fs::directory_iterator or fs::recursive_directory_iterator. _UniqueKey is the type of a callable @@ -47,6 +48,17 @@ namespace OpenVic { static ovdl::v2script::Parser parse_lua_defines(fs::path const& path); static ovdl::csv::Windows1252Parser parse_csv(fs::path const& path); + /* Cache the Parser so it won't be freed until free_cache is called. This is used to preserve condition and effect + * script Nodes until all defines are loaded and the scripts can be parsed. The reference returned by this function + * is only guaranteed to be valid until the function is next called. */ + ovdl::v2script::Parser& parse_defines_cached(fs::path const& path); + + private: + /* Clear the cache vector, freeing all cached Parsers and their Node trees. Pointers to cached Parsers' Nodes should + * be set to null before this is called to avoid segfaults. */ + void free_cache(); + + public: Dataloader() = default; /// @brief Searches for the Victoria 2 install directory @@ -92,8 +104,16 @@ namespace OpenVic { string_set_t lookup_dirs_in_dir(std::string_view path) const; - bool load_defines(GameManager& game_manager) const; + /* Load and parse all of the text defines data, including parsing cached condition and effect scripts after all the + * static data is loaded. Paths to the base and mod defines must have been supplied with set_roots.*/ + bool load_defines(GameManager& game_manager); + private: + /* Parse the cached Nodes of every condition and effect script in the defines. + * This is called by load_defines after all static data has been loaded. */ + bool parse_scripts(GameManager& game_manager) const; + + public: enum locale_t : size_t { English, French, German, Polish, Spanish, Italian, Swedish, Czech, Hungarian, Dutch, Portugese, Russian, Finnish, _LocaleCount diff --git a/src/openvic-simulation/dataloader/NodeTools.cpp b/src/openvic-simulation/dataloader/NodeTools.cpp index 1dbc99c..e429ed9 100644 --- a/src/openvic-simulation/dataloader/NodeTools.cpp +++ b/src/openvic-simulation/dataloader/NodeTools.cpp @@ -274,25 +274,42 @@ node_callback_t NodeTools::expect_length(callback_t<size_t> callback) { }; } -node_callback_t NodeTools::expect_key(std::string_view key, node_callback_t callback, bool* key_found) { - return _expect_type<ast::AbstractListNode>([key, callback, key_found](ast::AbstractListNode const& list_node) -> bool { - std::vector<ast::NodeUPtr> const& list = list_node._statements; - for (ast::NodeUPtr const& sub_node : list_node._statements) { - ast::AssignNode const* assign_node = sub_node->cast_to<ast::AssignNode>(); - if (assign_node != nullptr && assign_node->_name == key) { +node_callback_t NodeTools::expect_key(std::string_view key, node_callback_t callback, bool* key_found, bool allow_duplicates) { + return _expect_type<ast::AbstractListNode>( + [key, callback, key_found, allow_duplicates](ast::AbstractListNode const& list_node) -> bool { + bool ret = true; + size_t keys_found = 0; + std::vector<ast::NodeUPtr> const& list = list_node._statements; + for (ast::NodeUPtr const& sub_node : list_node._statements) { + ast::AssignNode const* assign_node = sub_node->cast_to<ast::AssignNode>(); + if (assign_node != nullptr && assign_node->_name == key) { + if (keys_found++ == 0) { + ret &= callback(&*assign_node->_initializer); + if (allow_duplicates) { + break; + } + } + } + } + if (keys_found == 0) { + if (key_found != nullptr) { + *key_found = false; + } else { + Logger::error("Failed to find expected key: \"", key, "\""); + } + ret = false; + } else { if (key_found != nullptr) { *key_found = true; } - return callback(&*assign_node->_initializer); + if (!allow_duplicates && keys_found > 1) { + Logger::error("Found ", keys_found, " instances of key: \"", key, "\" (expected 1)"); + ret = false; + } } + return ret; } - if (key_found != nullptr) { - *key_found = false; - } else { - Logger::error("Failed to find expected key: ", key); - } - return false; - }); + ); } node_callback_t NodeTools::expect_dictionary_and_length(length_callback_t length_callback, key_value_callback_t callback) { @@ -315,7 +332,7 @@ bool NodeTools::add_key_map_entry( } bool NodeTools::remove_key_map_entry(key_map_t& key_map, std::string_view key) { - if(key_map.erase(key) == 0) { + if (key_map.erase(key) == 0) { Logger::error("Failed to find dictionary key to remove: ", key); return false; } diff --git a/src/openvic-simulation/dataloader/NodeTools.hpp b/src/openvic-simulation/dataloader/NodeTools.hpp index f3224aa..f5f960f 100644 --- a/src/openvic-simulation/dataloader/NodeTools.hpp +++ b/src/openvic-simulation/dataloader/NodeTools.hpp @@ -1,11 +1,8 @@ #pragma once -#include <concepts> #include <cstdint> #include <functional> -#include <map> #include <optional> -#include <set> #include <type_traits> #include <openvic-dataloader/v2script/AbstractSyntaxTree.hpp> @@ -134,7 +131,9 @@ namespace OpenVic { node_callback_t expect_list(node_callback_t callback); node_callback_t expect_length(callback_t<size_t> callback); - node_callback_t expect_key(std::string_view key, node_callback_t callback, bool* key_found = nullptr); + node_callback_t expect_key( + std::string_view key, node_callback_t callback, bool* key_found = nullptr, bool allow_duplicates = false + ); node_callback_t expect_dictionary_and_length(length_callback_t length_callback, key_value_callback_t callback); node_callback_t expect_dictionary(key_value_callback_t callback); |