diff options
author | zaaarf <zaaarf@proton.me> | 2023-09-24 19:38:54 +0200 |
---|---|---|
committer | zaaarf <zaaarf@proton.me> | 2023-09-24 19:38:54 +0200 |
commit | eb425a600c03ca02d922a1b20a2815a57104f3cc (patch) | |
tree | 12d44479a568ece48286b67d6a0d2940495b445e /src | |
parent | febd529195df8ef881d01b2ad787e54978728ff4 (diff) |
fix: fixed segfault, added ulterior checks)
Diffstat (limited to 'src')
-rw-r--r-- | src/openvic-simulation/economy/ProductionType.cpp | 66 | ||||
-rw-r--r-- | src/openvic-simulation/economy/ProductionType.hpp | 10 |
2 files changed, 50 insertions, 26 deletions
diff --git a/src/openvic-simulation/economy/ProductionType.cpp b/src/openvic-simulation/economy/ProductionType.cpp index eae1311..4ea7967 100644 --- a/src/openvic-simulation/economy/ProductionType.cpp +++ b/src/openvic-simulation/economy/ProductionType.cpp @@ -8,13 +8,17 @@ using namespace OpenVic; using namespace OpenVic::NodeTools; -EmployedPop::EmployedPop(PopType const* pop_type, effect_t effect, fixed_point_t effect_multiplier, fixed_point_t amount) - : pop_type { pop_type }, effect { effect }, effect_multiplier { effect_multiplier }, amount { amount } {} +EmployedPop::EmployedPop(PopType const* pop_type, bool artisan, effect_t effect, fixed_point_t effect_multiplier, fixed_point_t amount) + : pop_type { pop_type }, artisan { artisan }, effect { effect }, effect_multiplier { effect_multiplier }, amount { amount } {} PopType const* EmployedPop::get_pop_type() { return pop_type; } +bool EmployedPop::is_artisan() { + return artisan; +} + EmployedPop::effect_t EmployedPop::get_effect() { return effect; } @@ -43,7 +47,7 @@ ProductionType::type_t ProductionType::get_type() const { return type; } -uint32_t ProductionType::get_workforce() const { +size_t ProductionType::get_workforce() const { return workforce; } @@ -84,7 +88,7 @@ ProductionTypeManager::ProductionTypeManager() : production_types { "production node_callback_t ProductionTypeManager::_expect_employed_pop(GoodManager& good_manager, PopManager& pop_manager, callback_t<EmployedPop> cb) { - return [this, &good_manager, &pop_manager, &cb](ast::NodeCPtr node) -> bool { + return [this, &good_manager, &pop_manager, cb](ast::NodeCPtr node) -> bool { std::string_view pop_type, effect; fixed_point_t effect_multiplier = 1, amount = 1; @@ -96,9 +100,14 @@ node_callback_t ProductionTypeManager::_expect_employed_pop(GoodManager& good_ma )(node); const PopType* found_pop_type = pop_manager.get_pop_type_by_identifier(pop_type); + bool artisan = false; if (found_pop_type == nullptr) { - Logger::error("Found invalid pop type ", pop_type, " while parsing production types!"); - return false; + if (pop_type == "artisan") { + artisan = true; + } else { + Logger::error("Found invalid pop type ", pop_type, " while parsing production types!"); + return false; + } } EmployedPop::effect_t found_effect; @@ -110,26 +119,31 @@ node_callback_t ProductionTypeManager::_expect_employed_pop(GoodManager& good_ma return false; } - return res & cb(EmployedPop { found_pop_type, found_effect, effect_multiplier, amount }); + return res & cb(EmployedPop { found_pop_type, artisan, found_effect, effect_multiplier, amount }); }; } node_callback_t ProductionTypeManager::_expect_employed_pop_list(GoodManager& good_manager, PopManager& pop_manager, callback_t<std::vector<EmployedPop>> cb) { - return [this, &good_manager, &pop_manager, &cb](ast::NodeCPtr node) -> bool { + return [this, &good_manager, &pop_manager, cb](ast::NodeCPtr node) -> bool { std::vector<EmployedPop> employed_pops; bool res = expect_list([this, &good_manager, &pop_manager, &employed_pops](ast::NodeCPtr node) -> bool { - EmployedPop* owner = nullptr; - bool res_partial = _expect_employed_pop(good_manager, pop_manager, assign_variable_callback(*owner))(node); - if (owner != nullptr) - employed_pops.push_back(*owner); + EmployedPop owner; + bool res_partial = _expect_employed_pop(good_manager, pop_manager, assign_variable_callback(owner))(node); + employed_pops.push_back(owner); return res_partial; })(node); return res & cb(employed_pops); }; } +#define POPTYPE_CHECK(employed_pop) \ + if ((employed_pop.pop_type == nullptr && !employed_pop.artisan) || (employed_pop.pop_type != nullptr && employed_pop.artisan)) {\ + Logger::error("Invalid pop type parsed for owner of production type ", identifier, "!"); \ + return false; \ + } + bool ProductionTypeManager::add_production_type(ARGS(std::string_view, std::string_view), GoodManager& good_manager) { if (identifier.empty()) { Logger::error("Invalid production type identifier - empty!"); @@ -145,6 +159,22 @@ bool ProductionTypeManager::add_production_type(ARGS(std::string_view, std::stri return false; } + if (workforce == 0) { + Logger::error("Workforce for production type ", identifier, " was 0 or unset!"); + return false; + } + + if (value == 0) { + Logger::error("Value for production type ", identifier, " was 0 or unset!"); + return false; + } + + POPTYPE_CHECK(owner) + + for (int i = 0; i < employees.size(); i++) { + POPTYPE_CHECK(employees[i]) + } + const Good* output = good_manager.get_good_by_identifier(output_goods); if (output == nullptr) { Logger::error("Invalid output ", output_goods, " for production type ", identifier, "!"); @@ -157,13 +187,6 @@ bool ProductionTypeManager::add_production_type(ARGS(std::string_view, std::stri }); } -/* TODO check that these are valid and set -"owner", ONE_EXACTLY, _expect_employed_pop(good_manager, pop_manager, move_variable_callback(owner)), -"workforce", ONE_EXACTLY, expect_uint(assign_variable_callback(workforce)), -"output_goods", ONE_EXACTLY, expect_identifier(assign_variable_callback(output_goods)), -"value", ONE_EXACTLY, expect_fixed_point(assign_variable_callback(value)), -*/ - #define PARSE_NODE(target_node) expect_dictionary_keys(ALLOW_OTHER_KEYS, \ "owner", ZERO_OR_ONE, _expect_employed_pop(good_manager, pop_manager, move_variable_callback(owner)), \ "employees", ZERO_OR_ONE, _expect_employed_pop_list(good_manager, pop_manager, move_variable_callback(employees)), \ @@ -224,9 +247,9 @@ bool ProductionTypeManager::load_production_types_file(GoodManager& good_manager EmployedPop owner; std::vector<EmployedPop> employees; std::string_view type, output_goods; - uint32_t workforce; + size_t workforce = 0; //0 is a meaningless value -> unset std::map<const Good*, fixed_point_t> input_goods, efficiency; - fixed_point_t value; + fixed_point_t value = 0; //0 is a meaningless value -> unset std::vector<Bonus> bonuses; bool coastal = false, farm = false, mine = false; @@ -237,7 +260,6 @@ bool ProductionTypeManager::load_production_types_file(GoodManager& good_manager std::string_view template_id = template_target_map[key]; if (template_node_map.contains(template_id)) { ast::NodeCPtr template_node = template_node_map[template_id]; - Logger::info("Applying template ", template_id," to ", key); //TODO temp, remove once it works ret &= PARSE_NODE(template_node); } } diff --git a/src/openvic-simulation/economy/ProductionType.hpp b/src/openvic-simulation/economy/ProductionType.hpp index 2d0586c..1e715d8 100644 --- a/src/openvic-simulation/economy/ProductionType.hpp +++ b/src/openvic-simulation/economy/ProductionType.hpp @@ -11,7 +11,7 @@ #include "openvic-dataloader/v2script/AbstractSyntaxTree.hpp" #define ARGS(enum_type, output) std::string_view identifier, EmployedPop owner, std::vector<EmployedPop> employees, enum_type type, \ - uint32_t workforce, std::map<const Good*, fixed_point_t> input_goods, output output_goods, \ + size_t workforce, std::map<const Good*, fixed_point_t> input_goods, output output_goods, \ fixed_point_t value, std::vector<Bonus> bonuses, std::map<const Good*, fixed_point_t> efficiency, \ bool coastal, bool farm, bool mine @@ -23,6 +23,7 @@ namespace OpenVic { private: PopType const* pop_type; //poptype + bool artisan; //set by the parser if the magic "artisan" poptype is passed enum struct effect_t { INPUT, OUTPUT, @@ -31,12 +32,13 @@ namespace OpenVic { fixed_point_t effect_multiplier; fixed_point_t amount; - EmployedPop(PopType const* pop_type, effect_t effect, fixed_point_t effect_multiplier, fixed_point_t amount); + EmployedPop(PopType const* pop_type, bool artisan, effect_t effect, fixed_point_t effect_multiplier, fixed_point_t amount); public: EmployedPop() = default; PopType const* get_pop_type(); + bool is_artisan(); effect_t get_effect(); fixed_point_t get_effect_multiplier(); fixed_point_t get_amount(); @@ -58,7 +60,7 @@ namespace OpenVic { RGO, ARTISAN } type; - const uint32_t workforce; + const size_t workforce; const std::map<const Good*, fixed_point_t> input_goods; //farms generally lack this const Good* output_goods; @@ -79,7 +81,7 @@ namespace OpenVic { EmployedPop const& get_owner() const; std::vector<EmployedPop> const& get_employees() const; type_t get_type() const; - uint32_t get_workforce() const; + size_t get_workforce() const; std::map<const Good*, fixed_point_t> const& get_input_goods(); const Good* get_output_goods() const; |