aboutsummaryrefslogtreecommitdiff
path: root/src/openvic-simulation/dataloader
diff options
context:
space:
mode:
Diffstat (limited to 'src/openvic-simulation/dataloader')
-rw-r--r--src/openvic-simulation/dataloader/Dataloader.cpp94
-rw-r--r--src/openvic-simulation/dataloader/Dataloader.hpp8
-rw-r--r--src/openvic-simulation/dataloader/NodeTools.cpp136
-rw-r--r--src/openvic-simulation/dataloader/NodeTools.hpp151
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;
};
}