feat(kæde): manglende led forklares i Kræver handling, fanen og som besked

problemText giver årsag og råd for køb/flaskehals/kredsløb og 'slukket af dig'
(userOff-kopi på ADChain.last); modellens problemer får need. Fanen Kæder viser
teksten som rød tekstrække under varen (foldet ud). Kræver handling får én rød
post pr. kæde (højst 2, score 3500+alvor mellem rød tom og rød fuld); klik åbner
fanen med kæden foldet ud. Engangsbesked pr. nyt led (rod|vare|art) kun fra
tick, ikke i opstartsfristen eller på delvise data/ufærdig markscanning.
Manualer og CHANGELOG opdateret.
This commit is contained in:
2026-09-30 14:40:29 +02:00
parent 1e7b2ec699
commit 19a10ab67c
12 changed files with 254 additions and 20 deletions
+43 -2
View File
@@ -29,6 +29,8 @@ ADChain.switchCount = 0
ADChain.now = 0
ADChain.timer = 0
ADChain.collectFailed = false
-- {[rodnøgle|vare|art] = true}: manglende led der allerede er meldt som besked (kun i hukommelsen; nulstilles ved indlæsning)
ADChain.problemKeys = {}
local function contains(list, value)
for _, item in ipairs(list or {}) do if item == value then return true end end
@@ -258,6 +260,24 @@ function ADChain.runsView(runs)
return list
end
-- Manglende led der ikke var der sidst (nøgle = rodnøgle|vare|art). -> nye problemer (hver nøgle én gang), nøglerne nu.
-- Et problem der forsvinder, glemmes; kommer det igen, er det nyt. prevKeys røres ikke.
function ADChain.problemKey(problem)
return tostring(problem.rootKey) .. "|" .. tostring(problem.fillType) .. "|" .. tostring(problem.kind)
end
function ADChain.newProblems(prevKeys, problems)
local fresh, keys = {}, {}
for _, problem in ipairs(problems or {}) do
local key = ADChain.problemKey(problem)
if not keys[key] then
keys[key] = true
if not (prevKeys or {})[key] then table.insert(fresh, problem) end
end
end
return fresh, keys
end
-- ---- evaluering ----
local function farmId()
@@ -325,7 +345,7 @@ function ADChain.evaluate(adEnv, act)
for key in pairs(state.paused) do paused[key] = true end
ADChain.last = {chain = result.chain, shortages = result.shortages, actions = result.actions, edges = result.edges,
missingFlows = ADChainActions.missingFlows(result.edges, runs), flowStatus = ADChain.flowStatus(result.edges, runs, ADChain.noVehicle),
paused = paused, data = data, fields = data.fields, fieldsIncomplete = data.fieldsIncomplete == true, titles = data.fillTitles, at = ADChain.now, switchCount = ADChain.switchCount}
paused = paused, userOff = copySet(state.userOff), data = data, fields = data.fields, fieldsIncomplete = data.fieldsIncomplete == true, titles = data.fillTitles, at = ADChain.now, switchCount = ADChain.switchCount}
return ADChain.last
end
@@ -335,13 +355,33 @@ function ADChain.lastAge()
return ADChain.now - (ADChain.last.at or 0)
end
-- Engangsbesked pr. nyt manglende led (kun fra tick). Ikke i opstartsfristen og ikke mens gården er læst delvist
-- eller markscanningen kører (ellers falske alarmer lige efter indlæsning) — så huskes intet, og det meldes senere.
function ADChain.notifyProblems(last)
if last == nil or ADChain.now < ADChain.STARTUP_GRACE_MS then return 0 end
if last.fieldsIncomplete or (last.data ~= nil and last.data.partial) then return 0 end
local fresh, keys = ADChain.newProblems(ADChain.problemKeys, last.chain ~= nil and last.chain.problems or {})
ADChain.problemKeys = keys
if #fresh == 0 or ADFieldJobs == nil or ADFieldJobs.notify == nil then return 0 end
local textOf = function(key) return g_i18n ~= nil and g_i18n:getText(key) or key end
local fmt = SmartPickupFrame ~= nil and SmartPickupFrame.formatCompact or nil
for _, problem in ipairs(fresh) do
local text = ADChainView.problemText(problem, last, textOf, nil, fmt)
Logging.info(ADChain.LOG_PREFIX .. "manglende led: %s", text)
ADFieldJobs.notify(text, true)
end
return #fresh
end
function ADChain.tick(adEnv, dt)
if adEnv == nil then return end
ADChain.now = ADChain.now + (dt or 0)
ADChain.timer = ADChain.timer + (dt or 0)
if ADChain.now < ADChain.STARTUP_GRACE_MS or ADChain.timer < ADChain.TICK_MS then return end
ADChain.timer = 0
ADChain.evaluate(adEnv, true)
local last = ADChain.evaluate(adEnv, true)
local ok, err = pcall(ADChain.notifyProblems, last)
if not ok then Logging.warning(ADChain.LOG_PREFIX .. "besked om manglende led fejlede: %s", tostring(err)) end
end
-- ---- GUI-handlinger ----
@@ -436,6 +476,7 @@ function ADChain.load()
ADChain.state = ADChain.newState()
ADChain.noVehicle = {}
ADChain.prevEnabled, ADChain.afterLoad = nil, true
ADChain.problemKeys = {}
local path = getPath()
if path == nil or not fileExists(path) then return end
local xmlFile = XMLFile.load("ADSmartPickupChain", path)