Fix infinite loop with circular dependencies.

This commit is contained in:
luk3yx 2019-07-13 15:25:12 +12:00
parent 22030aa96c
commit c6eda04dea
1 changed files with 39 additions and 26 deletions

View File

@ -33,38 +33,51 @@ local csm_order = false
-- Recalculate the CSM loading order -- Recalculate the CSM loading order
-- TODO: Make this nicer -- TODO: Make this nicer
local function recalc_csm_order() local function recalc_csm_order()
local loaded = {[':init'] = true, [':cleanup'] = true} local loaded = {}
local not_loaded = {} local staging = {}
local order = {':init'} local order = {':init'}
for k, v in pairs(sscsm.registered_csms) do local unsatisfied = {}
if k:sub(1, 1) ~= ':' then for name, def in pairs(sscsm.registered_csms) do
table.insert(not_loaded, v) assert(name == def.name)
if name:sub(1, 1) == ':' then
loaded[name] = true
elseif not def.depends or #def.depends == 0 then
loaded[name] = true
table.insert(staging, name)
else
unsatisfied[name] = {}
for _, mod in ipairs(def.depends) do
if mod:sub(1, 1) ~= ':' then
unsatisfied[name][mod] = true
end
end
end end
end end
while #not_loaded > 0 do while #staging > 0 do
local def = not_loaded[1] local name = staging[1]
local g = not def.depends or #def.depends == 0 for name2, u in pairs(unsatisfied) do
if not g then if u[name] then
g = true u[name] = nil
for _, mod in ipairs(def.depends) do if #u == 0 then
if not sscsm.registered_csms[mod] then table.insert(staging, name2)
minetest.log('error', '[SSCSM] SSCSM "' .. def.name ..
'" has an unsatisfied dependency: ' .. mod)
g = false
break
elseif not loaded[mod] then
table.insert(not_loaded, def)
g = false
break
end end
end end
end end
if g then table.insert(order, name)
table.insert(order, def.name) table.remove(staging, 1)
loaded[def.name] = true end
for name, u in pairs(unsatisfied) do
if next(u) then
local msg = 'SSCSM "' .. name .. '" has unsatisfied dependencies: '
local n = false
for dep, _ in pairs(u) do
if n then msg = msg .. ', ' else n = true end
msg = msg .. '"' .. dep .. '"'
end
minetest.log('error', msg)
end end
table.remove(not_loaded, 1)
end end
-- Set csm_order -- Set csm_order
@ -157,7 +170,7 @@ minetest.after(1, function()
sscsm.register({ sscsm.register({
name = 'sscsm:testing_cmds', name = 'sscsm:testing_cmds',
file = modpath .. '/sscsm_testing.lua' file = modpath .. '/sscsm_testing.lua',
}) })
sscsm.register({ sscsm.register({
@ -169,7 +182,7 @@ minetest.after(1, function()
sscsm.register({ sscsm.register({
name = 'sscsm:badtest', name = 'sscsm:badtest',
code = 'error("Oops, badtest loaded!")', code = 'error("Oops, badtest loaded!")',
depends = {':init', ':cleanup', 'bad_mod'} depends = {':init', ':cleanup', 'bad_mod', ':bad2', 'bad3'},
}) })
end end
end) end)