perf(marker): markscanning som arbejdskø — højst ét prøvepunkt pr. frame (v1.27.2.0)

In-game 26/9: hakket kom sjældnere da scanningen gik fra 1 s til 2 s -> scanningen af én mark i ét frame
var årsagen (opslag gennemgår alle ~40 afgrødetyper pr. punkt). Coroutines findes ikke i FS25 (Giants
fjernede dem, jf. Courseplays HybridAStar), derfor en eksplicit kø. Tidsmåling bruger netGetTime.
Test (test_adFieldsScan) beviser: færdig, korrekt resultat, <= 3 opslag pr. frame.
This commit is contained in:
2026-09-26 10:38:51 +02:00
parent c34a472b1c
commit 05832603e4
7 changed files with 300 additions and 161 deletions
+76
View File
@@ -0,0 +1,76 @@
-- Kør: luajit tests/test_adFieldsScan.lua (fra repo-roden)
-- Markscanningen som arbejdskø: bliver færdig, giver rigtigt resultat, og intet frame laver mere end ét
-- prøvepunkts arbejde (in-game 26/9: en hel mark i ét frame gav hak).
local failures = 0
local function check(name, actual, expected)
if actual == expected then print("OK " .. name) else
failures = failures + 1
print(string.format("FAIL %s: forventede %s, fik %s", name, tostring(expected), tostring(actual)))
end
end
Logging = {warning = function(fmt, ...) print("WARN " .. string.format(fmt, ...)) end, info = function() end}
-- falsk verden: én mark (F7) med hvede der er klar, polygon med 4 hjørner
local GRASS, WHEAT = 1, 3
local nodes = {[101] = {0, 0}, [102] = {100, 0}, [103] = {100, 100}, [104] = {0, 100}}
function getWorldTranslation(node) local p = nodes[node]; return p[1], 0, p[2] end
function getTerrainHeightAtWorldPos() return 0 end
local calls = 0
FSDensityMapUtil = {
getFieldDataAtWorldPosition = function() calls = calls + 1; return 1, 6 end, -- på mark, vækststadie 6
getFruitTypeIndexAtWorldPos = function() calls = calls + 1; return WHEAT end,
getFruitArea = function(_, _, _, _, _, _, _, any) calls = calls + 1; return 0, any and 10 or 10 end,
}
FieldDensityMap = {SPRAY_LEVEL = 4, LIME_LEVEL = 5, PLOW_LEVEL = 6}
DensityCoordType = {POINT_VECTOR_VECTOR = 1}
DensityMapModifier = {new = function() return {setParallelogramWorldCoords = function() end, executeGet = function() calls = calls + 1; return 1, 1 end} end}
g_fruitTypeManager = {
getFruitTypeByIndex = function(_, index) return {name = index == WHEAT and "WHEAT" or "GRASS", fillType = {index = 50, title = "Hvede"}, minHarvestingGrowthState = 6, maxHarvestingGrowthState = 7, cutState = 9} end,
getConverterDataByName = function() return {} end,
}
g_fillTypeManager = {getConverterDataByName = function() return {} end, getFillTypeNameByIndex = function() return "X" end}
g_farmlandManager = {getFarmlandOwner = function() return 1 end}
local field = {getId = function() return 7 end, farmland = {id = 70}, polygonPoints = {101, 102, 103, 104}, posX = 50, posZ = 50}
g_fieldManager = {getFields = function() return {field} end}
g_currentMission = {terrainRootNode = 1, missionInfo = {}, fieldGroundSystem = {
getDensityMapData = function() return 1, 0, 2 end, getMaxValue = function() return 2 end}}
local adEnv = {ADGraphManager = {
getMapMarkers = function() return {{id = 900, name = "F7"}, {id = 901, name = "Silo"}} end,
getWayPointById = function(_, id) return {x = 40, z = 40} end,
}}
dofile("FS25_ADSmartPickup/adFields.lua")
local maxPerFrame, frames = 0, 0
local now = 0
for _ = 1, 200 do
calls = 0
ADFields.scanStep(adEnv, 1, now)
if calls > maxPerFrame then maxPerFrame = calls end
frames = frames + 1
now = now + 16
if ADFields.getInfo(7) ~= nil then break end
end
-- markliste først, så marken (efter SCAN_INTERVAL) — kør videre til marken er scannet
for _ = 1, 400 do
if ADFields.getInfo(7) ~= nil then break end
calls = 0
ADFields.scanStep(adEnv, 1, now)
if calls > maxPerFrame then maxPerFrame = calls end
now = now + 16
end
local info = ADFields.getInfo(7)
check("SC1 marken er scannet", info ~= nil, true)
check("SC2 afgrøde", info and info.fruitName, "WHEAT")
check("SC3 art = høst", info and info.kind, "harvest")
check("SC4 klar-andel", info and info.readyRatio, 1)
check("SC5 fase klar", info and info.phase, "ready")
check("SC6 markør F7", info and info.markerId, 900)
check("SC7 prøvepunkter", info and #info.points, 5)
check("SC8 gødning læst", info and info.fert, 1)
check("SC9 højst ét punkts arbejde pr. frame (<= 4 opslag)", maxPerFrame <= 4, true)
print(" (flest opslag i ét frame: " .. maxPerFrame .. ")")
check("SC10 marklisten", #ADFields.list(), 1)
print(failures == 0 and "\nALLE TESTS OK" or ("\n" .. failures .. " FEJL"))
os.exit(failures == 0 and 0 or 1)