Skip to content

Commit 73423c5

Browse files
committed
Mod Compatibility Fixes
1 parent 5e05416 commit 73423c5

24 files changed

+352
-344
lines changed

src/headless/main.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ static std::chrono::nanoseconds run_pathing_test(AStarPathing& pathing) {
112112
return end_time - start_time;
113113
}
114114

115-
static bool run_headless(const fs::path root, std::vector<std::string> mods, bool run_tests) {
115+
static bool run_headless(fs::path const& root, std::vector<std::string>& mods, bool run_tests) {
116116
bool ret = true;
117117
Dataloader::path_vector_t roots = { root };
118118
Dataloader::path_vector_t replace_paths = {};
@@ -122,7 +122,7 @@ static bool run_headless(const fs::path root, std::vector<std::string> mods, boo
122122
} };
123123

124124
Logger::info("===== Loading mod descriptors... =====");
125-
ret &= game_manager.load_mod_descriptors(std::move(mods));
125+
ret &= game_manager.load_mod_descriptors(mods);
126126
for (auto const& mod : game_manager.get_mod_manager().get_mods()) {
127127
roots.emplace_back(root / mod.get_dataloader_root_path());
128128
for (std::string_view path : mod.get_replace_paths()) {
@@ -296,7 +296,7 @@ int main(int argc, char const* argv[]) {
296296

297297
std::cout << "!!! HEADLESS SIMULATION START !!!" << std::endl;
298298

299-
const bool ret = run_headless(root, std::move(mods), run_tests);
299+
const bool ret = run_headless(root, mods, run_tests);
300300

301301
std::cout << "!!! HEADLESS SIMULATION END !!!" << std::endl;
302302

src/openvic-simulation/GameManager.cpp

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,17 +6,15 @@ GameManager::GameManager(
66
InstanceManager::gamestate_updated_func_t new_gamestate_updated_callback
77
) : gamestate_updated_callback {
88
new_gamestate_updated_callback ? std::move(new_gamestate_updated_callback) : []() {}
9-
}, clock_state_changed_callback {
10-
new_clock_state_changed_callback ? std::move(new_clock_state_changed_callback) : []() {}
119
}, definitions_loaded { false }, mod_descriptors_loaded { false } {}
1210

13-
bool GameManager::load_mod_descriptors(std::vector<std::string> descriptors) {
11+
bool GameManager::load_mod_descriptors(std::vector<std::string> const& descriptors) {
1412
if (mod_descriptors_loaded) {
1513
Logger::error("Cannot load mod descriptors - already loaded!");
1614
return false;
1715
}
1816

19-
if (!dataloader.load_mod_descriptors(std::move(descriptors), mod_manager)) {
17+
if (!dataloader.load_mod_descriptors(descriptors, mod_manager)) {
2018
Logger::error("Failed to load mod descriptors!");
2119
return false;
2220
}

src/openvic-simulation/GameManager.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ namespace OpenVic {
3636

3737
bool set_roots(Dataloader::path_vector_t const& roots, Dataloader::path_vector_t const& replace_paths);
3838

39-
bool load_mod_descriptors(std::vector<std::string> descriptors);
39+
bool load_mod_descriptors(std::vector<std::string> const& descriptors);
4040

4141
bool load_definitions(Dataloader::localisation_callback_t localisation_callback);
4242

src/openvic-simulation/country/CountryDefinition.cpp

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
#include <string_view>
44

5+
#include <openvic-dataloader/v2script/AbstractSyntaxTree.hpp>
6+
57
#include "openvic-simulation/dataloader/Dataloader.hpp"
68
#include "openvic-simulation/dataloader/NodeTools.hpp"
79
#include "openvic-simulation/DefinitionManager.hpp"
@@ -11,7 +13,7 @@
1113
#include "openvic-simulation/pop/Culture.hpp"
1214
#include "openvic-simulation/types/Colour.hpp"
1315
#include "openvic-simulation/types/IdentifierRegistry.hpp"
14-
#include <openvic-dataloader/v2script/AbstractSyntaxTree.hpp>
16+
#include "openvic-simulation/utility/Logger.hpp"
1517

1618
using namespace OpenVic;
1719
using namespace OpenVic::NodeTools;
@@ -129,13 +131,19 @@ bool CountryDefinitionManager::load_countries(
129131
}
130132

131133
bool CountryDefinitionManager::load_country_colours(ast::NodeCPtr root) {
132-
return country_definitions.expect_item_dictionary([](CountryDefinition& country, ast::NodeCPtr colour_node) -> bool {
133-
return expect_dictionary_keys(
134-
"color1", ONE_EXACTLY, expect_colour(assign_variable_callback(country.primary_unit_colour)),
135-
"color2", ONE_EXACTLY, expect_colour(assign_variable_callback(country.secondary_unit_colour)),
136-
"color3", ONE_EXACTLY, expect_colour(assign_variable_callback(country.tertiary_unit_colour))
137-
)(colour_node);
138-
})(root);
134+
return country_definitions.expect_item_dictionary_and_default(
135+
[](std::string_view key, ast::NodeCPtr value) -> bool {
136+
Logger::warning("country_colors.txt references country tag ", key, " which is not defined!");
137+
return true;
138+
},
139+
[](CountryDefinition& country, ast::NodeCPtr colour_node) -> bool {
140+
return expect_dictionary_keys(
141+
"color1", ONE_EXACTLY, expect_colour(assign_variable_callback(country.primary_unit_colour)),
142+
"color2", ONE_EXACTLY, expect_colour(assign_variable_callback(country.secondary_unit_colour)),
143+
"color3", ONE_EXACTLY, expect_colour(assign_variable_callback(country.tertiary_unit_colour))
144+
)(colour_node);
145+
}
146+
)(root);
139147
}
140148

141149
node_callback_t CountryDefinitionManager::load_country_party(

src/openvic-simulation/dataloader/Dataloader.cpp

Lines changed: 22 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ bool Dataloader::set_roots(path_vector_t const& new_roots, path_vector_t const&
4242
replace_paths.clear();
4343
}
4444
bool ret = true;
45-
for (const fs::path& replace_path : new_replace_paths) {
45+
for (fs::path const& replace_path : new_replace_paths) {
4646
Logger::info("Adding replace path: ", replace_path);
4747
replace_paths.push_back(replace_path);
4848
}
@@ -70,36 +70,13 @@ bool Dataloader::set_roots(path_vector_t const& new_roots, path_vector_t const&
7070
fs::path Dataloader::lookup_file(std::string_view path, bool print_error) const {
7171
const fs::path filepath { ensure_forward_slash_path(path) };
7272

73-
#if defined(FILESYSTEM_CASE_INSENSITIVE)
74-
/* Case-insensitive filesystem */
75-
for (fs::path const& root : roots) {
76-
const fs::path composed = root / filepath;
77-
if (fs::is_regular_file(composed)) {
78-
if (root == roots.back()) {
79-
bool ignore = false;
80-
for (auto const& replace_path : replace_paths) {
81-
if (filepath.string().starts_with(replace_path.string())) {
82-
ignore = true;
83-
break;
84-
}
85-
}
86-
if (!ignore) {
87-
return composed;
88-
}
89-
} else {
90-
return composed;
91-
}
92-
}
93-
}
94-
#else
95-
/* Case-sensitive filesystem */
9673
const std::string_view filename = StringUtils::get_filename(path);
9774
for (fs::path const& root : roots) {
9875
const fs::path composed = root / filepath;
9976
if (fs::is_regular_file(composed)) {
10077
if (root == roots.back()) {
10178
bool ignore = false;
102-
for (auto const& replace_path : replace_paths) {
79+
for (fs::path const& replace_path : replace_paths) {
10380
if (filepath.string().starts_with(replace_path.string())) {
10481
ignore = true;
10582
break;
@@ -119,7 +96,7 @@ fs::path Dataloader::lookup_file(std::string_view path, bool print_error) const
11996
if (StringUtils::strings_equal_case_insensitive(file.filename().string(), filename)) {
12097
if (root == roots.back()) {
12198
bool ignore = false;
122-
for (auto const& replace_path : replace_paths) {
99+
for (fs::path const& replace_path : replace_paths) {
123100
if (filepath.string().starts_with(replace_path.string())) {
124101
ignore = true;
125102
break;
@@ -135,7 +112,6 @@ fs::path Dataloader::lookup_file(std::string_view path, bool print_error) const
135112
}
136113
}
137114
}
138-
#endif
139115

140116
if (print_error) {
141117
Logger::error("Lookup for \"", path, "\" failed!");
@@ -154,6 +130,17 @@ fs::path Dataloader::lookup_image_file(std::string_view path) const {
154130
return lookup_file(path);
155131
}
156132

133+
bool Dataloader::should_ignore_path(fs::path const& path, path_vector_t const& replace_paths) const {
134+
bool ignore = false;
135+
for (fs::path const& replace_path : replace_paths) {
136+
if (path.string().starts_with(replace_path.string())) {
137+
ignore = true;
138+
break;
139+
}
140+
}
141+
return ignore;
142+
}
143+
157144
template<typename _DirIterator, UniqueFileKey _UniqueKey>
158145
Dataloader::path_vector_t Dataloader::_lookup_files_in_dir(
159146
std::string_view path, fs::path const& extension, _UniqueKey const& unique_key
@@ -168,17 +155,8 @@ Dataloader::path_vector_t Dataloader::_lookup_files_in_dir(
168155
for (fs::path const& root : roots) {
169156
const size_t root_len = root.string().size();
170157
std::error_code ec;
171-
if (root == roots.back()) {
172-
bool ignore = false;
173-
for (auto const& replace_path : replace_paths) {
174-
if (dirpath.string().starts_with(replace_path.string())) {
175-
ignore = true;
176-
break;
177-
}
178-
}
179-
if (ignore) {
180-
continue;
181-
}
158+
if (root == roots.back() && should_ignore_path(dirpath, replace_paths)) {
159+
continue;
182160
}
183161
for (fs::directory_entry const& entry : _DirIterator { root / dirpath, ec }) {
184162
if (entry.is_regular_file()) {
@@ -328,7 +306,7 @@ void Dataloader::free_cache() {
328306
cached_parsers.clear();
329307
}
330308

331-
bool Dataloader::load_mod_descriptors(std::vector<std::string> descriptors, ModManager& mod_manager) {
309+
bool Dataloader::load_mod_descriptors(std::vector<std::string> const& descriptors, ModManager& mod_manager) {
332310
bool ret = true;
333311

334312
for (std::string_view descriptor_path : descriptors) {
@@ -824,6 +802,11 @@ bool Dataloader::_load_map_dir(DefinitionManager& definition_manager) const {
824802
ret = false;
825803
}
826804

805+
if (!map_definition.set_water_province_list(water_province_identifiers)) {
806+
Logger::error("Failed to set water provinces!");
807+
ret = false;
808+
}
809+
827810
{
828811
std::vector<colour_t> colours;
829812
if (!MapDefinition::load_region_colours(parse_defines(lookup_file(region_colours)).get_file_node(), colours)) {
@@ -841,11 +824,6 @@ bool Dataloader::_load_map_dir(DefinitionManager& definition_manager) const {
841824
}
842825
}
843826

844-
if (!map_definition.set_water_province_list(water_province_identifiers)) {
845-
Logger::error("Failed to set water provinces!");
846-
ret = false;
847-
}
848-
849827
if (!map_definition.get_terrain_type_manager().load_terrain_types(
850828
definition_manager.get_modifier_manager(),
851829
parse_defines(lookup_file(append_string_views(map_directory, terrain_definition))).get_file_node()

src/openvic-simulation/dataloader/Dataloader.hpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@ namespace OpenVic {
4646
bool _load_decisions(DefinitionManager& definition_manager);
4747
bool _load_history(DefinitionManager& definition_manager, bool unused_history_file_warnings) const;
4848

49+
bool should_ignore_path(fs::path const& path, path_vector_t const& replace_paths) const;
50+
4951
/* _DirIterator is fs::directory_iterator or fs::recursive_directory_iterator. _UniqueKey is the type of a callable
5052
* which converts a string_view filepath with root removed into a string_view unique key. Any path whose key is empty
5153
* or matches an earlier found path's key is discarded, ensuring each looked up path's key is non-empty and unique. */
@@ -123,7 +125,7 @@ namespace OpenVic {
123125
string_set_t lookup_dirs_in_dir(std::string_view path) const;
124126

125127
/* Load all mod descriptors passed by the user. Importantly, loads dependencies and replace_paths for us to check. */
126-
bool load_mod_descriptors(std::vector<std::string> descriptors, ModManager& mod_manager);
128+
bool load_mod_descriptors(std::vector<std::string> const& descriptors, ModManager& mod_manager);
127129

128130
/* Load and parse all of the text defines data, including parsing cached condition and effect scripts after all the
129131
* static data is loaded. Paths to the base and mod defines must have been supplied with set_roots.*/

src/openvic-simulation/dataloader/ModManager.cpp

Lines changed: 25 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -5,45 +5,44 @@
55

66
#include "openvic-simulation/dataloader/NodeTools.hpp"
77
#include "openvic-simulation/types/HasIdentifier.hpp"
8-
#include "types/IdentifierRegistry.hpp"
8+
#include "openvic-simulation/types/IdentifierRegistry.hpp"
99

1010
using namespace OpenVic;
1111
using namespace OpenVic::NodeTools;
1212

1313
Mod::Mod(std::string_view new_identifier, std::string_view new_path, std::optional<std::string_view> new_user_dir, std::vector<std::string> new_replace_paths, std::vector<std::string> new_dependencies)
14-
: HasIdentifier { new_identifier }, dataloader_root_path { new_path }, user_dir { new_user_dir }, replace_paths { new_replace_paths }, dependencies { new_dependencies } {}
14+
: HasIdentifier { new_identifier }, dataloader_root_path { new_path }, user_dir { new_user_dir }, replace_paths { new_replace_paths }, dependencies { new_dependencies } {}
1515

1616
ModManager::ModManager() {}
1717

1818
bool ModManager::load_mod_file(ast::NodeCPtr root) {
19-
std::string_view identifier;
20-
std::string_view path;
21-
std::optional<std::string_view> user_dir;
22-
std::vector<std::string> replace_paths;
23-
std::vector<std::string> dependencies;
24-
25-
bool ret = NodeTools::expect_dictionary_keys(
26-
"name", ONE_EXACTLY, expect_string(assign_variable_callback(identifier)),
27-
"path", ONE_EXACTLY, expect_string(assign_variable_callback(path)),
28-
"user_dir", ZERO_OR_ONE, expect_string(assign_variable_callback_opt(user_dir)),
29-
"replace_path", ZERO_OR_MORE, expect_string(vector_callback_string(replace_paths)),
30-
"dependencies", ZERO_OR_ONE, expect_list_reserve_length(dependencies, expect_string(vector_callback_string(dependencies)))
31-
)(root);
32-
33-
std::vector<std::string_view> previous_mods = mods.get_item_identifiers();
34-
for (std::string_view dependency : dependencies) {
19+
std::string_view identifier;
20+
std::string_view path;
21+
std::optional<std::string_view> user_dir;
22+
std::vector<std::string> replace_paths;
23+
std::vector<std::string> dependencies;
24+
25+
bool ret = NodeTools::expect_dictionary_keys(
26+
"name", ONE_EXACTLY, expect_string(assign_variable_callback(identifier)),
27+
"path", ONE_EXACTLY, expect_string(assign_variable_callback(path)),
28+
"user_dir", ZERO_OR_ONE, expect_string(assign_variable_callback_opt(user_dir)),
29+
"replace_path", ZERO_OR_MORE, expect_string(vector_callback_string(replace_paths)),
30+
"dependencies", ZERO_OR_ONE, expect_list_reserve_length(dependencies, expect_string(vector_callback_string(dependencies)))
31+
)(root);
32+
33+
std::vector<std::string_view> previous_mods = mods.get_item_identifiers();
34+
for (std::string_view dependency : dependencies) {
3535
if (std::find(previous_mods.begin(), previous_mods.end(), dependency) == previous_mods.end()) {
36-
ret = false;
36+
ret = false;
3737
Logger::error("Mod ", identifier, " has unmet dependency ", dependency);
3838
}
3939
}
4040

41-
if (ret) {
42-
ret &= mods.add_item(
43-
{ identifier, path, user_dir, std::move(replace_paths), std::move(dependencies) },
44-
duplicate_fail_callback
45-
);
46-
}
41+
if (ret) {
42+
ret &= mods.add_item(
43+
{ identifier, path, user_dir, std::move(replace_paths), std::move(dependencies) }
44+
);
45+
}
4746

48-
return ret;
47+
return ret;
4948
}

src/openvic-simulation/dataloader/ModManager.hpp

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -5,33 +5,33 @@
55

66
#include "openvic-simulation/types/HasIdentifier.hpp"
77
#include "openvic-simulation/types/IdentifierRegistry.hpp"
8-
#include "dataloader/NodeTools.hpp"
8+
#include "openvic-simulation/dataloader/NodeTools.hpp"
99

1010
namespace OpenVic {
1111

12-
struct Mod : HasIdentifier {
13-
friend struct ModManager;
12+
struct Mod : HasIdentifier {
13+
friend struct ModManager;
1414

15-
private:
16-
const std::string PROPERTY(dataloader_root_path);
17-
const std::optional<std::string> PROPERTY(user_dir);
18-
const std::vector<std::string> PROPERTY(replace_paths);
19-
const std::vector<std::string> PROPERTY(dependencies);
15+
private:
16+
const std::string PROPERTY(dataloader_root_path);
17+
const std::optional<std::string> PROPERTY(user_dir);
18+
const std::vector<std::string> PROPERTY(replace_paths);
19+
const std::vector<std::string> PROPERTY(dependencies);
2020

21-
Mod(std::string_view new_identifier, std::string_view new_path, std::optional<std::string_view> new_user_dir, std::vector<std::string> new_replace_paths, std::vector<std::string> new_dependencies);
21+
Mod(std::string_view new_identifier, std::string_view new_path, std::optional<std::string_view> new_user_dir, std::vector<std::string> new_replace_paths, std::vector<std::string> new_dependencies);
2222

23-
public:
24-
Mod(Mod&&) = default;
25-
};
23+
public:
24+
Mod(Mod&&) = default;
25+
};
2626

27-
struct ModManager {
28-
29-
private:
30-
IdentifierRegistry<Mod> IDENTIFIER_REGISTRY(mod);
27+
struct ModManager {
28+
29+
private:
30+
IdentifierRegistry<Mod> IDENTIFIER_REGISTRY(mod);
3131

32-
public:
33-
ModManager();
32+
public:
33+
ModManager();
3434

35-
bool load_mod_file(ast::NodeCPtr root);
36-
};
35+
bool load_mod_file(ast::NodeCPtr root);
36+
};
3737
} // namespace OpenVic

src/openvic-simulation/dataloader/NodeTools.hpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,10 @@ using namespace std::string_view_literals;
121121
constexpr bool key_value_success_callback(std::string_view, ast::NodeCPtr) {
122122
return true;
123123
}
124-
124+
inline bool key_value_warn_callback(std::string_view key, ast::NodeCPtr) {
125+
Logger::warning("Invalid dictionary key: ", key);
126+
return true;
127+
}
125128
inline bool key_value_invalid_callback(std::string_view key, ast::NodeCPtr) {
126129
Logger::error("Invalid dictionary key: ", key);
127130
return false;

0 commit comments

Comments
 (0)