Paste #MyA -- näytä pelkkänä tekstinä -- uusi tämän pohjalta
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 | The only changes needed are in mods.cpp and mods.h. Each ModSpec gets an additional field, std::set<std::string> optdepends, which is filled in getModsInPath(std::string path). The optional dependencies require a modification to the dependency resolver (class ModConfiguration). The new algorithm runs after the existing algorithm has completed (all the non-optional dependencies have been resolved), which is the case when m_unsatisfied_mods is empty and m_sorted_list is a list of all loaded mods in the proper order. Algorithm idea (very pseudocodey): ================================== for each ModSpec mod in m_sorted_list if mod has optional dependencies insert_after = mod for each ModSpec mod2 in m_sorted_list *after* mod if (mod2 is an optional dependency of mod) && (mod can be moved behind mod2 without violating non-optional dependencies) insert_after = mod2 end end if insert_after != mod: remove mod from m_sorted_list and reinsert it behind mod2 end end end Algorithm (less pseudocodey): ============================= already_done = empty set of strings i = 0 while i < m_sorted_list.size mod = m_sorted_list[i] insert_after = i if mod.optdepends is not empty && mod.name not in already_done for j = i+1 to m_sorted_list.size-1 mod2 = m_sorted_list[j] if mod2 depends on mod then break if mod2 in mod.optdepends then insert_after = j end end if insert_after == i // don't move mod i++ else // move mod behind insert_after m_sorted_list.remove(i) m_sorted_list.insert(insert_after, mod) already_done.add(mod.name) // don't increment i here end end // NOTE: already_done is used so that the algorithm doesn't go into an infinite loop // when circular optional dependencies exist. |