129 lines
3.0 KiB
Lua
129 lines
3.0 KiB
Lua
local this = {}
|
|
|
|
local getmetatable, setmetatable, type, rawget, rawset = getmetatable, setmetatable, type, rawget, rawset
|
|
|
|
function this.uses(obj, name)
|
|
return getmetatable(obj) == this[name]
|
|
end
|
|
|
|
function this.use(obj, name)
|
|
if type(obj) == "table" then
|
|
rawset(obj, "__mt", name)
|
|
return setmetatable(obj, this[name])
|
|
end
|
|
end
|
|
|
|
function this.set(obj, name) -- not persistent
|
|
if type(obj) == "table" then
|
|
return setmetatable(obj, this[name])
|
|
end
|
|
end
|
|
|
|
function this.new(name)
|
|
return setmetatable({ __mt = name }, this[name])
|
|
end
|
|
|
|
function this.refresh(obj)
|
|
if type(obj) == "table" and not obj.__self then
|
|
for key,val in pairs(obj) do
|
|
this.refresh(val)
|
|
end
|
|
|
|
local name = rawget(obj, "__mt")
|
|
if type(name) == "string" then
|
|
local mt = this[name]
|
|
if mt then return setmetatable(obj, mt) end
|
|
end
|
|
end
|
|
end
|
|
|
|
this.entityAsIndex = { -- metatable for using an entity as a table index
|
|
__index = function (tbl, entity)
|
|
if type(entity) == "table" and entity.valid then
|
|
local id = entity.unit_number
|
|
|
|
if id then
|
|
local tblId = rawget(tbl, "id")
|
|
if tblId then return tblId[id] end
|
|
else
|
|
local tblPos = rawget(tbl, "pos")
|
|
|
|
if tblPos then
|
|
local surface, pos = entity.surface.name, entity.position
|
|
local x, y = pos.x, pos.y
|
|
local tbls = tblPos[surface]
|
|
|
|
if tbls then
|
|
local tblsx = tbls[x]
|
|
if tblsx then return tblsx[y] end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end,
|
|
|
|
__newindex = function (tbl, entity, value)
|
|
local id = entity.unit_number
|
|
local count = rawget(tbl, "count") or 0
|
|
|
|
if id then -- entities indexed by unit number
|
|
local tblId = rawget(tbl, "id")
|
|
|
|
if tblId then
|
|
local oldvalue = tblId[id]
|
|
if value ~= oldvalue then
|
|
if value == nil then
|
|
rawset(tbl, "count", count - 1)
|
|
else
|
|
rawset(tbl, "count", count + 1)
|
|
end
|
|
|
|
tblId[id] = value
|
|
end
|
|
elseif value ~= nil then
|
|
rawset(tbl, "id", { [entity.unit_number] = value })
|
|
rawset(tbl, "count", count + 1)
|
|
end
|
|
else -- other entities that don't support unit number indexed by their surface and position
|
|
local surface, pos = entity.surface.name, entity.position
|
|
local x, y = pos.x, pos.y
|
|
local tblPos = rawget(tbl, "pos")
|
|
|
|
if tblPos then
|
|
local tbls = tblPos[surface]
|
|
|
|
if tbls then
|
|
local tblsx = tbls[x]
|
|
|
|
if tblsx then
|
|
local oldvalue = tblsx[y]
|
|
if value ~= oldvalue then
|
|
if value == nil then
|
|
rawset(tbl, "count", count - 1)
|
|
else
|
|
rawset(tbl, "count", count + 1)
|
|
end
|
|
|
|
tblsx[y] = value
|
|
end
|
|
elseif value ~= nil then
|
|
tbls[x] = { [y] = value }
|
|
rawset(tbl, "count", count + 1)
|
|
end
|
|
elseif value ~= nil then
|
|
tblPos[surface] = { [x] = { [y] = value } }
|
|
rawset(tbl, "count", count + 1)
|
|
end
|
|
elseif value ~= nil then
|
|
rawset(tbl, "pos", { [surface] = { [x] = { [y] = value } } })
|
|
rawset(tbl, "count", count + 1)
|
|
end
|
|
end
|
|
end,
|
|
|
|
__len = function (tbl)
|
|
return rawget(tbl, "count") or 0
|
|
end,
|
|
}
|
|
|
|
return this |