11#include " GameManager.hpp"
22
3- #include < cstddef>
43#include < string_view>
54
65#include " openvic-simulation/dataloader/Dataloader.hpp"
@@ -38,35 +37,6 @@ bool GameManager::load_mod_descriptors() {
3837 return true ;
3938}
4039
41- bool GameManager::_get_mod_dependencies (Mod const * mod, memory::vector<Mod const *>& dep_list) {
42- static constexpr size_t MAX_RECURSE = 16 ;
43- size_t current_recurse = 0 ;
44-
45- static auto dep_cycle = [this , ¤t_recurse](auto self, Mod const * mod, memory::vector<Mod const *>& dep_list) -> bool {
46- bool ret = true ;
47- for (std::string_view dep_identifier : mod->get_dependencies ()) {
48- if (!mod_manager.has_mod_identifier (dep_identifier)) {
49- Logger::error (" Mod \" " , mod->get_identifier (), " \" has unmet dependency \" " , dep_identifier, " \" and cannot be loaded!" );
50- return false ;
51- }
52- Mod const * dep = mod_manager.get_mod_by_identifier (dep_identifier);
53- /* The poor man's cycle checking (cycles should be very rare and hard to accomplish with vic2 modding, this is a failsafe) */
54- if (current_recurse == MAX_RECURSE) {
55- Logger::error (" Mod \" " , mod->get_identifier (), " \" has cyclical or broken dependency chain and cannot be loaded!" );
56- return false ;
57- } else {
58- current_recurse++;
59- ret &= self (self, dep, dep_list); /* recursively search for mod dependencies */
60- }
61- if (std::find (dep_list.begin (), dep_list.end (), dep) == dep_list.end ()) {
62- dep_list.emplace_back (dep);
63- }
64- }
65- return ret;
66- };
67- return dep_cycle (dep_cycle, mod, dep_list);
68- }
69-
7040bool GameManager::load_mods (
7141 Dataloader::path_vector_t & roots,
7242 Dataloader::path_vector_t & replace_paths,
@@ -78,7 +48,7 @@ bool GameManager::load_mods(
7848
7949 bool ret = true ;
8050
81- memory::vector <Mod const *> load_list;
51+ vector_ordered_set <Mod const *> load_list;
8252
8353 /* Check loaded mod descriptors for requested mods, using either full name or user directory name
8454 * (Historical Project Mod 0.4.6 or HPM both valid, for example), and load them plus their dependencies.
@@ -99,21 +69,24 @@ bool GameManager::load_mods(
9969 }
10070
10171 Mod const * mod_ptr = &*it;
102- memory::vector<Mod const *> dependencies;
103- if (!_get_mod_dependencies (mod_ptr, dependencies)) {
104- ret = false ;
72+ vector_ordered_set<Mod const *> dependencies = mod_ptr->generate_dependency_list (&ret);
73+ if (!ret) {
10574 continue ;
10675 }
10776
10877 /* Add mod plus dependencies to load_list in proper order. */
109- load_list.reserve (1 + dependencies.size ());
110- for (Mod const * dep : dependencies) {
111- if (ret && std::find (load_list.begin (), load_list.end (), dep) == load_list.end ()) {
112- load_list.emplace_back (dep);
78+ if (load_list.empty ()) {
79+ load_list = std::move (dependencies);
80+ } else {
81+ for (Mod const * dep : dependencies) {
82+ if (!load_list.contains (dep)) {
83+ load_list.emplace (dep);
84+ }
11385 }
11486 }
115- if (ret && std::find (load_list.begin (), load_list.end (), mod_ptr) == load_list.end ()) {
116- load_list.emplace_back (mod_ptr);
87+
88+ if (!load_list.contains (mod_ptr)) {
89+ load_list.emplace (mod_ptr);
11790 }
11891 }
11992
@@ -129,7 +102,7 @@ bool GameManager::load_mods(
129102
130103 /* Load only vanilla and push an error if mod loading failed. */
131104 if (ret) {
132- mod_manager.set_loaded_mods (std::move (load_list));
105+ mod_manager.set_loaded_mods (std::move (load_list. release () ));
133106 } else {
134107 mod_manager.set_loaded_mods ({});
135108 replace_paths.clear ();
0 commit comments