fix: slut-review — pcall om start/dialoger, Auto-varer fra aktivt AD-mål, nil-guards, README

This commit is contained in:
2026-09-22 23:35:47 +02:00
parent b74d1325c6
commit 856b949749
7 changed files with 99 additions and 27 deletions
+9 -6
View File
@@ -53,12 +53,15 @@ function ADLoadSwap.findDumpMarker(adEnv, vehicle, fillType, rest, homeWayPointI
local station = ADSmartPickup.getUnloadStationAtWayPointId(adEnv, marker.id, farmId)
if station ~= nil and isSilo(station, homeStation) and acceptsRest(station, fillType, rest, farmId) then
local wayPoint = adEnv.ADGraphManager:getWayPointById(marker.id)
local dx, dz = wayPoint.x - x, wayPoint.z - z
table.insert(candidates, {
marker = marker,
hasFillType = ADSmartPickup.getOwnStorageLevel(station, {fillType}) > 0,
distance = dx * dx + dz * dz,
})
-- En markør uden waypoint (stale AD-graf) skal springes over, ikke crashe hele opslaget.
if wayPoint ~= nil then
local dx, dz = wayPoint.x - x, wayPoint.z - z
table.insert(candidates, {
marker = marker,
hasFillType = ADSmartPickup.getOwnStorageLevel(station, {fillType}) > 0,
distance = dx * dx + dz * dz,
})
end
end
end
table.sort(candidates, function(a, b)
+33 -9
View File
@@ -112,7 +112,20 @@ end
-- findSupplyPickup selv til de ønskede produktioners inputs bagefter.
function ADRunsController.getTargetFillTypes(adEnv, run, vehicle)
local farmId = ADSmartPickup.getFarmId(vehicle)
local target = run.targetWayPointId ~= nil and ADSmartPickup.getUnloadStationAtWayPointId(adEnv, run.targetWayPointId, farmId) or nil
-- En kørende traktor følger AD's eget mål (stateModule:getSecondMarker(), det samme
-- choosePickup/findSupplyPickup bruger) indtil næste Start — IKKE run'ets gemte
-- targetWayPointId. Redigerer brugeren run'ets Mål mens tildelte traktorer kører,
-- skal Auto-listen derfor følge det LIVE mål, ellers kan den blive tom og fejlagtigt
-- smide traktoren over i mappe-logikken midt i turen.
local wayPointId = run.targetWayPointId
local stateModule = vehicle.ad ~= nil and vehicle.ad.stateModule or nil
if stateModule ~= nil and stateModule.isActive ~= nil and stateModule:isActive() and stateModule.getSecondMarker ~= nil then
local secondMarker = stateModule:getSecondMarker()
if secondMarker ~= nil and secondMarker.id ~= nil then
wayPointId = secondMarker.id
end
end
local target = wayPointId ~= nil and ADSmartPickup.getUnloadStationAtWayPointId(adEnv, wayPointId, farmId) or nil
if target == nil then
return {}
end
@@ -251,10 +264,14 @@ local function findNearestLoadMarker(adEnv, vehicle, farmId)
for _, marker in pairs(adEnv.ADGraphManager:getMapMarkers()) do
if ADSmartPickup.getLoadStationAtWayPointId(adEnv, marker.id, farmId) ~= nil then
local wayPoint = adEnv.ADGraphManager:getWayPointById(marker.id)
local dx, dz = wayPoint.x - x, wayPoint.z - z
local distance = dx * dx + dz * dz
if distance < bestDistance then
best, bestDistance = marker, distance
-- En stale markør uden waypoint skal springes over — ellers fejler Start med "error"
-- for ALLE tildelte traktorer, ikke kun den der ramte den ugyldige markør.
if wayPoint ~= nil then
local dx, dz = wayPoint.x - x, wayPoint.z - z
local distance = dx * dx + dz * dz
if distance < bestDistance then
best, bestDistance = marker, distance
end
end
end
end
@@ -284,6 +301,16 @@ local function isVehicleActive(vehicle)
return stateModule ~= nil and stateModule.isActive ~= nil and stateModule:isActive()
end
-- Anvend run-tilstand OG start traktoren i ét pcall'et kald: kaster vehicle:startAutoDrive()
-- (fx AD's egen validering), skal den ene traktor fejle uden at hele startRun-loopet
-- afbrydes — ellers når de øvrige tildelte traktorer aldrig at blive startet.
local function applyAndStart(adEnv, run, vehicle, ingredients)
applyRunToVehicle(adEnv, run, vehicle, ingredients)
if not isVehicleActive(vehicle) then
vehicle:startAutoDrive()
end
end
-- Pr. tildelt traktor: validér, skriv AD-tilstand, start. ✖-traktorer springes over.
function ADRunsController.startRun(adEnv, runId)
local run = ADRuns.getRun(ADRunsController.store, runId)
@@ -299,11 +326,8 @@ function ADRunsController.startRun(adEnv, runId)
local result = {vehicle = vehicle, ok = validation.ok, reason = validation.reason}
if validation.ok then
local ingredients = ADRunsController.getRunIngredients(adEnv, run, vehicle)
local ok, err = pcall(applyRunToVehicle, adEnv, run, vehicle, ingredients)
local ok, err = pcall(applyAndStart, adEnv, run, vehicle, ingredients)
if ok then
if not isVehicleActive(vehicle) then
vehicle:startAutoDrive()
end
Logging.info(ADRunsController.LOG_PREFIX .. "run '%s': '%s' startet mod markør %s", tostring(run.name), tostring(vehicle:getName()), tostring(run.targetWayPointId))
else
result.ok, result.reason = false, "error"
+13 -6
View File
@@ -424,9 +424,13 @@ function SmartPickupFrame:onClickNew()
end
function SmartPickupFrame:onClickRename()
local run = self:getRun()
if run == nil then return end
TextInputDialog.show(SmartPickupFrame.onRenameResult, self, run.name, self.i18n:getText("spu_renameTitle"), nil, 30, g_i18n:getText("button_ok"))
-- Dialogen kan kaste (fx manglende i18n-nøgle) — fang det som resten af GUI'et, i stedet
-- for at lade fejlen undslippe klik-callbacken uden statuslinje-besked.
self:safe(function(frame)
local run = frame:getRun()
if run == nil then return end
TextInputDialog.show(SmartPickupFrame.onRenameResult, frame, run.name, frame.i18n:getText("spu_renameTitle"), nil, 30, g_i18n:getText("button_ok"))
end)
end
function SmartPickupFrame:onRenameResult(value, clickOk)
@@ -440,9 +444,12 @@ function SmartPickupFrame:onRenameResult(value, clickOk)
end
function SmartPickupFrame:onClickDelete()
local run = self:getRun()
if run == nil then return end
YesNoDialog.show(SmartPickupFrame.onDeleteResult, self, string.format(self.i18n:getText("spu_deleteConfirm"), run.name), self.i18n:getText("spu_button_delete"))
-- Samme begrundelse som onClickRename: dialog-opkaldet skal ikke kunne undslippe uden om safe().
self:safe(function(frame)
local run = frame:getRun()
if run == nil then return end
YesNoDialog.show(SmartPickupFrame.onDeleteResult, frame, string.format(frame.i18n:getText("spu_deleteConfirm"), run.name), frame.i18n:getText("spu_button_delete"))
end)
end
function SmartPickupFrame:onDeleteResult(yes)
-1
View File
@@ -22,7 +22,6 @@
<text name="spu_vehicle_tooltip" text="Ja = traktoren er med i dette run."/>
<text name="spu_waitPools" text="Wait-puljer"/>
<text name="spu_waitPoolRow" text="%s — %d punkter — %d optaget%s"/>
<text name="spu_status" text="Status"/>
<text name="spu_status_running" text="Kører (%d/%d)"/>
<text name="spu_status_stopped" text="Stoppet (%d traktorer)"/>
<text name="spu_status_started" text="Startet %d, sprunget over %d"/>
-1
View File
@@ -22,7 +22,6 @@
<text name="spu_vehicle_tooltip" text="Yes = the tractor belongs to this run."/>
<text name="spu_waitPools" text="Wait pools"/>
<text name="spu_waitPoolRow" text="%s — %d points — %d occupied%s"/>
<text name="spu_status" text="Status"/>
<text name="spu_status_running" text="Running (%d/%d)"/>
<text name="spu_status_stopped" text="Stopped (%d tractors)"/>
<text name="spu_status_started" text="Started %d, skipped %d"/>