perf(kæde): priser slås kun op for kandidatmarker, fanen genbruger resultater under 30 s og kæden måles af profileren
This commit is contained in:
@@ -275,7 +275,7 @@ local function plan(data, state)
|
||||
if not data.fieldsIncomplete then
|
||||
shortages = ADCropPlan.shortages(chain.fieldDemand, data.stock, data.fields, data.yields)
|
||||
state.dismissed = ADChain.pruneDismissed(state.dismissed, shortages)
|
||||
actions = ADCropPlan.choose(shortages, data.fields, used, data.yields, data.prices, ADChain.dismissedFruits(state.dismissed))
|
||||
actions = ADCropPlan.choose(shortages, data.fields, used, data.yields, data.priceOf or data.prices, ADChain.dismissedFruits(state.dismissed))
|
||||
end
|
||||
-- de ægte opskrifter (ikke kopien): en pauset rod er stadig tændt og må ikke "tændes" og overtages af kæden
|
||||
local prod = ADChainActions.productions(data.recipes, chain.needRecipes, protected)
|
||||
@@ -326,6 +326,12 @@ function ADChain.evaluate(adEnv, act)
|
||||
return ADChain.last
|
||||
end
|
||||
|
||||
-- Alder (ms, spillets ur) af det sidste resultat; math.huge når der intet er. Fanen genbruger et friskt resultat.
|
||||
function ADChain.lastAge()
|
||||
if ADChain.last == nil then return math.huge end
|
||||
return ADChain.now - (ADChain.last.at or 0)
|
||||
end
|
||||
|
||||
function ADChain.tick(adEnv, dt)
|
||||
if adEnv == nil then return end
|
||||
ADChain.now = ADChain.now + (dt or 0)
|
||||
|
||||
@@ -141,6 +141,27 @@ local function readPlaceables(data, farmId, byChain, nameOf)
|
||||
table.sort(data.recipes, function(a, b) return a.key < b.key end)
|
||||
end
|
||||
|
||||
-- Markedspris for en afgrøde, først når kæden spørger (kun kandidatmarkernes afgrøder, kun ved mangel);
|
||||
-- hver afgrøde slås højst op én gang pr. læsning. Fejl -> 0 (logget én gang).
|
||||
local function priceResolver(data)
|
||||
local cache = {}
|
||||
return function(fruitName)
|
||||
if cache[fruitName] ~= nil then return cache[fruitName] end
|
||||
local index = data.fruitFillIndex[fruitName]
|
||||
local price = 0
|
||||
if index ~= nil then
|
||||
local ok, quote = pcall(ADSources.getMarketQuote, index)
|
||||
if ok then
|
||||
price = quote ~= nil and quote.price or 0
|
||||
else
|
||||
ADChainData.warnOnce("price:" .. tostring(fruitName), "pris for %s kunne ikke læses: %s", tostring(fruitName), tostring(quote))
|
||||
end
|
||||
end
|
||||
cache[fruitName] = price
|
||||
return price
|
||||
end
|
||||
end
|
||||
|
||||
local function readCrops(data, nameOf)
|
||||
local fruits = g_fruitTypeManager ~= nil and g_fruitTypeManager.fruitTypes or {}
|
||||
for _, fruit in ipairs(fruits) do
|
||||
@@ -151,8 +172,7 @@ local function readCrops(data, nameOf)
|
||||
if fruit.fillType.index ~= nil then nameOf(fruit.fillType.index) end
|
||||
data.crops[fillName] = fruit.name
|
||||
data.yields[fruit.name] = (tonumber(fruit.literPerSqm) or 0) * 10000
|
||||
local quote = fruit.fillType.index ~= nil and ADSources.getMarketQuote(fruit.fillType.index) or nil
|
||||
data.prices[fruit.name] = quote ~= nil and quote.price or 0
|
||||
data.fruitFillIndex[fruit.name] = fruit.fillType.index
|
||||
end)
|
||||
if not ok then failed(data, "fruit:" .. tostring(fruit.name), "afgrøde %s kunne ikke læses: %s", tostring(fruit.name), tostring(err)) end
|
||||
end
|
||||
@@ -169,7 +189,8 @@ local function readStock(data, adEnv, farmId, nameOf)
|
||||
if not ok then failed(data, "stock", "lager kunne ikke læses: %s", tostring(err)) end
|
||||
end
|
||||
|
||||
-- Afgrøder gården selv bruger: input i en tændt produktion eller foder/halm i en stald.
|
||||
-- Afgrøder gården selv bruger: input i en tændt produktion eller foder/halm i en stald (kun staldenes forbrug
|
||||
-- læses: feedOnly springer fabrikkernes rater over — dem dækker opskrifterne allerede).
|
||||
local function readUsedFruits(data, adEnv, farmId, nameOf)
|
||||
for _, recipe in ipairs(data.recipes) do
|
||||
if recipe.enabled then
|
||||
@@ -179,7 +200,7 @@ local function readUsedFruits(data, adEnv, farmId, nameOf)
|
||||
end
|
||||
end
|
||||
local ok, err = pcall(function()
|
||||
for index, rate in pairs(ADSources.getFarmRates(adEnv, farmId) or {}) do
|
||||
for index, rate in pairs(ADSources.getFarmRates(adEnv, farmId, true) or {}) do
|
||||
local fruit = data.crops[nameOf(index) or ""]
|
||||
if fruit ~= nil and (rate.consumption or 0) > 0 then data.usedFruits[fruit] = true end
|
||||
end
|
||||
@@ -216,9 +237,10 @@ end
|
||||
-- data.partial = true når noget ikke kunne læses i dette kald; data.fieldsIncomplete = true mens markscanningen
|
||||
-- ikke har nået alle marker.
|
||||
function ADChainData.collect(adEnv, farmId, byChain)
|
||||
local data = {recipes = {}, husbandry = {}, crops = {}, stock = {}, fields = {}, yields = {}, prices = {},
|
||||
local data = {recipes = {}, husbandry = {}, crops = {}, stock = {}, fields = {}, yields = {}, fruitFillIndex = {},
|
||||
usedFruits = {}, points = {}, fillTitles = {}, fillIndex = {}}
|
||||
local nameOf = nameResolver(data)
|
||||
data.priceOf = priceResolver(data)
|
||||
readPlaceables(data, farmId, byChain, nameOf)
|
||||
readCrops(data, nameOf)
|
||||
readStock(data, adEnv, farmId, nameOf)
|
||||
|
||||
@@ -110,6 +110,8 @@ function ADProfiler.install()
|
||||
{ADSources, "getFarmInventory", "gårdens lagre"},
|
||||
{ADWaitPool, "hasRouteTo", "rutetjek"},
|
||||
{ADWaitPool, "hasRouteBothWays", "rutetjek frem+tilbage"},
|
||||
{ADChain, "evaluate", "kæde"},
|
||||
{ADChainData, "collect", "kæde: læs gården"},
|
||||
}
|
||||
for _, target in ipairs(targets) do
|
||||
ADProfiler.wrap(target[1], target[2], target[3])
|
||||
|
||||
@@ -1,22 +1,15 @@
|
||||
-- Smart Pickup — fanen Kæder
|
||||
-- Produktionskæderne som træ: rod (produktion spilleren har tændt) -> varer -> råvarer, med kilde, behov pr.
|
||||
-- måned og flowstatus; afgrødeforslag kan godkendes/afvises og en rod sættes på pause. Rækkerne bygges af
|
||||
-- ADChainView (testet); her kun kloning, farve og klik. Evaluering højst hvert CHAIN_EVALUATE_MS (visning, handler ikke).
|
||||
-- ADChainView (testet); her kun kloning, farve og klik. Et resultat yngre end CHAIN_MAX_AGE_MS (fra kædens eget
|
||||
-- tick eller en tidligere visning) genbruges; ellers evalueres (visning, handler ikke). Klik evaluerer altid.
|
||||
|
||||
SmartPickupFrame.CHAIN_EVALUATE_MS = 5000
|
||||
|
||||
-- Spillets ur i ms; uden g_time evalueres ved hver opbygning (der kun sker hvert CHAIN_REBUILD_TICKS s).
|
||||
local function nowMs()
|
||||
return type(g_time) == "number" and g_time or nil
|
||||
end
|
||||
SmartPickupFrame.CHAIN_MAX_AGE_MS = 30000
|
||||
|
||||
function SmartPickupFrame:chainLast(adEnv, force)
|
||||
local now = nowMs()
|
||||
local due = force or ADChain.last == nil or now == nil or self.chainEvaluatedAt == nil
|
||||
or now - self.chainEvaluatedAt >= SmartPickupFrame.CHAIN_EVALUATE_MS
|
||||
if due then
|
||||
local age = ADChain.lastAge ~= nil and ADChain.lastAge() or math.huge
|
||||
if force or ADChain.last == nil or age >= SmartPickupFrame.CHAIN_MAX_AGE_MS then
|
||||
ADChain.evaluate(adEnv)
|
||||
self.chainEvaluatedAt = now
|
||||
end
|
||||
return ADChain.last
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user