11#include " GameManager.hpp"
22
3- #include < cstddef>
43#include < string_view>
54
65#include " openvic-simulation/dataloader/Dataloader.hpp"
@@ -27,35 +26,6 @@ bool GameManager::load_mod_descriptors() {
2726 return true ;
2827}
2928
30- bool GameManager::_get_mod_dependencies (Mod const * mod, memory::vector<Mod const *>& dep_list) {
31- static constexpr size_t MAX_RECURSE = 16 ;
32- size_t current_recurse = 0 ;
33-
34- static auto dep_cycle = [this , ¤t_recurse](auto self, Mod const * mod, memory::vector<Mod const *>& dep_list) -> bool {
35- bool ret = true ;
36- for (std::string_view dep_identifier : mod->get_dependencies ()) {
37- if (!mod_manager.has_mod_identifier (dep_identifier)) {
38- Logger::error (" Mod \" " , mod->get_identifier (), " \" has unmet dependency \" " , dep_identifier, " \" and cannot be loaded!" );
39- return false ;
40- }
41- Mod const * dep = mod_manager.get_mod_by_identifier (dep_identifier);
42- /* The poor man's cycle checking (cycles should be very rare and hard to accomplish with vic2 modding, this is a failsafe) */
43- if (current_recurse == MAX_RECURSE) {
44- Logger::error (" Mod \" " , mod->get_identifier (), " \" has cyclical or broken dependency chain and cannot be loaded!" );
45- return false ;
46- } else {
47- current_recurse++;
48- ret &= self (self, dep, dep_list); /* recursively search for mod dependencies */
49- }
50- if (std::find (dep_list.begin (), dep_list.end (), dep) == dep_list.end ()) {
51- dep_list.emplace_back (dep);
52- }
53- }
54- return ret;
55- };
56- return dep_cycle (dep_cycle, mod, dep_list);
57- }
58-
5929bool GameManager::load_mods (
6030 Dataloader::path_vector_t & roots,
6131 Dataloader::path_vector_t & replace_paths,
@@ -67,7 +37,7 @@ bool GameManager::load_mods(
6737
6838 bool ret = true ;
6939
70- memory::vector <Mod const *> load_list;
40+ vector_ordered_set <Mod const *> load_list;
7141
7242 /* Check loaded mod descriptors for requested mods, using either full name or user directory name
7343 * (Historical Project Mod 0.4.6 or HPM both valid, for example), and load them plus their dependencies.
@@ -88,21 +58,24 @@ bool GameManager::load_mods(
8858 }
8959
9060 Mod const * mod_ptr = &*it;
91- memory::vector<Mod const *> dependencies;
92- if (!_get_mod_dependencies (mod_ptr, dependencies)) {
93- ret = false ;
61+ vector_ordered_set<Mod const *> dependencies = mod_ptr->generate_dependency_list (&ret);
62+ if (!ret) {
9463 continue ;
9564 }
9665
9766 /* Add mod plus dependencies to load_list in proper order. */
98- load_list.reserve (1 + dependencies.size ());
99- for (Mod const * dep : dependencies) {
100- if (ret && std::find (load_list.begin (), load_list.end (), dep) == load_list.end ()) {
101- load_list.emplace_back (dep);
67+ if (load_list.empty ()) {
68+ load_list = std::move (dependencies);
69+ } else {
70+ for (Mod const * dep : dependencies) {
71+ if (!load_list.contains (dep)) {
72+ load_list.emplace (dep);
73+ }
10274 }
10375 }
104- if (ret && std::find (load_list.begin (), load_list.end (), mod_ptr) == load_list.end ()) {
105- load_list.emplace_back (mod_ptr);
76+
77+ if (!load_list.contains (mod_ptr)) {
78+ load_list.emplace (mod_ptr);
10679 }
10780 }
10881
@@ -118,7 +91,7 @@ bool GameManager::load_mods(
11891
11992 /* Load only vanilla and push an error if mod loading failed. */
12093 if (ret) {
121- mod_manager.set_loaded_mods (std::move (load_list));
94+ mod_manager.set_loaded_mods (std::move (load_list. release () ));
12295 } else {
12396 mod_manager.set_loaded_mods ({});
12497 replace_paths.clear ();
0 commit comments