pastebin

Paste #MyA -- näytä pelkkänä tekstinä -- uusi tämän pohjalta

Värjäys: Tyyli: ensimmäinen rivinumero: Tabin korvaus:

 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.