mirror of
				https://github.com/OpenMW/openmw.git
				synced 2025-10-27 03:26:38 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			140 lines
		
	
	
	
		
			3.5 KiB
		
	
	
	
		
			Lua
		
	
	
	
	
	
			
		
		
	
	
			140 lines
		
	
	
	
		
			3.5 KiB
		
	
	
	
		
			Lua
		
	
	
	
	
	
| local M = {}
 | |
| M.__Content = true
 | |
| M.new = function(source)
 | |
|     local result = {}
 | |
|     result.__nameIndex = {}
 | |
|     for i, v in ipairs(source) do
 | |
|         if type(v) ~= 'table' then
 | |
|             error('Content can only contain tables')
 | |
|         end
 | |
|         result[i] = v
 | |
|         if type(v.name) == 'string' then
 | |
|             result.__nameIndex[v.name] = i
 | |
|         end
 | |
|     end
 | |
|     return setmetatable(result, M)
 | |
| end
 | |
| local 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))
 | |
|     end
 | |
| end
 | |
| 
 | |
| local function getIndexFromKey(self, key)
 | |
|     local index = key
 | |
|     if type(key) == 'string' then
 | |
|         index = self.__nameIndex[key]
 | |
|         if not index then
 | |
|             error('Unexpected content key:' .. key)
 | |
|         end
 | |
|     end
 | |
|     validateIndex(self, index)
 | |
|     return index
 | |
| end
 | |
| 
 | |
| local methods = {
 | |
|     insert = function(self, index, value)
 | |
|         validateIndex(self, index)
 | |
|         if type(value) ~= 'table' then
 | |
|             error('Content can only contain tables')
 | |
|         end
 | |
|         for i = #self, index, -1 do
 | |
|             rawset(self, i + 1, rawget(self, i))
 | |
|             local name = rawget(self, i + 1)
 | |
|             if name then
 | |
|                 self.__nameIndex[name] = i + 1
 | |
|             end
 | |
|         end
 | |
|         rawset(self, index, value)
 | |
|         if value.name then
 | |
|             self.__nameIndex[value.name] = index
 | |
|         end
 | |
|     end,
 | |
|     indexOf = function(self, value)
 | |
|         if type(value) == 'string' then
 | |
|             return self.__nameIndex[value]
 | |
|         elseif type(value) == 'table' then
 | |
|             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)
 | |
| end
 | |
| local function nameAt(self, index)
 | |
|     local v = rawget(self, index)
 | |
|     return v and type(v.name) == 'string' and v.name
 | |
| end
 | |
| 
 | |
| 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 value.name then
 | |
|         self.__nameIndex[value.name] = index
 | |
|     end
 | |
| end
 | |
| 
 | |
| M.__newindex = function(self, key, value)
 | |
|     local index = getIndexFromKey(self, key)
 | |
|     if value == nil then
 | |
|         remove(self, index)
 | |
|     elseif type(value) == 'table' then
 | |
|         assign(self, index, value)
 | |
|     else
 | |
|         error('Content can only contain tables')
 | |
|     end
 | |
| end
 | |
| M.__tostring = function(self)
 | |
|     return ('UiContent{%d layouts}'):format(#self)
 | |
| end
 | |
| local function next(self, index)
 | |
|     local v = rawget(self, index)
 | |
|     if v then
 | |
|         return index + 1, v
 | |
|     else
 | |
|         return nil, nil
 | |
|     end
 | |
| end
 | |
| 
 | |
| M.__pairs = function(self)
 | |
|     return next, self, 1
 | |
| end
 | |
| M.__ipairs = M.__pairs
 | |
| M.__metatable = false
 | |
| 
 | |
| return M
 |