91 lines
2.9 KiB
Lua
91 lines
2.9 KiB
Lua
--
|
|
local Proxy_table = {
|
|
registered_proxies = {},
|
|
tables_by_proxies = {},
|
|
proxy_children = {}
|
|
}
|
|
--setmetatable(Proxy_table.registered_proxies, {__mode="k"})
|
|
--setmetatable(Proxy_table.tables_by_proxies, {__mode="v"})
|
|
--setmetatable(Proxy_table.proxy_children, {__mode="k"})
|
|
|
|
leef.class.proxy_table = Proxy_table
|
|
--this creates proxy tables in a structure of tables
|
|
--this is great if you want to prevent the change of a table
|
|
--but still want it to be viewable, such as with constants
|
|
--og_table is the table which you want to be immutable. Parent is the parent proxy which it is apart of (this is optional and used for recursive parenting)
|
|
local tables_by_proxies = Proxy_table.tables_by_proxies
|
|
local metatable = {
|
|
__index = function(t, key)
|
|
local og_table = tables_by_proxies[t]
|
|
if type(og_table[key]) == "table" then
|
|
return Proxy_table:get_or_create(og_table[key], og_table.__proxy_table_parent)
|
|
else
|
|
return og_table[key]
|
|
end
|
|
end,
|
|
__newindex = function(table, key)
|
|
assert(false, "attempt to edit immutable table, cannot edit a proxy table (LEEF-class)")
|
|
end,
|
|
__len = function(t)
|
|
print("test")
|
|
return #tables_by_proxies[t]
|
|
end,
|
|
__testvar=true
|
|
}
|
|
|
|
function Proxy_table:new(og_table, parent)
|
|
local new = {
|
|
__proxy_table_parent = parent
|
|
}
|
|
self.registered_proxies[og_table] = new
|
|
self.tables_by_proxies[new] = og_table
|
|
if parent then
|
|
self.proxy_children[parent][og_table] = true
|
|
else
|
|
self.proxy_children[og_table] = {}
|
|
parent = og_table
|
|
end
|
|
--set the proxy's metatable
|
|
setmetatable(new, metatable)
|
|
--[[overwrite og_table meta to destroy the proxy aswell (but I realized it wont be GCed unless it's removed altogether, so this is pointless)
|
|
local mtable = getmetatable(og_table)
|
|
local old_gc = mtable.__gc
|
|
mtable.__gc = function(t)
|
|
self.registered_proxies[t] = nil
|
|
self.proxy_children[t] = nil
|
|
old_gc(t)
|
|
end
|
|
setmetatable(og_table, mtable)]]
|
|
--premake proxy tables
|
|
for i, v in pairs(og_table) do
|
|
if type(v) == "table" then
|
|
Proxy_table:get_or_create(v, parent)
|
|
end
|
|
end
|
|
return new
|
|
end
|
|
function Proxy_table:get_or_create(og_table, parent)
|
|
return self.registered_proxies[og_table] or Proxy_table:new(og_table, parent)
|
|
end
|
|
function Proxy_table:destroy_proxy(parent)
|
|
self.registered_proxies[parent] = nil
|
|
if self.proxy_children[parent] then
|
|
for i, v in pairs(self.proxy_children[parent]) do
|
|
Proxy_table:destroy_proxy(i)
|
|
end
|
|
end
|
|
self.proxy_children[parent] = nil
|
|
end
|
|
local proxies = Proxy_table.tables_by_proxies
|
|
local old_next = next
|
|
function next(t, i)
|
|
return old_next(proxies[t] or t, i)
|
|
end
|
|
local old_pairs = pairs
|
|
function pairs(t, ...)
|
|
return old_pairs(proxies[t] or t, ...)
|
|
end
|
|
local old_ipairs = ipairs
|
|
function ipairs(t, ...)
|
|
return old_ipairs(proxies[t] or t, ...)
|
|
end |