feat(marksilo): opsætningsmodel (til/fra, gårdlagre, x 1-10, tærskel) + records
This commit is contained in:
@@ -0,0 +1,76 @@
|
|||||||
|
-- AD Field Silo Config
|
||||||
|
-- Marksilo-flowets opsætning som ren model (ny tabel ud, input muteres ikke) + flade records til XML-laget.
|
||||||
|
|
||||||
|
ADFieldSiloConfig = {}
|
||||||
|
|
||||||
|
ADFieldSiloConfig.MAX_VEHICLES = 10
|
||||||
|
ADFieldSiloConfig.DEFAULT_MAX_VEHICLES = 2
|
||||||
|
ADFieldSiloConfig.MIN_LITERS_CHOICES = {5000, 10000, 25000, 50000}
|
||||||
|
ADFieldSiloConfig.DEFAULT_MIN_LITERS = 10000
|
||||||
|
|
||||||
|
local function copy(cfg)
|
||||||
|
local ids = {}
|
||||||
|
for index, id in ipairs(cfg.storeIds or {}) do ids[index] = id end
|
||||||
|
return {enabled = cfg.enabled == true, storeIds = ids, maxVehicles = cfg.maxVehicles, minLiters = cfg.minLiters}
|
||||||
|
end
|
||||||
|
|
||||||
|
local function clampVehicles(value)
|
||||||
|
value = tonumber(value) or ADFieldSiloConfig.DEFAULT_MAX_VEHICLES
|
||||||
|
return math.max(1, math.min(ADFieldSiloConfig.MAX_VEHICLES, math.floor(value)))
|
||||||
|
end
|
||||||
|
|
||||||
|
local function snapLiters(value)
|
||||||
|
value = tonumber(value)
|
||||||
|
if value == nil then return ADFieldSiloConfig.DEFAULT_MIN_LITERS end
|
||||||
|
local best, bestDiff = nil, nil
|
||||||
|
for _, choice in ipairs(ADFieldSiloConfig.MIN_LITERS_CHOICES) do
|
||||||
|
local diff = math.abs(choice - value)
|
||||||
|
if bestDiff == nil or diff < bestDiff then best, bestDiff = choice, diff end
|
||||||
|
end
|
||||||
|
return best
|
||||||
|
end
|
||||||
|
|
||||||
|
function ADFieldSiloConfig.new()
|
||||||
|
return {enabled = false, storeIds = {}, maxVehicles = ADFieldSiloConfig.DEFAULT_MAX_VEHICLES, minLiters = ADFieldSiloConfig.DEFAULT_MIN_LITERS}
|
||||||
|
end
|
||||||
|
|
||||||
|
function ADFieldSiloConfig.with(cfg, changes)
|
||||||
|
local new = copy(cfg)
|
||||||
|
if changes.enabled ~= nil then new.enabled = changes.enabled == true end
|
||||||
|
if changes.maxVehicles ~= nil then new.maxVehicles = clampVehicles(changes.maxVehicles) end
|
||||||
|
if changes.minLiters ~= nil then new.minLiters = snapLiters(changes.minLiters) end
|
||||||
|
return new
|
||||||
|
end
|
||||||
|
|
||||||
|
function ADFieldSiloConfig.hasStore(cfg, id)
|
||||||
|
for _, storeId in ipairs(cfg.storeIds or {}) do
|
||||||
|
if storeId == id then return true end
|
||||||
|
end
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
function ADFieldSiloConfig.toggleStore(cfg, id)
|
||||||
|
local new = copy(cfg)
|
||||||
|
local kept, found = {}, false
|
||||||
|
for _, storeId in ipairs(new.storeIds) do
|
||||||
|
if storeId == id then found = true else table.insert(kept, storeId) end
|
||||||
|
end
|
||||||
|
if not found then table.insert(kept, id) end
|
||||||
|
new.storeIds = kept
|
||||||
|
return new
|
||||||
|
end
|
||||||
|
|
||||||
|
function ADFieldSiloConfig.toRecord(cfg)
|
||||||
|
return {enabled = cfg.enabled and 1 or 0, stores = table.concat(cfg.storeIds or {}, " "),
|
||||||
|
maxVehicles = cfg.maxVehicles, minLiters = cfg.minLiters}
|
||||||
|
end
|
||||||
|
|
||||||
|
function ADFieldSiloConfig.fromRecord(record)
|
||||||
|
local cfg = ADFieldSiloConfig.new()
|
||||||
|
if record == nil then return cfg end
|
||||||
|
for token in string.gmatch(tostring(record.stores or ""), "%S+") do table.insert(cfg.storeIds, token) end
|
||||||
|
cfg.enabled = tonumber(record.enabled) == 1
|
||||||
|
cfg.maxVehicles = clampVehicles(record.maxVehicles)
|
||||||
|
cfg.minLiters = snapLiters(record.minLiters)
|
||||||
|
return cfg
|
||||||
|
end
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
-- Kør: luajit tests/test_adFieldSiloConfig.lua (fra repo-roden)
|
||||||
|
dofile("FS25_ADSmartPickup/adFieldSiloConfig.lua")
|
||||||
|
local C = ADFieldSiloConfig
|
||||||
|
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
|
||||||
|
local cfg = C.new()
|
||||||
|
check("standard fra", cfg.enabled, false)
|
||||||
|
check("standard x=2", cfg.maxVehicles, 2)
|
||||||
|
check("standard tærskel 10000", cfg.minLiters, 10000)
|
||||||
|
check("x under 1 -> 1", C.with(cfg, {maxVehicles = 0}).maxVehicles, 1)
|
||||||
|
check("x over 10 -> 10", C.with(cfg, {maxVehicles = 99}).maxVehicles, 10)
|
||||||
|
check("tærskel snappes til nærmeste valg", C.with(cfg, {minLiters = 12000}).minLiters, 10000)
|
||||||
|
check("tærskel 40000 -> 50000", C.with(cfg, {minLiters = 40000}).minLiters, 50000)
|
||||||
|
check("with muterer ikke", cfg.maxVehicles, 2)
|
||||||
|
local on = C.toggleStore(cfg, "silo1")
|
||||||
|
check("toggle til", C.hasStore(on, "silo1"), true)
|
||||||
|
check("toggle muterer ikke", C.hasStore(cfg, "silo1"), false)
|
||||||
|
check("toggle fra", C.hasStore(C.toggleStore(on, "silo1"), "silo1"), false)
|
||||||
|
local full = C.with(C.toggleStore(C.toggleStore(cfg, "a"), "b"), {enabled = true, maxVehicles = 4, minLiters = 25000})
|
||||||
|
local back = C.fromRecord(C.toRecord(full))
|
||||||
|
check("record: enabled", back.enabled, true)
|
||||||
|
check("record: lagre", table.concat(back.storeIds, " "), "a b")
|
||||||
|
check("record: x", back.maxVehicles, 4)
|
||||||
|
check("record: tærskel", back.minLiters, 25000)
|
||||||
|
check("tom record -> standard", C.fromRecord(nil).maxVehicles, 2)
|
||||||
|
check("record uden tal -> standard tærskel", C.fromRecord({enabled = 1}).minLiters, 10000)
|
||||||
|
print(failures == 0 and "\nALLE TESTS OK" or ("\n" .. failures .. " FEJL"))
|
||||||
|
os.exit(failures == 0 and 0 or 1)
|
||||||
Reference in New Issue
Block a user