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.
|