1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
|
#pragma once
#include "openvic-simulation/types/IdentifierRegistry.hpp"
#include "openvic-simulation/types/OrderedContainers.hpp"
namespace OpenVic {
struct RuleManager;
struct BuildingTypeManager;
/* The index of the Rule within its group, used to determine precedence in mutually exclusive rule groups. */
struct Rule : HasIdentifier, HasIndex<> {
friend struct RuleManager;
enum class rule_group_t : uint8_t {
ECONOMY, CITIZENSHIP, SLAVERY, UPPER_HOUSE, VOTING
};
static constexpr bool is_mutually_exclusive_group(rule_group_t group) {
using enum rule_group_t;
return group == CITIZENSHIP || group == UPPER_HOUSE || group == VOTING;
}
/* Mutually exclusive groups must be default disabled! */
static constexpr bool is_default_enabled(rule_group_t group) {
using enum rule_group_t;
return !is_mutually_exclusive_group(group) && group != SLAVERY;
}
private:
const rule_group_t PROPERTY(group);
Rule(std::string_view new_identifier, rule_group_t new_group, index_t new_index);
public:
Rule(Rule&&) = default;
};
struct RuleSet {
friend struct RuleManager;
using rule_map_t = ordered_map<Rule const*, bool>;
using rule_group_map_t = ordered_map<Rule::rule_group_t, rule_map_t>;
private:
rule_group_map_t PROPERTY(rule_groups);
public:
RuleSet() = default;
RuleSet(rule_group_map_t&& new_rule_groups);
RuleSet(RuleSet const&) = default;
RuleSet(RuleSet&&) = default;
RuleSet& operator=(RuleSet const&) = default;
RuleSet& operator=(RuleSet&&) = default;
/* Removes conflicting and disabled mutually exclusive rules. If log is true, a warning will be emitted for each
* removed disabled rule and an error will be emitted for each removed conflicting rule. Returns true if no conflicts
* are found (regardless of whether disabled rules are removed or not), false otherwise. */
bool trim_and_resolve_conflicts(bool log);
size_t get_rule_group_count() const;
size_t get_rule_count() const;
void clear();
bool empty() const;
rule_map_t const& get_rule_group(Rule::rule_group_t group, bool* successful = nullptr) const;
bool get_rule(Rule const* rule, bool* successful = nullptr) const;
bool has_rule(Rule const* rule) const;
/* Sets the rule to the specified value. Returns false if there was an existing rule, regardless of its value. */
bool set_rule(Rule const* rule, bool value);
RuleSet& operator|=(RuleSet const& right);
RuleSet operator|(RuleSet const& right) const;
friend std::ostream& operator<<(std::ostream& stream, RuleSet const& value);
};
struct RuleManager {
private:
IdentifierRegistry<Rule> IDENTIFIER_REGISTRY(rule);
ordered_map<Rule::rule_group_t, size_t> rule_group_sizes;
public:
bool add_rule(std::string_view identifier, Rule::rule_group_t group);
bool setup_rules(BuildingTypeManager const& building_type_manager);
NodeTools::node_callback_t expect_rule_set(NodeTools::callback_t<RuleSet&&> ruleset_callback) const;
};
}
|