feat: controller — bygninger -> markører (resolveMarkers), migration af markør-runs, noMarker-validering, flow-rækker

This commit is contained in:
2026-09-23 18:16:44 +02:00
parent d80f45aef3
commit b202380d9c
4 changed files with 224 additions and 1 deletions
+150 -1
View File
@@ -100,7 +100,19 @@ function ADRunsController.updateRun(runId, changes)
local run = ADRuns.getRun(ADRunsController.store, runId)
local parts = {}
for key, value in pairs(changes) do
table.insert(parts, string.format("%s=%s", tostring(key), type(value) == "table" and table.concat(value, " ") or tostring(value)))
local text
if type(value) == "table" then
if key == "products" then
text = ADRuns.serializeProducts(value)
else
local items = {}
for _, item in ipairs(value) do table.insert(items, tostring(item)) end
text = table.concat(items, " ")
end
else
text = tostring(value)
end
table.insert(parts, string.format("%s=%s", tostring(key), text))
end
table.sort(parts)
Logging.info(ADRunsController.LOG_PREFIX .. "run '%s': %s", run ~= nil and tostring(run.name) or tostring(runId), table.concat(parts, ", "))
@@ -264,6 +276,132 @@ function ADRunsController.getVehicleLabel(adEnv, vehicle)
return tostring(vehicle:getName())
end
-- ---- bygninger (flow-tavlen): bygnings-id'er -> markører ----
local function listEquals(a, b)
if #a ~= #b then return false end
for index = 1, #a do
if a[index] ~= b[index] then return false end
end
return true
end
-- Udleder run'ets markørlister fra de valgte bygninger: udkørsel -> sourceWayPointIds (bygningens
-- læssemarkør), forsyning -> targetWayPointIds (aflæsningsmarkør). Markører der ikke hører til
-- nogen bygning ("rå", fra før flow-tavlen) bevares; markører der hører til en FRAVALGT bygning
-- fjernes. Returnerer {missing = {bygningsnavne uden markør}}. Store opdateres kun ved ændring.
function ADRunsController.resolveMarkers(adEnv, run)
local missing = {}
if ADBuildings == nil or run == nil then
return {missing = missing}
end
local farmId = g_currentMission:getFarmId()
local role = run.kind == "outbound" and "load" or "unload"
local buildingIds = run.kind == "outbound" and run.sourceBuildingIds or run.targetBuildingIds
local existing = run.kind == "outbound" and run.sourceWayPointIds or ADRunsController.getRunTargets(run)
local resolved, seen = {}, {}
for _, buildingId in ipairs(buildingIds or {}) do
local building = ADBuildings.find(adEnv, farmId, buildingId)
local marker = building ~= nil and (role == "load" and building.loadMarker or building.unloadMarker) or nil
if marker ~= nil then
if not seen[marker.id] then
seen[marker.id] = true
table.insert(resolved, marker.id)
end
else
table.insert(missing, building ~= nil and building.name or (tostring(buildingId) .. " (mangler)"))
end
end
for _, wayPointId in ipairs(existing or {}) do
if not seen[wayPointId] and ADBuildings.byMarker(adEnv, farmId, wayPointId, role) == nil then
seen[wayPointId] = true
table.insert(resolved, wayPointId)
end
end
if not listEquals(resolved, existing or {}) then
local changes = run.kind == "outbound" and {sourceWayPointIds = resolved} or {targetWayPointIds = resolved}
ADRunsController.store = ADRuns.updateRun(ADRunsController.store, run.id, changes)
local updated = ADRuns.getRun(ADRunsController.store, run.id)
if updated ~= nil then
run.sourceWayPointIds, run.targetWayPointIds, run.targetWayPointId = updated.sourceWayPointIds, updated.targetWayPointIds, updated.targetWayPointId
end
end
return {missing = missing}
end
-- Ved indlæsning: runs fra før flow-tavlen har kun markører — oversæt dem til bygninger, hvor
-- markøren er en bygnings læsse-/aflæsningsmarkør. Rå markører uden bygning beholdes.
function ADRunsController.migrateBuildings(adEnv)
if ADBuildings == nil then
return
end
local farmId = g_currentMission:getFarmId()
for _, run in ipairs(ADRunsController.store.runs) do
local role = run.kind == "outbound" and "load" or "unload"
local ids = copyList(run.kind == "outbound" and run.sourceBuildingIds or run.targetBuildingIds)
local known = {}
for _, id in ipairs(ids) do known[id] = true end
local added = {}
for _, wayPointId in ipairs(run.kind == "outbound" and run.sourceWayPointIds or ADRunsController.getRunTargets(run)) do
local building = ADBuildings.byMarker(adEnv, farmId, wayPointId, role)
if building ~= nil and not known[building.id] then
known[building.id] = true
table.insert(ids, building.id)
table.insert(added, building.name)
end
end
if #added > 0 then
local changes = run.kind == "outbound" and {sourceBuildingIds = ids} or {targetBuildingIds = ids}
ADRunsController.store = ADRuns.updateRun(ADRunsController.store, run.id, changes)
Logging.info(ADRunsController.LOG_PREFIX .. "run '%s': markører oversat til bygninger: %s", tostring(run.name), table.concat(added, ", "))
end
end
end
-- Data til én række i flow-tavlen (GUI'et formaterer teksten).
function ADRunsController.getFlowRow(adEnv, run)
local farmId = g_currentMission:getFarmId()
local row = {productNames = {}, productAuto = false, fromNames = {}, toNames = {}, fromAllSilos = run.kind ~= "outbound", missing = {}, policies = {}, vehicleNames = {}, collectRound = run.collectRound == true, sellAtPercent = run.sellAtPercent, storeAbovePercent = run.storeAbovePercent, loops = run.loops, kind = run.kind}
local ids = run.kind == "outbound" and run.sourceBuildingIds or run.targetBuildingIds
local names = run.kind == "outbound" and row.fromNames or row.toNames
for _, buildingId in ipairs(ids or {}) do
local building = ADBuildings ~= nil and ADBuildings.find(adEnv, farmId, buildingId) or nil
local marker = building ~= nil and (run.kind == "outbound" and building.loadMarker or building.unloadMarker) or nil
local name = building ~= nil and building.name or (tostring(buildingId) .. " (mangler)")
table.insert(names, name)
if marker == nil then table.insert(row.missing, name) end
end
-- rå markører (uden bygning) vises med markørnavn
local raw = run.kind == "outbound" and run.sourceWayPointIds or ADRunsController.getRunTargets(run)
for _, wayPointId in ipairs(raw or {}) do
if ADBuildings == nil or ADBuildings.byMarker(adEnv, farmId, wayPointId, run.kind == "outbound" and "load" or "unload") == nil then
local marker = adEnv.ADGraphManager.getMapMarkerByWayPointId ~= nil and adEnv.ADGraphManager:getMapMarkerByWayPointId(wayPointId) or nil
table.insert(names, marker ~= nil and ("markør '" .. tostring(marker.name) .. "'") or ("markør " .. tostring(wayPointId)))
end
end
if run.kind == "outbound" then
for _, product in ipairs(run.products or {}) do
table.insert(row.productNames, product.fillType)
table.insert(row.policies, product.policy)
end
local status = ADRunsController.getOutboundStatus(adEnv, run)
row.reason, row.warning = status.reasons[1], status.warning
else
row.productAuto = run.ingredientMode ~= "manual"
if not row.productAuto then
for _, name in ipairs(run.ingredients or {}) do table.insert(row.productNames, name) end
end
end
local vehiclesById = getFarmVehiclesById(adEnv)
for _, vehicleId in ipairs(run.vehicleIds) do
local vehicle = vehiclesById[vehicleId]
table.insert(row.vehicleNames, vehicle ~= nil and tostring(vehicle:getName()) or "?")
end
local status = ADRunsController.getRunStatus(adEnv, run)
row.running, row.total, row.isRunning = status.running, status.total, status.isRunning
return row
end
-- ---- validering ----
-- Liter-kapacitet for vognen; nil uden vogn. Universal Autoload opgiver ikke liter men ANTAL paller
@@ -406,6 +544,11 @@ local function getCargoTarget(adEnv, run, vehicle)
end
local function validateOutboundVehicle(adEnv, run, vehicle, result)
local resolved = ADRunsController.resolveMarkers(adEnv, run)
if resolved.missing[1] ~= nil then
result.reason, result.missingBuilding = "noMarker", resolved.missing[1]
return result
end
if #getRunSources(adEnv, run, ADSmartPickup.getFarmId(vehicle)) == 0 then
result.reason = "noSource"
return result
@@ -470,6 +613,11 @@ function ADRunsController.validateVehicle(adEnv, run, vehicle)
if run.kind == "outbound" then
return validateOutboundVehicle(adEnv, run, vehicle, result)
end
local resolvedIn = ADRunsController.resolveMarkers(adEnv, run)
if resolvedIn.missing[1] ~= nil then
result.reason, result.missingBuilding = "noMarker", resolvedIn.missing[1]
return result
end
local hasTarget = false
for _, wayPointId in ipairs(ADRunsController.getRunTargets(run)) do
if adEnv.ADGraphManager:getMapMarkerByWayPointId(wayPointId) ~= nil then
@@ -921,6 +1069,7 @@ function ADRunsController.load(adEnv)
return
end
ADRunsController.store = store
pcall(ADRunsController.migrateBuildings, adEnv)
local vehiclesById = getFarmVehiclesById(adEnv)
for _, run in ipairs(store.runs) do
for _, vehicleId in ipairs(run.vehicleIds) do