Something went wrong. Try again.
OpenMW is an open implementation of the Morrowind engine
Something went wrong. Try again.
3.5 kB · 137 lines
Lua
at master
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138local M = {}M.__Content = true
function validateContentChild(v) if not (type(v) == 'table' or v.__type and v.__type.name == 'LuaUi::Element') then error('Content can only contain tables and Elements') endend
M.new = function(source) local result = {} result.__nameIndex = {} for i, v in ipairs(source) do validateContentChild(v) result[i] = v if type(v.name) == 'string' then result.__nameIndex[v.name] = i end end return setmetatable(result, M)endlocal function validateIndex(self, index) if type(index) ~= 'number' then error('Unexpected Content key: ' .. tostring(index)) end if index < 1 or (#self + 1) < index then error('Invalid Content index: ' .. tostring(index)) endend
local function getIndexFromKey(self, key) local index = key if type(key) == 'string' then index = self.__nameIndex[key] end return indexend
local methods = { insert = function(self, index, value) validateIndex(self, index) validateContentChild(value) for i = #self, index, -1 do rawset(self, i + 1, rawget(self, i)) local name = rawget(self, i + 1).name if type(name) == 'string' then self.__nameIndex[name] = i + 1 end end rawset(self, index, value) if type(value.name) == 'string' then self.__nameIndex[value.name] = index end end, indexOf = function(self, value) if type(value) == 'string' then return self.__nameIndex[value] else for i = 1, #self do if rawget(self, i) == value then return i end end end return nil end, add = function(self, value) self:insert(#self + 1, value) return #self end,}M.__index = function(self, key) if methods[key] then return methods[key] end local index = getIndexFromKey(self, key) return rawget(self, index)endlocal function nameAt(self, index) local v = rawget(self, index) return v and type(v.name) == 'string' and v.nameend
local function remove(self, index) local oldName = nameAt(self, index) if oldName then self.__nameIndex[oldName] = nil end if index > #self then error('Invalid Content index:' .. tostring(index)) end for i = index, #self - 1 do local v = rawget(self, i + 1) rawset(self, i, v) if type(v.name) == 'string' then self.__nameIndex[v.name] = i end end rawset(self, #self, nil)end
local function assign(self, index, value) local oldName = nameAt(self, index) if oldName then self.__nameIndex[oldName] = nil end rawset(self, index, value) if type(value.name) == 'string' then self.__nameIndex[value.name] = index endend
M.__newindex = function(self, key, value) local index = getIndexFromKey(self, key) if value == nil then remove(self, index) else validateContentChild(value) assign(self, index, value) endendM.__tostring = function(self) return ('UiContent{%d layouts}'):format(#self)endlocal function next(self, index) index = index + 1 local v = rawget(self, index) if v then return index, v endend
M.__pairs = function(self) return next, self, 0endM.__ipairs = M.__pairsM.__metatable = false
return M