Code: Select all
--==List==--
local list = {}
list.__index = list
list.__len = function(self)
return self.size
end
list._init = function(self)
self.p,self.n = {},{}
self.size = 0
self.current = false
self.p[self] = self
self.n[self] = self
end
list.has = function(self,item)
if not item or item == self or not self.p[item] then return false
else return true end
end
list.insert = function(self,item)
if not item or item == self or self:has(item) then return false end
if self.size == 0 then self.current = item end
self.size = self.size + 1
local tail = self.p[self]
self.n[tail] = item
self.p[item] = tail
self.n[item] = self
self.p[self] = item
return true
end
list.remove = function(self,item)
local item = item or self.p[self]
if not self:has(item) then return false end
self.size = self.size - 1
if self.size == 0 then self.current = false end
if item == self.current then
self:goNext()
end
local p,n = self.p[item],self.n[item]
self.n[p] = n
self.p[n] = p
self.n[item] = nil
self.p[item] = nil
return item
end
list.swap = function(self,item1,item2)
if not (self:has(item1) and self:has(item2)) then return false end
local temp
temp = self.p[item1]
self.p[item1] = self.p[item2]
self.p[item2] = temp
temp = self.n[item1]
self.n[item1] = self.n[item2]
self.n[item2] = temp
return true
end
list.getNext = function(self,item)
local item = item
if not self:has(item) then return false end
item = self.n[item]
if item == self then item = self.n[item] end
return item
end
list.getPrev = function(self,item)
local item = item
if not self:has(item) then return false end
item = self.p[item]
if item == self then item = self.p[item] end
return item
end
list.getCurrent = function(self)
return self.current
end
list.setCurrent = function(self,item)
if not self:has(item) then return false end
self.current = item
return true
end
list.goNext = function(self)
if not self.current then return false end
self.current = self:getNext(self.current)
return true
end
list.goPrev = function(self)
if not self.current then return false end
self.current = self:getPrev(self.current)
return true
end
list.iter = function(self)
self.current = self.n[self]
local item
return function()
if self.size == 0 or item == self.p[self] then return end
if item == self.current then self:goNext() end
item = self.current
return item
end
end
list.loop = function(self)
local item
return function()
if self.size == 0 then return end
if item == self.current then self:goNext() end
item = self.current
return item
end
end
return setmetatable({},{
__index = list,
__call = function(self)
local t = setmetatable({},list)
list._init(t)
return t
end
})
Pros:
-Easy to see if something is in the list or not.
-Should be fast to remove.
-Can be looped indefinitely, allowing for use in game loops and/or coroutines.
Cons:
-Doens't allow false values(false, nil)
-Cannot insert the list within itself.
-Cannot have duplicate items in the list.