Fix recursive tracking
This commit is contained in:
parent
5b11cb12f5
commit
053b59cf00
26
logging.lua
26
logging.lua
@ -73,7 +73,7 @@ end
|
|||||||
|
|
||||||
local RecursionSentinel = {}
|
local RecursionSentinel = {}
|
||||||
function RecursionSentinel.make(table, index)
|
function RecursionSentinel.make(table, index)
|
||||||
local obj = { table = table }
|
local obj = { table = table, index = index }
|
||||||
setmetatable(obj, RecursionSentinel)
|
setmetatable(obj, RecursionSentinel)
|
||||||
return obj
|
return obj
|
||||||
end
|
end
|
||||||
@ -87,42 +87,38 @@ function RecursionSentinel.isKnown(knownTables, value)
|
|||||||
end
|
end
|
||||||
|
|
||||||
function RecursionSentinel.getSentinel(knownTables, value)
|
function RecursionSentinel.getSentinel(knownTables, value)
|
||||||
local sentinel = knownTables[value]
|
return knownTables[value] or RecursionSentinel.add(knownTables, value)
|
||||||
if sentinel == nil then
|
|
||||||
sentinel = knownTables[value]
|
|
||||||
knownTables[#knownTables+1] = value
|
|
||||||
knownTables[value] = RecursionSentinel.make(value, #knownTables)
|
|
||||||
end
|
|
||||||
return sentinel
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function RecursionSentinel.add(knownTables, value)
|
function RecursionSentinel.add(knownTables, value)
|
||||||
local sentinel = RecursionSentinel.make(value)
|
local sentinel = RecursionSentinel.make(value, #knownTables)
|
||||||
knownTables[value] = sentinel
|
knownTables[value] = sentinel
|
||||||
return sentinel
|
return sentinel
|
||||||
end
|
end
|
||||||
|
|
||||||
function RecursionSentinel.pop(knownTables)
|
function RecursionSentinel.remove(knownTables, value)
|
||||||
local value = knownTables[#knownTables]
|
local sentinel = knownTables[value]
|
||||||
knownTables[#knownTables] = nil
|
if sentinel then
|
||||||
|
sentinel.index = nil
|
||||||
|
end
|
||||||
knownTables[value] = nil
|
knownTables[value] = nil
|
||||||
end
|
end
|
||||||
|
|
||||||
local function cloneNonRecursive(value, sentinels)
|
local function cloneNonRecursive(value, sentinels)
|
||||||
if type(value) == "table" then
|
if type(value) == "table" then
|
||||||
|
local sentinel = RecursionSentinel.getSentinel(sentinels, value)
|
||||||
if RecursionSentinel.isKnown(sentinels, value) then
|
if RecursionSentinel.isKnown(sentinels, value) then
|
||||||
return RecursionSentinel.getSentinel(sentinels, value)
|
return sentinel
|
||||||
end
|
end
|
||||||
|
|
||||||
local clone = {}
|
local clone = {}
|
||||||
local sentinel = RecursionSentinel.add(sentinels, value)
|
|
||||||
for i,v in ipairs(value) do
|
for i,v in ipairs(value) do
|
||||||
clone[i] = cloneNonRecursive(v, sentinels)
|
clone[i] = cloneNonRecursive(v, sentinels)
|
||||||
end
|
end
|
||||||
for k,v in pairs(value) do
|
for k,v in pairs(value) do
|
||||||
clone[cloneNonRecursive(k, sentinels)] = cloneNonRecursive(v, sentinels)
|
clone[cloneNonRecursive(k, sentinels)] = cloneNonRecursive(v, sentinels)
|
||||||
end
|
end
|
||||||
RecursionSentinel.pop(sentinels)
|
RecursionSentinel.remove(sentinels, sentinel.table)
|
||||||
|
|
||||||
sentinel.value = clone
|
sentinel.value = clone
|
||||||
return sentinel.value
|
return sentinel.value
|
||||||
|
Loading…
x
Reference in New Issue
Block a user