aboutsummaryrefslogtreecommitdiff
path: root/src/openvic-simulation/scripts
diff options
context:
space:
mode:
Diffstat (limited to 'src/openvic-simulation/scripts')
-rw-r--r--src/openvic-simulation/scripts/Condition.cpp57
-rw-r--r--src/openvic-simulation/scripts/Condition.hpp38
-rw-r--r--src/openvic-simulation/scripts/ConditionScript.cpp2
-rw-r--r--src/openvic-simulation/scripts/ConditionScript.hpp8
-rw-r--r--src/openvic-simulation/scripts/ConditionalWeight.cpp81
-rw-r--r--src/openvic-simulation/scripts/ConditionalWeight.hpp19
6 files changed, 130 insertions, 75 deletions
diff --git a/src/openvic-simulation/scripts/Condition.cpp b/src/openvic-simulation/scripts/Condition.cpp
index fd1f4fa..bb8b662 100644
--- a/src/openvic-simulation/scripts/Condition.cpp
+++ b/src/openvic-simulation/scripts/Condition.cpp
@@ -7,12 +7,12 @@ using namespace OpenVic;
using namespace OpenVic::NodeTools;
using enum value_type_t;
-using enum scope_t;
+using enum scope_type_t;
using enum identifier_type_t;
Condition::Condition(
- std::string_view new_identifier, value_type_t new_value_type, scope_t new_scope,
- scope_t new_scope_change, identifier_type_t new_key_identifier_type,
+ std::string_view new_identifier, value_type_t new_value_type, scope_type_t new_scope,
+ scope_type_t new_scope_change, identifier_type_t new_key_identifier_type,
identifier_type_t new_value_identifier_type
) : HasIdentifier { new_identifier }, value_type { new_value_type }, scope { new_scope },
scope_change { new_scope_change }, key_identifier_type { new_key_identifier_type },
@@ -26,7 +26,7 @@ ConditionNode::ConditionNode(
condition_key_item { new_condition_key_item }, condition_value_item { new_condition_key_item } {}
bool ConditionManager::add_condition(
- std::string_view identifier, value_type_t value_type, scope_t scope, scope_t scope_change,
+ std::string_view identifier, value_type_t value_type, scope_type_t scope, scope_type_t scope_change,
identifier_type_t key_identifier_type, identifier_type_t value_identifier_type
) {
if (identifier.empty()) {
@@ -337,8 +337,8 @@ bool ConditionManager::setup_conditions(DefinitionManager const& definition_mana
const auto import_identifiers = [this, &ret](
std::vector<std::string_view> const& identifiers,
value_type_t value_type,
- scope_t scope,
- scope_t scope_change = NO_SCOPE,
+ scope_type_t scope,
+ scope_type_t scope_change = NO_SCOPE,
identifier_type_t key_identifier_type = NO_IDENTIFIER,
identifier_type_t value_identifier_type = NO_IDENTIFIER
) -> void {
@@ -523,10 +523,10 @@ callback_t<std::string_view> ConditionManager::expect_parse_identifier(
}
node_callback_t ConditionManager::expect_condition_node(
- DefinitionManager const& definition_manager, Condition const& condition, scope_t this_scope,
- scope_t from_scope, scope_t cur_scope, callback_t<ConditionNode&&> callback
+ DefinitionManager const& definition_manager, Condition const& condition, scope_type_t current_scope,
+ scope_type_t this_scope, scope_type_t from_scope, callback_t<ConditionNode&&> callback
) const {
- return [this, &definition_manager, &condition, callback, this_scope, from_scope, cur_scope](
+ return [this, &definition_manager, &condition, callback, current_scope, this_scope, from_scope](
ast::NodeCPtr node
) -> bool {
bool ret = false;
@@ -534,8 +534,8 @@ node_callback_t ConditionManager::expect_condition_node(
const std::string_view identifier = condition.get_identifier();
const value_type_t value_type = condition.get_value_type();
- const scope_t scope = condition.get_scope();
- const scope_t scope_change = condition.get_scope_change();
+ const scope_type_t scope = condition.get_scope();
+ const scope_type_t scope_change = condition.get_scope_change();
const identifier_type_t key_identifier_type = condition.get_key_identifier_type();
const identifier_type_t value_identifier_type = condition.get_value_identifier_type();
@@ -647,23 +647,24 @@ node_callback_t ConditionManager::expect_condition_node(
if (!ret && share_value_type(value_type, GROUP)) {
ConditionNode::condition_list_t node_list;
ret |= expect_condition_node_list(
- definition_manager, this_scope, from_scope,
- scope_change == NO_SCOPE ? cur_scope : scope_change,
- false,
+ definition_manager,
+ scope_change == NO_SCOPE ? current_scope : scope_change,
+ this_scope,
+ from_scope,
vector_callback(node_list)
)(node);
value = std::move(node_list);
}
// scope validation
- scope_t effective_current_scope = cur_scope;
- if (share_scope(effective_current_scope, THIS)) {
+ scope_type_t effective_current_scope = current_scope;
+ if (share_scope_type(effective_current_scope, THIS)) {
effective_current_scope = this_scope;
- } else if (share_scope(effective_current_scope, FROM)) {
+ } else if (share_scope_type(effective_current_scope, FROM)) {
effective_current_scope = from_scope;
}
- if (!share_scope(scope, effective_current_scope) && effective_current_scope > scope) {
+ if (!share_scope_type(scope, effective_current_scope) && effective_current_scope > scope) {
Logger::warning(
"Condition or scope ", identifier, " was found in wrong scope ", effective_current_scope, ", expected ",
scope, "!"
@@ -706,15 +707,15 @@ static bool top_scope_fallback(std::string_view id, ast::NodeCPtr node) {
};
node_callback_t ConditionManager::expect_condition_node_list(
- DefinitionManager const& definition_manager, scope_t this_scope, scope_t from_scope,
- scope_t cur_scope, bool top_scope, callback_t<ConditionNode&&> callback
+ DefinitionManager const& definition_manager, scope_type_t current_scope, scope_type_t this_scope, scope_type_t from_scope,
+ callback_t<ConditionNode&&> callback, bool top_scope
) const {
- return [this, &definition_manager, callback, this_scope, from_scope, cur_scope, top_scope](ast::NodeCPtr node) -> bool {
+ return [this, &definition_manager, callback, current_scope, this_scope, from_scope, top_scope](ast::NodeCPtr node) -> bool {
const auto expect_node = [
- this, &definition_manager, callback, this_scope, from_scope, cur_scope
+ this, &definition_manager, callback, current_scope, this_scope, from_scope
](Condition const& condition, ast::NodeCPtr node) -> bool {
return expect_condition_node(
- definition_manager, condition, this_scope, from_scope, cur_scope, callback
+ definition_manager, condition, current_scope, this_scope, from_scope, callback
)(node);
};
@@ -729,19 +730,19 @@ node_callback_t ConditionManager::expect_condition_node_list(
}
node_callback_t ConditionManager::expect_condition_script(
- DefinitionManager const& definition_manager, scope_t initial_scope, scope_t this_scope,
- scope_t from_scope, callback_t<ConditionNode&&> callback
+ DefinitionManager const& definition_manager, scope_type_t initial_scope, scope_type_t this_scope,
+ scope_type_t from_scope, callback_t<ConditionNode&&> callback
) const {
return [this, &definition_manager, initial_scope, this_scope, from_scope, callback](ast::NodeCPtr node) -> bool {
ConditionNode::condition_list_t conds;
bool ret = expect_condition_node_list(
definition_manager,
+ initial_scope,
this_scope,
from_scope,
- initial_scope,
- true,
- NodeTools::vector_callback(conds)
+ NodeTools::vector_callback(conds),
+ true
)(node);
ret &= callback({ root_condition, std::move(conds), true });
diff --git a/src/openvic-simulation/scripts/Condition.hpp b/src/openvic-simulation/scripts/Condition.hpp
index 8d4d246..1f4929a 100644
--- a/src/openvic-simulation/scripts/Condition.hpp
+++ b/src/openvic-simulation/scripts/Condition.hpp
@@ -27,7 +27,7 @@ namespace OpenVic {
// Order matters in this enum, for the fallback system to work
// smaller entities must have smaller integers associated!
- enum class scope_t : uint8_t { //TODO: maybe distinguish TRANSPARENT from NO_SCOPE
+ enum class scope_type_t : uint8_t { //TODO: maybe distinguish TRANSPARENT from NO_SCOPE
NO_SCOPE = 0,
POP = 1 << 0,
PROVINCE = 1 << 1,
@@ -74,15 +74,15 @@ namespace OpenVic {
/* Allows enum types to be used with bitwise operators. */
template<> struct enable_bitfield<value_type_t> : std::true_type {};
- template<> struct enable_bitfield<scope_t> : std::true_type {};
+ template<> struct enable_bitfield<scope_type_t> : std::true_type {};
template<> struct enable_bitfield<identifier_type_t> : std::true_type {};
/* Returns true if the values have any bit in common. */
inline constexpr bool share_value_type(value_type_t lhs, value_type_t rhs) {
return (lhs & rhs) != value_type_t::NO_TYPE;
}
- inline constexpr bool share_scope(scope_t lhs, scope_t rhs) {
- return (lhs & rhs) != scope_t::NO_SCOPE;
+ inline constexpr bool share_scope_type(scope_type_t lhs, scope_type_t rhs) {
+ return (lhs & rhs) != scope_type_t::NO_SCOPE;
}
inline constexpr bool share_identifier_type(identifier_type_t lhs, identifier_type_t rhs) {
return (lhs & rhs) != identifier_type_t::NO_IDENTIFIER;
@@ -122,10 +122,10 @@ namespace OpenVic {
}
#undef BUILD_STRING
-#define BUILD_STRING(entry) _BUILD_STRING(entry, share_scope)
+#define BUILD_STRING(entry) _BUILD_STRING(entry, share_scope_type)
- inline std::ostream& operator<<(std::ostream& stream, scope_t value) {
- using enum scope_t;
+ inline std::ostream& operator<<(std::ostream& stream, scope_type_t value) {
+ using enum scope_type_t;
if (value == NO_SCOPE) {
return stream << "[NO_SCOPE]";
}
@@ -198,14 +198,14 @@ namespace OpenVic {
private:
const value_type_t PROPERTY(value_type);
- const scope_t PROPERTY(scope);
- const scope_t PROPERTY(scope_change);
+ const scope_type_t PROPERTY(scope);
+ const scope_type_t PROPERTY(scope_change);
const identifier_type_t PROPERTY(key_identifier_type);
const identifier_type_t PROPERTY(value_identifier_type);
Condition(
- std::string_view new_identifier, value_type_t new_value_type, scope_t new_scope,
- scope_t new_scope_change, identifier_type_t new_key_identifier_type,
+ std::string_view new_identifier, value_type_t new_value_type, scope_type_t new_scope,
+ scope_type_t new_scope_change, identifier_type_t new_key_identifier_type,
identifier_type_t new_value_identifier_type
);
@@ -249,8 +249,8 @@ namespace OpenVic {
Condition const* root_condition = nullptr;
bool add_condition(
- std::string_view identifier, value_type_t value_type, scope_t scope,
- scope_t scope_change = scope_t::NO_SCOPE,
+ std::string_view identifier, value_type_t value_type, scope_type_t scope,
+ scope_type_t scope_change = scope_type_t::NO_SCOPE,
identifier_type_t key_identifier_type = identifier_type_t::NO_IDENTIFIER,
identifier_type_t value_identifier_type = identifier_type_t::NO_IDENTIFIER
);
@@ -261,21 +261,21 @@ namespace OpenVic {
) const;
NodeTools::node_callback_t expect_condition_node(
- DefinitionManager const& definition_manager, Condition const& condition, scope_t this_scope,
- scope_t from_scope, scope_t cur_scope, NodeTools::callback_t<ConditionNode&&> callback
+ DefinitionManager const& definition_manager, Condition const& condition, scope_type_t current_scope,
+ scope_type_t this_scope, scope_type_t from_scope, NodeTools::callback_t<ConditionNode&&> callback
) const;
NodeTools::node_callback_t expect_condition_node_list(
- DefinitionManager const& definition_manager, scope_t this_scope, scope_t from_scope,
- scope_t cur_scope, bool top_scope, NodeTools::callback_t<ConditionNode&&> callback
+ DefinitionManager const& definition_manager, scope_type_t current_scope, scope_type_t this_scope,
+ scope_type_t from_scope, NodeTools::callback_t<ConditionNode&&> callback, bool top_scope = false
) const;
public:
bool setup_conditions(DefinitionManager const& definition_manager);
NodeTools::node_callback_t expect_condition_script(
- DefinitionManager const& definition_manager, scope_t initial_scope, scope_t this_scope, scope_t from_scope,
- NodeTools::callback_t<ConditionNode&&> callback
+ DefinitionManager const& definition_manager, scope_type_t initial_scope, scope_type_t this_scope,
+ scope_type_t from_scope, NodeTools::callback_t<ConditionNode&&> callback
) const;
};
}
diff --git a/src/openvic-simulation/scripts/ConditionScript.cpp b/src/openvic-simulation/scripts/ConditionScript.cpp
index bee4d07..c556bd2 100644
--- a/src/openvic-simulation/scripts/ConditionScript.cpp
+++ b/src/openvic-simulation/scripts/ConditionScript.cpp
@@ -6,7 +6,7 @@ using namespace OpenVic;
using namespace OpenVic::NodeTools;
ConditionScript::ConditionScript(
- scope_t new_initial_scope, scope_t new_this_scope, scope_t new_from_scope
+ scope_type_t new_initial_scope, scope_type_t new_this_scope, scope_type_t new_from_scope
) : initial_scope { new_initial_scope }, this_scope { new_this_scope }, from_scope { new_from_scope } {}
bool ConditionScript::_parse_script(ast::NodeCPtr root, DefinitionManager const& definition_manager) {
diff --git a/src/openvic-simulation/scripts/ConditionScript.hpp b/src/openvic-simulation/scripts/ConditionScript.hpp
index e6ed255..aa386e8 100644
--- a/src/openvic-simulation/scripts/ConditionScript.hpp
+++ b/src/openvic-simulation/scripts/ConditionScript.hpp
@@ -10,14 +10,14 @@ namespace OpenVic {
private:
ConditionNode PROPERTY_REF(condition_root);
- scope_t PROPERTY(initial_scope);
- scope_t PROPERTY(this_scope);
- scope_t PROPERTY(from_scope);
+ scope_type_t PROPERTY(initial_scope);
+ scope_type_t PROPERTY(this_scope);
+ scope_type_t PROPERTY(from_scope);
protected:
bool _parse_script(ast::NodeCPtr root, DefinitionManager const& definition_manager) override;
public:
- ConditionScript(scope_t new_initial_scope, scope_t new_this_scope, scope_t new_from_scope);
+ ConditionScript(scope_type_t new_initial_scope, scope_type_t new_this_scope, scope_type_t new_from_scope);
};
}
diff --git a/src/openvic-simulation/scripts/ConditionalWeight.cpp b/src/openvic-simulation/scripts/ConditionalWeight.cpp
index 7c3e0a0..1bb83d0 100644
--- a/src/openvic-simulation/scripts/ConditionalWeight.cpp
+++ b/src/openvic-simulation/scripts/ConditionalWeight.cpp
@@ -3,12 +3,12 @@
using namespace OpenVic;
using namespace OpenVic::NodeTools;
-ConditionalWeight::ConditionalWeight(scope_t new_initial_scope, scope_t new_this_scope, scope_t new_from_scope)
+ConditionalWeight::ConditionalWeight(scope_type_t new_initial_scope, scope_type_t new_this_scope, scope_type_t new_from_scope)
: initial_scope { new_initial_scope }, this_scope { new_this_scope }, from_scope { new_from_scope } {}
template<typename T>
static NodeCallback auto expect_modifier(
- std::vector<T>& items, scope_t initial_scope, scope_t this_scope, scope_t from_scope
+ std::vector<T>& items, scope_type_t initial_scope, scope_type_t this_scope, scope_type_t from_scope
) {
return [&items, initial_scope, this_scope, from_scope](ast::NodeCPtr node) -> bool {
fixed_point_t weight = 0;
@@ -26,23 +26,86 @@ static NodeCallback auto expect_modifier(
}
node_callback_t ConditionalWeight::expect_conditional_weight(base_key_t base_key) {
- return expect_dictionary_keys(
- // TODO - add days and years as options with a shared expected count of ONE_EXACTLY
- base_key_to_string(base_key), ZERO_OR_ONE, expect_fixed_point(assign_variable_callback(base)),
- "days", ZERO_OR_ONE, success_callback,
- "years", ZERO_OR_ONE, success_callback,
+ key_map_t key_map;
+ bool successfully_set_up_base_keys = true;
+
+ switch (base_key) {
+ case BASE:
+ {
+ successfully_set_up_base_keys &= add_key_map_entry(
+ key_map,
+ "base", ONE_EXACTLY, expect_fixed_point(assign_variable_callback(base))
+ );
+
+ break;
+ }
+ case FACTOR:
+ {
+ successfully_set_up_base_keys &= add_key_map_entry(
+ key_map,
+ "factor", ONE_EXACTLY, expect_fixed_point(assign_variable_callback(base))
+ );
+
+ break;
+ }
+ case TIME:
+ {
+ const auto time_callback = [this](std::string_view key, Timespan (*to_timespan)(Timespan::day_t)) -> auto {
+ return [this, key, to_timespan](uint32_t value) -> bool {
+ if (base == fixed_point_t::_0()) {
+ base = fixed_point_t::parse((*to_timespan)(value).to_int());
+ return true;
+ } else {
+ Logger::error(
+ "ConditionalWeight cannot have multiple base values - trying to set base to ", value, " ", key,
+ " when it already has a value equivalent to ", base, " days!"
+ );
+ return false;
+ }
+ };
+ };
+
+ successfully_set_up_base_keys &= add_key_map_entries(
+ key_map,
+ "days", ZERO_OR_ONE, expect_uint<uint32_t>(time_callback("days", Timespan::from_days)),
+ "months", ZERO_OR_ONE, expect_uint<uint32_t>(time_callback("months", Timespan::from_months)),
+ "years", ZERO_OR_ONE, expect_uint<uint32_t>(time_callback("years", Timespan::from_years))
+ );
+
+ break;
+ }
+ default:
+ {
+ successfully_set_up_base_keys = false;
+ }
+ }
+
+ if (!successfully_set_up_base_keys) {
+ return [base_key](ast::NodeCPtr node) -> bool {
+ Logger::error(
+ "Failed to set up base keys for ConditionalWeight with base value: ", static_cast<uint32_t>(base_key)
+ );
+ return false;
+ };
+ }
+
+ return expect_dictionary_key_map(
+ std::move(key_map),
"modifier", ZERO_OR_MORE, expect_modifier(condition_weight_items, initial_scope, this_scope, from_scope),
"group", ZERO_OR_MORE, [this](ast::NodeCPtr node) -> bool {
condition_weight_group_t items;
+
const bool ret = expect_dictionary_keys(
"modifier", ONE_OR_MORE, expect_modifier(items, initial_scope, this_scope, from_scope)
)(node);
+
if (!items.empty()) {
condition_weight_items.emplace_back(std::move(items));
return ret;
+ } else {
+ Logger::error("ConditionalWeight group must have at least one modifier!");
+ return false;
}
- Logger::error("ConditionalWeight group must have at least one modifier!");
- return false;
}
);
}
diff --git a/src/openvic-simulation/scripts/ConditionalWeight.hpp b/src/openvic-simulation/scripts/ConditionalWeight.hpp
index c99d6b0..fcab0a6 100644
--- a/src/openvic-simulation/scripts/ConditionalWeight.hpp
+++ b/src/openvic-simulation/scripts/ConditionalWeight.hpp
@@ -14,32 +14,23 @@ namespace OpenVic {
using condition_weight_item_t = std::variant<condition_weight_t, condition_weight_group_t>;
enum class base_key_t : uint8_t {
- BASE, FACTOR, MONTHS
+ BASE, FACTOR, TIME
};
using enum base_key_t;
private:
fixed_point_t PROPERTY(base);
std::vector<condition_weight_item_t> PROPERTY(condition_weight_items);
- scope_t PROPERTY(initial_scope);
- scope_t PROPERTY(this_scope);
- scope_t PROPERTY(from_scope);
+ scope_type_t PROPERTY(initial_scope);
+ scope_type_t PROPERTY(this_scope);
+ scope_type_t PROPERTY(from_scope);
struct parse_scripts_visitor_t;
public:
- ConditionalWeight(scope_t new_initial_scope, scope_t new_this_scope, scope_t new_from_scope);
+ ConditionalWeight(scope_type_t new_initial_scope, scope_type_t new_this_scope, scope_type_t new_from_scope);
ConditionalWeight(ConditionalWeight&&) = default;
- static constexpr std::string_view base_key_to_string(base_key_t base_key) {
- switch (base_key) {
- case base_key_t::BASE: return "base";
- case base_key_t::FACTOR: return "factor";
- case base_key_t::MONTHS: return "months"; // TODO - add functionality for days or months or years
- default: return "INVALID BASE KEY";
- }
- }
-
NodeTools::node_callback_t expect_conditional_weight(base_key_t base_key);
bool parse_scripts(DefinitionManager const& definition_manager);