-- manager/state.lua — Shared mutable state, cache, and coordination flags -- Usage: local state = dofile("manager/state.lua")() return function() local S = {} ------------------------------------------------- -- Cached data (updated by background scanner) ------------------------------------------------- S.cache = { catalogue = {}, itemList = {}, itemListDirty = false, grandTotal = 0, chestCount = 0, totalSlots = 0, usedSlots = 0, freeSlots = 0, usedRatio = 0, dropperOk = false, barrelOk = false, furnaceCount = 0, furnaceStatus = {}, droppers = {}, } -- Client-registered droppers, keyed by clientId S.clientDroppers = {} ------------------------------------------------- -- Activity flags (shown on monitor) ------------------------------------------------- S.activity = { sorting = false, dispensing = false, scanning = false, smelting = false, defragging = false, composting = false, crafting = false, discarding = false, autocrafting = false, } ------------------------------------------------- -- State version tracking (for delta broadcasting) ------------------------------------------------- S.stateVersion = 0 S.lastBroadcastVersion = -1 S.configDirty = true function S.bumpStateVersion() S.stateVersion = S.stateVersion + 1 S.billboardNeedsRedraw = true end ------------------------------------------------- -- UI coordination flags ------------------------------------------------- S.needsRedraw = true S.smelterNeedsRedraw = true S.billboardNeedsRedraw = true S.statusMessage = "" S.statusColor = colors.white S.statusTimer = 0 ------------------------------------------------- -- Alerts and smelting control ------------------------------------------------- S.activeAlerts = {} S.smeltingPaused = false S.disabledRecipes = {} ------------------------------------------------- -- Instant cache adjustment (no scan needed) ------------------------------------------------- function S.adjustCache(itemName, chestName, delta) if delta == 0 then return end local cat = S.cache.catalogue if delta > 0 then if not cat[itemName] then cat[itemName] = {} end local found = false for _, entry in ipairs(cat[itemName]) do if entry.chest == chestName then entry.total = entry.total + delta found = true break end end if not found then table.insert(cat[itemName], { chest = chestName, total = delta }) end else if cat[itemName] then for idx, entry in ipairs(cat[itemName]) do if entry.chest == chestName then entry.total = entry.total + delta if entry.total <= 0 then table.remove(cat[itemName], idx) end break end end if #cat[itemName] == 0 then cat[itemName] = nil end end end S.cache.itemListDirty = true S.cache.grandTotal = S.cache.grandTotal + delta S.bumpStateVersion() end function S.ensureItemList() if not S.cache.itemListDirty then return end local itemList = {} local grandTotal = 0 for name, sources in pairs(S.cache.catalogue) do local total = 0 for _, s in ipairs(sources) do total = total + s.total end grandTotal = grandTotal + total table.insert(itemList, { name = name, total = total }) end table.sort(itemList, function(a, b) return a.total > b.total end) S.cache.itemList = itemList S.cache.grandTotal = grandTotal S.cache.itemListDirty = false end return S end