Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- ---[ PRIVATE ]-----------------------------------------------------------------
- local tostring, pairs, insert
- = tostring, pairs, table.insert
- local StringBuilder
- = xs_text.StringBuilder
- local check, toWeakTable
- = xs_utils.check, xs_utils.toWeakTable
- local bit_or, bit_and
- = bit_or, bit_and
- ---[ PUBLIC ]------------------------------------------------------------------
- __FILE__ = "xs_cache"
- class "Cache" (XsObj)
- function Cache:__init() super("Cache")
- self.values = toWeakTable({}, "k")
- self.builders = {}
- end
- function Cache:__tostring()
- if self:IsEmpty() then
- return string.format("%s [%08X] (#0)\n", self.__cls, self.__uid)
- end
- local buffer = StringBuilder()
- buffer:AppendFormat("%s [%08X] (#%d)\n", self.__cls, self.__uid, self:Count()):IncreaseIndent()
- for k, _ in pairs(self.builders) do
- buffer:AppendLine("[", tostring(k), "] = ", tostring(self.values[k]))
- end
- return buffer:ToString()
- end
- function Cache:__len()
- return #self.builders
- end
- function Cache:Count()
- return #self.builders
- end
- function Cache:IsEmpty()
- return #self.builders == 0
- end
- function Cache:Clear()
- self.values = toWeakTable({}, "k")
- self.builders = {}
- end
- function Cache:Register(key, builder)
- check(key ~= nil, "[Cache:Add] argument #1 cannot be nil.")
- check(type(builder) == "function", "[Cache:Add] argument #2 has to be a function")
- self.builders[key] = builder
- end
- function Cache:Unregister(key)
- check(key ~= nil, "[Cache:Remove] argument #1 cannot be nil.")
- if self.builders[key] == nil then
- return false
- end
- self.builders[key] = nil
- self.values[key] = nil
- return true
- end
- function Cache:Request(key, ...)
- -- check(key ~= nil, "[Cache:Request] argument #1 cannot be nil.")
- local value = self.values[key]
- if value == nil then
- value = self.builders[key](...)
- self.values[key] = value
- end
- return value
- end
- function Cache:Update(key, value)
- -- check(key ~= nil, "[Cache:Update] argument #1 cannot be nil.")
- -- check(self.builder[key] == nil, sprintf("[Cache:Update] Cannot update non-registered key %q.", key))
- self.values[key] = value
- end
- function Cache:Contains(key)
- -- check(key ~= nil, "[Cache:Contains] argument #1 cannot be nil.")
- return self.builders[key] ~= nil
- end
- -- These state values exist as to avoid comparing potentially large and complex data.
- -- The code would be simpler without that 'optimization' though.
- -- So, it may be worth benchmarking this and maybe revert to ComputeCache's previous revision.
- local CC_STATE_DEFAULT = 0
- local CC_STATE_INVALID = 1
- local CC_STATE_UPDATED = 2
- class "ComputeCache" (XsObj)
- function ComputeCache:__init() super("ComputeCache")
- self.signature = nil
- self.result = nil
- self.state = CC_STATE_DEFAULT
- end
- function ComputeCache:IsInvalid(...)
- if bit_and(self.state, CC_STATE_INVALID) ~= 0 or self.signature == nil then
- return true
- end
- local params = { ... }
- if #self.signature ~= #params then
- self.state = CC_STATE_INVALID
- return true
- end
- for i = 1, #params do
- if params[i] ~= self.signature[i] then
- self.state = CC_STATE_INVALID
- return true
- end
- end
- return false
- end
- function ComputeCache:Update(...)
- self.signature = toWeakTable({ ... }, "k")
- self.state = bit_or(self.state, CC_STATE_UPDATED + CC_STATE_INVALID)
- end
- function ComputeCache:SetResult(result)
- if bit_and(self.state, CC_STATE_UPDATED) == 0 then
- self.state = bit_or(self.state, CC_STATE_INVALID)
- else
- self.state = CC_STATE_DEFAULT
- end
- self.result = result
- end
- function ComputeCache:GetResult(result)
- return self.result
- end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement