diff options
Diffstat (limited to 'src/openvic-simulation/dataloader')
-rw-r--r-- | src/openvic-simulation/dataloader/Dataloader.cpp | 94 | ||||
-rw-r--r-- | src/openvic-simulation/dataloader/Dataloader.hpp | 8 | ||||
-rw-r--r-- | src/openvic-simulation/dataloader/NodeTools.cpp | 136 | ||||
-rw-r--r-- | src/openvic-simulation/dataloader/NodeTools.hpp | 151 |
4 files changed, 245 insertions, 144 deletions
diff --git a/src/openvic-simulation/dataloader/Dataloader.cpp b/src/openvic-simulation/dataloader/Dataloader.cpp index 70164c3..718218f 100644 --- a/src/openvic-simulation/dataloader/Dataloader.cpp +++ b/src/openvic-simulation/dataloader/Dataloader.cpp @@ -381,7 +381,10 @@ Dataloader::path_vector_t Dataloader::lookup_files_in_dir(fs::path const& path, 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)) { - ret &= callback(file); + if (!callback(file)) { + Logger::error("Callback failed for file: ", file); + ret = false; + } } return ret; } @@ -433,6 +436,14 @@ v2script::Parser Dataloader::parse_defines(fs::path const& path) { return _run_ovdl_parser<v2script::Parser, &_v2script_parse>(path); } +static bool _lua_parse(v2script::Parser& parser) { + return parser.lua_defines_parse(); +} + +static ovdl::v2script::Parser parse_lua_defines(fs::path const& path) { + return _run_ovdl_parser<v2script::Parser, &_lua_parse>(path); +} + static bool _csv_parse(csv::Windows1252Parser& parser) { return parser.parse_csv(); } @@ -441,12 +452,6 @@ csv::Windows1252Parser Dataloader::parse_csv(fs::path const& path) { return _run_ovdl_parser<csv::Windows1252Parser, &_csv_parse>(path); } -static callback_t<fs::path const&> _parse_defines_callback(node_callback_t callback) { - return [callback](fs::path const& path) -> bool { - return callback(Dataloader::parse_defines(path).get_file_node()); - }; -} - bool Dataloader::_load_pop_types(PopManager& pop_manager, fs::path const& pop_type_directory) const { const bool ret = apply_to_files_in_dir(pop_type_directory, ".txt", [&pop_manager](fs::path const& file) -> bool { @@ -457,13 +462,13 @@ bool Dataloader::_load_pop_types(PopManager& pop_manager, fs::path const& pop_ty return ret; } -bool Dataloader::_load_units(GameManager& game_manager, fs::path const& units_directory) const { +bool Dataloader::_load_units(UnitManager& unit_manager, GoodManager const& good_manager, fs::path const& units_directory) const { const bool ret = apply_to_files_in_dir(units_directory, ".txt", - [&game_manager](fs::path const& file) -> bool { - return game_manager.get_unit_manager().load_unit_file(game_manager.get_good_manager(), parse_defines(file).get_file_node()); + [&unit_manager, &good_manager](fs::path const& file) -> bool { + return unit_manager.load_unit_file(good_manager, parse_defines(file).get_file_node()); } ); - game_manager.get_unit_manager().lock_units(); + unit_manager.lock_units(); return ret; } @@ -499,15 +504,8 @@ bool Dataloader::_load_map_dir(GameManager& game_manager, fs::path const& map_di bool ret = expect_dictionary_keys( "max_provinces", ONE_EXACTLY, - expect_uint( - [&map](uint64_t val) -> bool { - if (Province::NULL_INDEX < val && val <= Province::MAX_INDEX) { - return map.set_max_provinces(val); - } - Logger::error("Invalid max province count ", val, " (out of valid range ", - Province::NULL_INDEX, " < max_provinces <= ", Province::MAX_INDEX, ")"); - return false; - } + expect_uint<Province::index_t>( + std::bind(&Map::set_max_provinces, &map, std::placeholders::_1) ), "sea_starts", ONE_EXACTLY, expect_list_reserve_length( @@ -537,17 +535,20 @@ bool Dataloader::_load_map_dir(GameManager& game_manager, fs::path const& map_di Logger::error("Failed to load map default file!"); } - if (!map.load_province_definitions(parse_csv(lookup_file(map_directory / definitions)).get_lines())) { + if (!map.load_province_definitions( + parse_csv(lookup_file(map_directory / definitions)).get_lines())) { Logger::error("Failed to load province definitions file!"); ret = false; } - if (!map.load_province_positions(game_manager.get_building_manager(), parse_defines(lookup_file(map_directory / positions)).get_file_node())) { + if (!map.load_province_positions( + game_manager.get_economy_manager().get_building_manager(), parse_defines(lookup_file(map_directory / positions)).get_file_node())) { Logger::error("Failed to load province positions file!"); ret = false; } - if (!map.load_region_file(parse_defines(lookup_file(map_directory / region)).get_file_node())) { + if (!map.load_region_file( + parse_defines(lookup_file(map_directory / region)).get_file_node())) { Logger::error("Failed to load region file!"); ret = false; } @@ -556,19 +557,23 @@ bool Dataloader::_load_map_dir(GameManager& game_manager, fs::path const& map_di Logger::error("Failed to set water provinces!"); ret = false; } - map.lock_water_provinces(); - if (!map.get_terrain_type_manager().load_terrain_types(game_manager.get_modifier_manager(), parse_defines(lookup_file(map_directory / terrain_definition)).get_file_node())) { + if (!map.get_terrain_type_manager().load_terrain_types( + game_manager.get_modifier_manager(), + parse_defines(lookup_file(map_directory / terrain_definition)).get_file_node())) { Logger::error("Failed to load terrain types!"); ret = false; } - if (!map.load_map_images(lookup_file(map_directory / provinces), lookup_file(map_directory / terrain), false)) { + if (!map.load_map_images( + lookup_file(map_directory / provinces), + lookup_file(map_directory / terrain), false)) { Logger::error("Failed to load map images!"); ret = false; } - if (!map.generate_and_load_province_adjacencies(parse_csv(lookup_file(map_directory / adjacencies)).get_lines())) { + if (!map.generate_and_load_province_adjacencies( + parse_csv(lookup_file(map_directory / adjacencies)).get_lines())) { Logger::error("Failed to generate and load province adjacencies!"); ret = false; } @@ -597,7 +602,8 @@ bool Dataloader::load_defines(GameManager& game_manager) const { Logger::error("Failed to set up modifier effects!"); ret = false; } - if (!game_manager.get_good_manager().load_goods_file(parse_defines(lookup_file(goods_file)).get_file_node())) { + if (!game_manager.get_economy_manager().get_good_manager().load_goods_file( + parse_defines(lookup_file(goods_file)).get_file_node())) { Logger::error("Failed to load goods!"); ret = false; } @@ -605,40 +611,43 @@ bool Dataloader::load_defines(GameManager& game_manager) const { 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())) { + 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())) { Logger::error("Failed to load graphical culture types!"); ret = false; } - if (!game_manager.get_pop_manager().get_culture_manager().load_culture_file(parse_defines(lookup_file(culture_file)).get_file_node())) { + if (!game_manager.get_pop_manager().get_culture_manager().load_culture_file( + parse_defines(lookup_file(culture_file)).get_file_node())) { Logger::error("Failed to load cultures!"); ret = false; } - if (!game_manager.get_pop_manager().get_religion_manager().load_religion_file(parse_defines(lookup_file(religion_file)).get_file_node())) { + if (!game_manager.get_pop_manager().get_religion_manager().load_religion_file( + parse_defines(lookup_file(religion_file)).get_file_node())) { Logger::error("Failed to load religions!"); ret = false; } - if (!game_manager.get_ideology_manager().load_ideology_file(parse_defines(lookup_file(ideology_file)).get_file_node())) { + if (!game_manager.get_politics_manager().get_ideology_manager().load_ideology_file( + parse_defines(lookup_file(ideology_file)).get_file_node())) { Logger::error("Failed to load ideologies!"); ret = false; } - if (!game_manager.get_government_type_manager().load_government_types_file(game_manager.get_ideology_manager(), parse_defines(lookup_file(governments_file)).get_file_node())) { + if (!game_manager.get_politics_manager().load_government_types_file( + parse_defines(lookup_file(governments_file)).get_file_node())) { Logger::error("Failed to load government types!"); ret = false; } - if (!game_manager.get_issue_manager().load_issues_file(parse_defines(lookup_file(issues_file)).get_file_node())) { + if (!game_manager.get_politics_manager().get_issue_manager().load_issues_file( + parse_defines(lookup_file(issues_file)).get_file_node())) { Logger::error("Failed to load issues!"); ret = false; } - if (!game_manager.get_production_type_manager().load_production_types_file( - game_manager.get_good_manager(), + 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())) { Logger::error("Failed to load production types!"); ret = false; } - if (!game_manager.get_building_manager().load_buildings_file( - game_manager.get_good_manager(), - game_manager.get_production_type_manager(), + if (!game_manager.get_economy_manager().load_buildings_file( game_manager.get_modifier_manager(), parse_defines(lookup_file(buildings_file)).get_file_node())) { Logger::error("Failed to load buildings!"); @@ -648,7 +657,8 @@ bool Dataloader::load_defines(GameManager& game_manager) const { Logger::error("Failed to load map!"); ret = false; } - if (!_load_units(game_manager, units_directory)) { + if (!_load_units(game_manager.get_military_manager().get_unit_manager(), + game_manager.get_economy_manager().get_good_manager(), units_directory)) { Logger::error("Failed to load units!"); ret = false; } @@ -659,11 +669,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 _parse_defines_callback(game_manager.get_map().expect_province_dictionary( + 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); } - ))(file); + )(parse_defines(file).get_file_node()); } ); } diff --git a/src/openvic-simulation/dataloader/Dataloader.hpp b/src/openvic-simulation/dataloader/Dataloader.hpp index 705da00..c4cd7c7 100644 --- a/src/openvic-simulation/dataloader/Dataloader.hpp +++ b/src/openvic-simulation/dataloader/Dataloader.hpp @@ -13,7 +13,8 @@ namespace OpenVic { struct GameManager; struct PopManager; - struct Map; + struct UnitManager; + struct GoodManager; class Dataloader { public: @@ -23,11 +24,12 @@ namespace OpenVic { path_vector_t roots; bool _load_pop_types(PopManager& pop_manager, fs::path const& pop_type_directory) const; - bool _load_units(GameManager& unit_manager, fs::path const& units_directory) const; + bool _load_units(UnitManager& unit_manager, GoodManager const& good_manager, fs::path const& units_directory) const; bool _load_map_dir(GameManager& game_manager, fs::path const& map_directory) const; public: static ovdl::v2script::Parser parse_defines(fs::path const& path); + static ovdl::v2script::Parser parse_lua_defines(fs::path const& path); static ovdl::csv::Windows1252Parser parse_csv(fs::path const& path); Dataloader() = default; @@ -89,5 +91,3 @@ namespace OpenVic { inline static std::unordered_map<hint_path_t, game_path_t, fshash> _cached_paths; }; } - - diff --git a/src/openvic-simulation/dataloader/NodeTools.cpp b/src/openvic-simulation/dataloader/NodeTools.cpp index 5ef09d1..391ffb6 100644 --- a/src/openvic-simulation/dataloader/NodeTools.cpp +++ b/src/openvic-simulation/dataloader/NodeTools.cpp @@ -19,20 +19,28 @@ static node_callback_t _expect_type(callback_t<T const&> callback) { }; } -template<typename T> -requires(std::derived_from<T, ast::AbstractStringNode>) -static callback_t<T const&> _abstract_string_node_callback(callback_t<std::string_view> callback) { - return [callback](T const& node) -> bool { - return callback(node._name); +template<std::derived_from<ast::AbstractStringNode> T> +static callback_t<T const&> _abstract_string_node_callback(callback_t<std::string_view> callback, bool allow_empty) { + return [callback, allow_empty](T const& node) -> bool { + if (allow_empty) { + return callback(node._name); + } else { + if (!node._name.empty()) { + return callback(node._name); + } else { + Logger::error("Invalid string value - empty!"); + return false; + } + } }; } node_callback_t NodeTools::expect_identifier(callback_t<std::string_view> callback) { - return _expect_type<ast::IdentifierNode>(_abstract_string_node_callback<ast::IdentifierNode>(callback)); + return _expect_type<ast::IdentifierNode>(_abstract_string_node_callback<ast::IdentifierNode>(callback, false)); } -node_callback_t NodeTools::expect_string(callback_t<std::string_view> callback) { - return _expect_type<ast::StringNode>(_abstract_string_node_callback<ast::StringNode>(callback)); +node_callback_t NodeTools::expect_string(callback_t<std::string_view> callback, bool allow_empty) { + return _expect_type<ast::StringNode>(_abstract_string_node_callback<ast::StringNode>(callback, allow_empty)); } node_callback_t NodeTools::expect_identifier_or_string(callback_t<std::string_view> callback) { @@ -43,7 +51,7 @@ node_callback_t NodeTools::expect_identifier_or_string(callback_t<std::string_vi cast_node = node->cast_to<ast::StringNode>(); } if (cast_node != nullptr) { - return _abstract_string_node_callback<ast::AbstractStringNode>(callback)(*cast_node); + return _abstract_string_node_callback<ast::AbstractStringNode>(callback, false)(*cast_node); } Logger::error("Invalid node type ", node->get_type(), " when expecting ", ast::IdentifierNode::get_type_static(), " or ", ast::StringNode::get_type_static()); } else { @@ -54,20 +62,20 @@ node_callback_t NodeTools::expect_identifier_or_string(callback_t<std::string_vi } node_callback_t NodeTools::expect_bool(callback_t<bool> callback) { - return expect_identifier( - [callback](std::string_view identifier) -> bool { - if (identifier == "yes") { - return callback(true); - } else if (identifier == "no") { - return callback(false); - } - Logger::error("Invalid bool identifier text: ", identifier); - return false; - } - ); + static const string_map_t<bool> bool_map = { + { "yes", true }, { "no", false } + }; + return expect_identifier(expect_mapped_string(bool_map, callback)); +} + +node_callback_t NodeTools::expect_int_bool(callback_t<bool> callback) { + static const string_map_t<bool> bool_map = { + { "1", true }, { "0", false } + }; + return expect_identifier(expect_mapped_string(bool_map, callback)); } -node_callback_t NodeTools::expect_int(callback_t<int64_t> callback) { +node_callback_t NodeTools::expect_int64(callback_t<int64_t> callback) { return expect_identifier( [callback](std::string_view identifier) -> bool { bool successful = false; @@ -81,7 +89,7 @@ node_callback_t NodeTools::expect_int(callback_t<int64_t> callback) { ); } -node_callback_t NodeTools::expect_uint(callback_t<uint64_t> callback) { +node_callback_t NodeTools::expect_uint64(callback_t<uint64_t> callback) { return expect_identifier( [callback](std::string_view identifier) -> bool { bool successful = false; @@ -134,10 +142,6 @@ node_callback_t NodeTools::expect_colour(callback_t<colour_t> callback) { }; } -node_callback_t NodeTools::expect_timespan(callback_t<Timespan> callback) { - return expect_int(callback); -} - node_callback_t NodeTools::expect_date(callback_t<Date> callback) { return expect_identifier( [callback](std::string_view identifier) -> bool { @@ -152,6 +156,24 @@ node_callback_t NodeTools::expect_date(callback_t<Date> callback) { ); } +node_callback_t NodeTools::expect_years(callback_t<Timespan> callback) { + return expect_uint<Timespan::day_t>([callback](Timespan::day_t val) -> bool { + return callback(Timespan::fromYears(val)); + }); +} + +node_callback_t NodeTools::expect_months(callback_t<Timespan> callback) { + return expect_uint<Timespan::day_t>([callback](Timespan::day_t val) -> bool { + return callback(Timespan::fromMonths(val)); + }); +} + +node_callback_t NodeTools::expect_days(callback_t<Timespan> callback) { + return expect_uint<Timespan::day_t>([callback](Timespan::day_t val) -> bool { + return callback(Timespan::fromDays(val)); + }); +} + template<typename T, node_callback_t (*expect_func)(callback_t<T>)> node_callback_t _expect_vec2(callback_t<vec2_t<T>> callback) { return [callback](ast::NodeCPtr node) -> bool { @@ -166,7 +188,7 @@ node_callback_t _expect_vec2(callback_t<vec2_t<T>> callback) { } node_callback_t NodeTools::expect_ivec2(callback_t<ivec2_t> callback) { - return _expect_vec2<int64_t, expect_int>(callback); + return _expect_vec2<int32_t, expect_int>(callback); } node_callback_t NodeTools::expect_fvec2(callback_t<fvec2_t> callback) { @@ -238,17 +260,24 @@ 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) { +node_callback_t NodeTools::expect_key(std::string_view key, node_callback_t callback, bool* key_found) { return _expect_type<ast::AbstractListNode>( - [key, callback](ast::AbstractListNode const& list_node) -> bool { + [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) { + if (key_found != nullptr) { + *key_found = true; + } return callback(&*assign_node->_initializer); } } - Logger::error("Failed to find expected key: ", key); + if (key_found != nullptr) { + *key_found = false; + } else { + Logger::error("Failed to find expected key: ", key); + } return false; } ); @@ -262,21 +291,30 @@ node_callback_t NodeTools::expect_dictionary(key_value_callback_t callback) { return expect_dictionary_and_length(default_length_callback, callback); } -void 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) { +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()) { key_map.emplace(key, dictionary_entry_t { expected_count, callback }); - } else { - Logger::error("Duplicate expected dictionary key: ", key); + return true; + } + Logger::error("Duplicate expected dictionary key: ", key); + return false; +} + +bool NodeTools::remove_key_map_entry(key_map_t& key_map, std::string_view key) { + const key_map_t::const_iterator it = key_map.find(key); + if (it != key_map.end()) { + key_map.erase(it); + return true; } + Logger::error("Failed to find dictionary key to remove: ", key); + return false; } -key_value_callback_t NodeTools::dictionary_keys_callback(key_map_t& key_map, bool allow_other_keys) { - return [&key_map, allow_other_keys](std::string_view key, ast::NodeCPtr value) -> bool { +key_value_callback_t NodeTools::dictionary_keys_callback(key_map_t& key_map, key_value_callback_t default_callback) { + return [&key_map, default_callback](std::string_view key, ast::NodeCPtr value) -> bool { const key_map_t::iterator it = key_map.find(key); if (it == key_map.end()) { - if (allow_other_keys) return true; - Logger::error("Invalid dictionary key: ", key); - return false; + return default_callback(key, value); } dictionary_entry_t& entry = it->second; if (++entry.count > 1 && !entry.can_repeat()) { @@ -300,16 +338,28 @@ bool NodeTools::check_key_map_counts(key_map_t& key_map) { return ret; } -node_callback_t NodeTools::_expect_dictionary_keys_and_length(length_callback_t length_callback, bool allow_other_keys, key_map_t&& key_map) { - return [length_callback, allow_other_keys, key_map = std::move(key_map)](ast::NodeCPtr node) mutable -> bool { +node_callback_t NodeTools::expect_dictionary_key_map_and_length_and_default(key_map_t key_map, length_callback_t length_callback, key_value_callback_t default_callback) { + return [length_callback, default_callback, key_map = std::move(key_map)](ast::NodeCPtr node) mutable -> bool { bool ret = expect_dictionary_and_length( - length_callback, dictionary_keys_callback(key_map, allow_other_keys) + length_callback, dictionary_keys_callback(key_map, default_callback) )(node); ret &= check_key_map_counts(key_map); return ret; }; } +node_callback_t NodeTools::expect_dictionary_key_map_and_length(key_map_t key_map, length_callback_t length_callback) { + return expect_dictionary_key_map_and_length_and_default(std::move(key_map), length_callback, key_value_invalid_callback); +} + +node_callback_t NodeTools::expect_dictionary_key_map_and_default(key_map_t key_map, key_value_callback_t default_callback) { + return expect_dictionary_key_map_and_length_and_default(std::move(key_map), default_length_callback, default_callback); +} + +node_callback_t NodeTools::expect_dictionary_key_map(key_map_t key_map) { + return expect_dictionary_key_map_and_length_and_default(std::move(key_map), default_length_callback, key_value_invalid_callback); +} + node_callback_t NodeTools::name_list_callback(std::vector<std::string>& list) { return expect_list_reserve_length( list, @@ -325,3 +375,7 @@ node_callback_t NodeTools::name_list_callback(std::vector<std::string>& list) { ) ); } + +callback_t<std::string_view> NodeTools::assign_variable_callback_string(std::string& var) { + return assign_variable_callback_cast<std::string_view>(var); +} diff --git a/src/openvic-simulation/dataloader/NodeTools.hpp b/src/openvic-simulation/dataloader/NodeTools.hpp index 5ba9d63..44ac271 100644 --- a/src/openvic-simulation/dataloader/NodeTools.hpp +++ b/src/openvic-simulation/dataloader/NodeTools.hpp @@ -11,6 +11,11 @@ namespace OpenVic { namespace ast = ovdl::v2script::ast; + /* Template for map from strings to Ts, in which string_views can be + * searched for without needing to be copied into a string, */ + template<typename T> + using string_map_t = std::map<std::string, T, std::less<void>>; + namespace NodeTools { template<typename... Args> @@ -21,17 +26,55 @@ namespace OpenVic { using key_value_callback_t = callback_t<std::string_view, ast::NodeCPtr>; constexpr bool key_value_success_callback(std::string_view, ast::NodeCPtr) { return true; } + inline bool key_value_invalid_callback(std::string_view key, ast::NodeCPtr) { + Logger::error("Invalid dictionary key: ", key); + return false; + } node_callback_t expect_identifier(callback_t<std::string_view> callback); - node_callback_t expect_string(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_identifier_or_string(callback_t<std::string_view> callback); + node_callback_t expect_bool(callback_t<bool> callback); - node_callback_t expect_int(callback_t<int64_t> callback); - node_callback_t expect_uint(callback_t<uint64_t> callback); + node_callback_t expect_int_bool(callback_t<bool> callback); + + node_callback_t expect_int64(callback_t<int64_t> callback); + node_callback_t expect_uint64(callback_t<uint64_t> callback); + + template<std::signed_integral T> + node_callback_t expect_int(callback_t<T> callback) { + return expect_int64([callback](int64_t val) -> bool { + if (static_cast<int64_t>(std::numeric_limits<T>::lowest()) <= val && + val <= static_cast<int64_t>(std::numeric_limits<T>::max())) { + return callback(val); + } + Logger::error("Invalid int: ", val, " (valid range: [", + static_cast<int64_t>(std::numeric_limits<T>::lowest()), ", ", + static_cast<int64_t>(std::numeric_limits<T>::max()), "])"); + return false; + }); + } + + template<std::integral T> + node_callback_t expect_uint(callback_t<T> callback) { + return expect_uint64([callback](uint64_t val) -> bool { + if (val <= static_cast<uint64_t>(std::numeric_limits<T>::max())) { + return callback(val); + } + Logger::error("Invalid uint: ", val, " (valid range: [0, ", + static_cast<uint64_t>(std::numeric_limits<T>::max()), "])"); + return false; + }); + } + node_callback_t expect_fixed_point(callback_t<fixed_point_t> callback); node_callback_t expect_colour(callback_t<colour_t> callback); - node_callback_t expect_timespan(callback_t<Timespan> callback); + node_callback_t expect_date(callback_t<Date> callback); + node_callback_t expect_years(callback_t<Timespan> callback); + node_callback_t expect_months(callback_t<Timespan> callback); + node_callback_t expect_days(callback_t<Timespan> callback); + node_callback_t expect_ivec2(callback_t<ivec2_t> callback); node_callback_t expect_fvec2(callback_t<fvec2_t> callback); node_callback_t expect_assign(key_value_callback_t callback); @@ -44,7 +87,7 @@ 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); + node_callback_t expect_key(std::string_view key, node_callback_t callback, bool* key_found = nullptr); 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); @@ -73,41 +116,45 @@ namespace OpenVic { } }; using enum dictionary_entry_t::expected_count_t; - using key_map_t = std::map<std::string, dictionary_entry_t, std::less<void>>; + using key_map_t = string_map_t<dictionary_entry_t>; - void 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); - key_value_callback_t dictionary_keys_callback(key_map_t& key_map, bool allow_other_keys); + bool 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); + bool remove_key_map_entry(key_map_t& key_map, std::string_view key); + key_value_callback_t dictionary_keys_callback(key_map_t& key_map, key_value_callback_t default_callback); bool check_key_map_counts(key_map_t& key_map); - constexpr struct allow_other_keys_t {} ALLOW_OTHER_KEYS; - - node_callback_t _expect_dictionary_keys_and_length(length_callback_t length_callback, bool allow_other_keys, key_map_t&& key_map); + node_callback_t expect_dictionary_key_map_and_length_and_default(key_map_t key_map, length_callback_t length_callback, key_value_callback_t default_callback); + node_callback_t expect_dictionary_key_map_and_length(key_map_t key_map, length_callback_t length_callback); + node_callback_t expect_dictionary_key_map_and_default(key_map_t key_map, key_value_callback_t default_callback); + node_callback_t expect_dictionary_key_map(key_map_t key_map); template<typename... Args> - node_callback_t _expect_dictionary_keys_and_length(length_callback_t length_callback, - bool allow_other_keys, key_map_t&& key_map, + node_callback_t expect_dictionary_key_map_and_length_and_default(key_map_t key_map, length_callback_t length_callback, key_value_callback_t default_callback, std::string_view key, dictionary_entry_t::expected_count_t expected_count, node_callback_t callback, Args... args) { + // TODO - pass return value back up (part of big key_map_t rewrite?) add_key_map_entry(key_map, key, expected_count, callback); - return _expect_dictionary_keys_and_length(length_callback, allow_other_keys, std::move(key_map), args...); + return expect_dictionary_key_map_and_length_and_default(std::move(key_map), length_callback, default_callback, args...); } template<typename... Args> - node_callback_t expect_dictionary_keys_and_length(length_callback_t length_callback, - std::string_view key, dictionary_entry_t::expected_count_t expected_count, node_callback_t callback, - Args... args) { - return _expect_dictionary_keys_and_length(length_callback, false, {}, key, expected_count, callback, args...); + node_callback_t expect_dictionary_keys_and_length_and_default(length_callback_t length_callback, key_value_callback_t default_callback, Args... args) { + return expect_dictionary_key_map_and_length_and_default({}, length_callback, default_callback, args...); } template<typename... Args> - node_callback_t expect_dictionary_keys_and_length(length_callback_t length_callback, - allow_other_keys_t, Args... args) { - return _expect_dictionary_keys_and_length(length_callback, true, {}, args...); + node_callback_t expect_dictionary_keys_and_length(length_callback_t length_callback, Args... args) { + return expect_dictionary_key_map_and_length_and_default({}, length_callback, key_value_invalid_callback, args...); + } + + template<typename... Args> + node_callback_t expect_dictionary_keys_and_default(key_value_callback_t default_callback, Args... args) { + return expect_dictionary_key_map_and_length_and_default({}, default_length_callback, default_callback, args...); } template<typename... Args> node_callback_t expect_dictionary_keys(Args... args) { - return expect_dictionary_keys_and_length(default_length_callback, args...); + return expect_dictionary_key_map_and_length_and_default({}, default_length_callback, key_value_invalid_callback, args...); } template<typename T> @@ -133,7 +180,19 @@ namespace OpenVic { node_callback_t name_list_callback(std::vector<std::string>& list); template<typename T> - callback_t<T> assign_variable_callback(T& var) { + callback_t<std::string_view> expect_mapped_string(string_map_t<T> const& map, callback_t<T> callback) { + return [&map, callback](std::string_view string) -> bool { + const typename string_map_t<T>::const_iterator it = map.find(string); + if (it != map.end()) { + return callback(it->second); + } + Logger::error("String not found in map: ", string); + return false; + }; + } + + template<typename T, typename U> + callback_t<T> assign_variable_callback_cast(U& var) { return [&var](T val) -> bool { var = val; return true; @@ -141,6 +200,13 @@ namespace OpenVic { } template<typename T> + callback_t<T> assign_variable_callback(T& var) { + return assign_variable_callback_cast<T, T>(var); + } + + callback_t<std::string_view> assign_variable_callback_string(std::string& var); + + template<typename T> callback_t<T&&> move_variable_callback(T& var) { return [&var](T&& val) -> bool { var = std::move(val); @@ -161,41 +227,12 @@ namespace OpenVic { template<typename T> requires requires(T& t) { - t--; - } - node_callback_t decrement_callback(T& var, node_callback_t callback) { - return [&var, callback](ast::NodeCPtr node) -> bool { - var--; - return callback(node); - }; - } - - template<typename T> - requires(std::integral<T>) - callback_t<uint64_t> assign_variable_callback_uint(T& var) { - return [&var](uint64_t val) -> bool { - if (val <= static_cast<uint64_t>(std::numeric_limits<T>::max())) { - var = val; - return true; - } - Logger::error("Invalid uint: ", val, " (valid range: [0, ", - static_cast<uint64_t>(std::numeric_limits<T>::max()), "])"); - return false; - }; + t++; } - - template<typename T> - requires(std::signed_integral<T>) - callback_t<int64_t> assign_variable_callback_int(T& var) { - return [&var](int64_t val) -> bool { - if (static_cast<int64_t>(std::numeric_limits<T>::lowest()) <= val && val <= static_cast<int64_t>(std::numeric_limits<T>::max())) { - var = val; - return true; - } - Logger::error("Invalid int: ", val, " (valid range: [", - static_cast<int64_t>(std::numeric_limits<T>::lowest()), ", ", - static_cast<int64_t>(std::numeric_limits<T>::max()), "])"); - return false; + key_value_callback_t increment_callback(T& var) { + return [&var](std::string_view, ast::NodeCPtr) -> bool { + var++; + return true; }; } |