You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

88 lines
3.7 KiB

local _,rematch = ...
local L = rematch.localization
local C = rematch.constants
rematch.odTable = {}
--[[
"On Demand" tables (odTables) are intended to be used as cache tables for more computationally expensive
data that's only infrequently used, such as collating pets in teams, getting sources for all species, etc.
The goal is for a process to start the table (either by odTable:Start() or a key lookup), when a pre-
defined function will populate the table (fillFunc), and then after 0.25 seconds (or C.ODTABLE_EXPIRE_TIME)
it will wipe itself automatically.
To create: local odTable = rematch.odTable:Create(fillFunc,isPersistent,expireTime)
-- fillFunc (optional) is a function to fill the table when it's started.
-- isPersistent (optional) is true if the table should never be wiped (very computationally expensive
-- fillFuncs should set this to true, such as defining a sourceID for all species)
-- expireTime (optional) is the time (in seconds) before stopping the table, or C.ODTABLE_EXPIRE_TIME
-- if this value is undefined.
When ready to use: odTable:Start() or get odTable.key
-- if a fillFunc is defined it will first run the function before returning the key's value
-- remember that pairs(odTable) isn't sufficient to trigger a lookup to start; use Start() then
When done with the table: odTable:Stop() (or do nothing and let 0.25 seconds elapse)
-- this will wipes the table so it's not sitting there for the rest of the session
]]
local lookup, startTable, stopTable
local allTables = {}
function rematch.odTable:Create(fillFunc,isPersistent,expireTime)
local odTable = {}
allTables[odTable] = {
isActive = false,
fillFunc = fillFunc,
isPersistent = isPersistent,
expireTime = expireTime or C.ODTABLE_EXPIRE_TIME,
start = function(self) startTable(odTable) end,
stop = function(self) stopTable(odTable) end
}
setmetatable(odTable,{__index=lookup})
return odTable
end
-- lookup function when the table's key has a value of nil
function lookup(self,key)
-- if odTable:Start() or odTable:Stop(), return the appropriate function
local thisTable = allTables[self]
if key=="Start" then
return thisTable.start
elseif key=="Stop" then
return thisTable.stop
end
-- looking up a missing key now, start if not already started (possibly run fillFunc if defined)
if not thisTable.isActive then
thisTable.start(self)
end
-- if the table started, then this key may be filled in now, return its value (if it exists)
return rawget(self,key)
end
-- called during lookup or via odTable:Start(), actives table, runs fillFunc if defined, and then
-- starts a timer to stop or expire the table
function startTable(self)
local thisTable = allTables[self]
if not thisTable.isActive then -- only activate if it wasn't activated before
thisTable.isActive = true
if thisTable.fillFunc then -- if table has a function to fill on start
thisTable.fillFunc(self) -- run it
end
end
-- if the table is not persistent, start a timer to stop it
if not thisTable.isPersistent then
rematch.timer:Start(thisTable.expireTime,thisTable.stop)
end
return self
end
-- called after expireTime has elapsed (or odTable:Stop()), wipes the table's contents and deactivates
function stopTable(self)
local thisTable = allTables[self]
wipe(self)
thisTable.isActive = false
rematch.timer:Stop(thisTable.stop) -- in case a Stop() call happened, don't let it wipe again after expiring
return self
end