2020-05-02 09:40:31 +00:00
|
|
|
--[[
|
|
|
|
unique mapping
|
|
|
|
|
|
|
|
generate a mapping from unique values to plain numbers
|
|
|
|
useful for arbitrarily ordering things that don't have
|
|
|
|
a natural ordering in lua (eg textures for batching)
|
|
|
|
]]
|
2020-01-31 00:56:37 +00:00
|
|
|
|
|
|
|
local unique_mapping = {}
|
2020-03-15 10:22:22 +00:00
|
|
|
unique_mapping._mt = {
|
2020-01-31 00:56:37 +00:00
|
|
|
__index = unique_mapping,
|
|
|
|
__mode = "kv", --weak refs
|
|
|
|
}
|
|
|
|
|
|
|
|
--(used as storage for non-weak data)
|
|
|
|
local _MAP_VARS = setmetatable({}, {
|
|
|
|
__mode = "k" --only keys are weak
|
|
|
|
})
|
|
|
|
|
2020-05-02 09:40:31 +00:00
|
|
|
--create a new unique mapping
|
2020-01-31 00:56:37 +00:00
|
|
|
function unique_mapping:new()
|
2020-03-15 10:22:22 +00:00
|
|
|
local r = setmetatable({}, self._mt)
|
2020-01-31 00:56:37 +00:00
|
|
|
--set up the actual vars
|
|
|
|
_MAP_VARS[r] = {
|
|
|
|
current_index = 0,
|
|
|
|
}
|
|
|
|
return r
|
|
|
|
end
|
|
|
|
|
2020-05-02 09:40:31 +00:00
|
|
|
--private;
|
|
|
|
--get the next index for this mapping
|
2020-01-31 00:56:37 +00:00
|
|
|
function unique_mapping:_increment()
|
|
|
|
local vars = _MAP_VARS[self]
|
|
|
|
vars.current_index = vars.current_index + 1
|
|
|
|
return vars.current_index
|
|
|
|
end
|
|
|
|
|
2020-05-02 09:40:31 +00:00
|
|
|
--get or build a mapping for a passed value
|
2020-01-31 00:56:37 +00:00
|
|
|
function unique_mapping:map(value)
|
|
|
|
local val = self[value]
|
|
|
|
if val then
|
|
|
|
return val
|
|
|
|
end
|
|
|
|
local i = self:_increment()
|
|
|
|
self[value] = i
|
|
|
|
return i
|
|
|
|
end
|
|
|
|
|
2020-05-02 09:40:31 +00:00
|
|
|
--get a function representing an a < b comparision that can be used
|
|
|
|
--with table.sort and friends, like `table.sort(values, mapping:compare())`
|
|
|
|
function unique_mapping:compare()
|
|
|
|
-- memoised so it doesn't generate garbage, but also doesn't
|
|
|
|
-- allocate until it's actually used
|
|
|
|
if not self._compare then
|
|
|
|
self._compare = function(a, b)
|
|
|
|
return self:map(a) < self:map(b)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
return self._compare
|
|
|
|
end
|
|
|
|
|
2020-01-31 00:56:37 +00:00
|
|
|
return unique_mapping
|