aboutsummaryrefslogtreecommitdiff
path: root/src/openvic/pop/Religion.cpp
blob: 58b73e5f7ad5380c035983d37beb5f1999c462c6 (plain) (blame)
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
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
#include "Religion.hpp"

#include <cassert>

using namespace OpenVic;
using namespace OpenVic::NodeTools;

ReligionGroup::ReligionGroup(const std::string_view new_identifier) : HasIdentifier { new_identifier } {}

Religion::Religion(const std::string_view new_identifier, colour_t new_colour,
   ReligionGroup const& new_group, icon_t new_icon, bool new_pagan)
   : HasIdentifierAndColour { new_identifier, new_colour, true },
     group { new_group },
     icon { new_icon },
     pagan { new_pagan } {
   assert(icon > 0);
}

ReligionGroup const& Religion::get_group() const {
   return group;
}

Religion::icon_t Religion::get_icon() const {
   return icon;
}

bool Religion::get_pagan() const {
   return pagan;
}

ReligionManager::ReligionManager()
   : religion_groups { "religion groups" },
     religions { "religions" } {}

return_t ReligionManager::add_religion_group(const std::string_view identifier) {
   if (identifier.empty()) {
      Logger::error("Invalid religion group identifier - empty!");
      return FAILURE;
   }
   return religion_groups.add_item({ identifier });
}

void ReligionManager::lock_religion_groups() {
   religion_groups.lock();
}

ReligionGroup const* ReligionManager::get_religion_group_by_identifier(const std::string_view identifier) const {
   return religion_groups.get_item_by_identifier(identifier);
}

size_t ReligionManager::get_religion_group_count() const {
   return religion_groups.size(); 
}

std::vector<ReligionGroup> const& ReligionManager::get_religion_groups() const {
   return religion_groups.get_items();
}

return_t ReligionManager::add_religion(const std::string_view identifier, colour_t colour, ReligionGroup const* group, Religion::icon_t icon, bool pagan) {
   if (!religion_groups.is_locked()) {
      Logger::error("Cannot register religions until religion groups are locked!");
      return FAILURE;
   }
   if (identifier.empty()) {
      Logger::error("Invalid religion identifier - empty!");
      return FAILURE;
   }
   if (group == nullptr) {
      Logger::error("Null religion group for ", identifier);
      return FAILURE;
   }
   if (colour > MAX_COLOUR_RGB) {
      Logger::error("Invalid religion colour for ", identifier, ": ", colour_to_hex_string(colour));
      return FAILURE;
   }
   if (icon <= 0) {
      Logger::error("Invalid religion icon for ", identifier, ": ", icon);
      return FAILURE;
   }
   return religions.add_item({ identifier, colour, *group, icon, pagan });
}

void ReligionManager::lock_religions() {
   religions.lock();
}

Religion const* ReligionManager::get_religion_by_identifier(const std::string_view identifier) const {
   return religions.get_item_by_identifier(identifier);
}

size_t ReligionManager::get_religion_count() const {
   return religions.size(); 
}

std::vector<Religion> const& ReligionManager::get_religions() const {
   return religions.get_items();
}

return_t ReligionManager::load_religion_file(ast::NodeCPtr root) {

   size_t total_expected_religions = 0;
   return_t ret = expect_dictionary_reserve_length(
      religion_groups,
      [this, &total_expected_religions](std::string_view key, ast::NodeCPtr value) -> return_t {
         return_t ret = expect_list_and_length(
            [&total_expected_religions](size_t size) -> size_t {
               total_expected_religions += size;
               return 0;
            },
            success_callback
         )(value);
         if (add_religion_group(key) != SUCCESS) ret = FAILURE;
         return ret;
      }
   )(root);
   lock_religion_groups();
   religions.reserve(religions.size() + total_expected_religions);
   if (expect_dictionary(
      [this](std::string_view religion_group_key, ast::NodeCPtr religion_group_value) -> return_t {

         ReligionGroup const* religion_group = get_religion_group_by_identifier(religion_group_key);

         return expect_dictionary(
            [this, religion_group](std::string_view key, ast::NodeCPtr value) -> return_t {
               colour_t colour = NULL_COLOUR;
               Religion::icon_t icon = 0;
               bool pagan = false;

               return_t ret = expect_dictionary_keys(
                  "icon", ONE_EXACTLY, expect_uint(assign_variable_callback_uint("religion icon", icon)),
                  "color", ONE_EXACTLY, expect_colour(assign_variable_callback(colour)),
                  "pagan", ZERO_OR_ONE, expect_bool(assign_variable_callback(pagan))
               )(value);
               if (add_religion(key, colour, religion_group, icon, pagan) != SUCCESS) ret = FAILURE;
               return ret;
            }
         )(religion_group_value);
      }
   )(root) != SUCCESS) ret = FAILURE;
   lock_religions();
   return ret;
}