ZO_CircularBuffer = ZO_Object:Subclass() local DEFAULT_MAX_SIZE = 100 function ZO_CircularBuffer:New(maxSize) local buffer = ZO_Object.New(self) buffer.maxSize = maxSize or DEFAULT_MAX_SIZE buffer:Clear() return buffer end function ZO_CircularBuffer:Add(item) self.index = self.index + 1 local old = self.entries[self.index] self.entries[self.index] = item self.index = self.index % self.maxSize return old end function ZO_CircularBuffer:CalculateIndex(index) return (self.index - self:Size() + index - 1) % self.maxSize + 1 end function ZO_CircularBuffer:At(index) if index > 0 and index <= self:Size() then local index = self:CalculateIndex(index) return self.entries[index] end end function ZO_CircularBuffer:Clear() self.index = 0 self.entries = {} end function ZO_CircularBuffer:Size() return #self.entries end function ZO_CircularBuffer:MaxSize() return self.maxSize end function ZO_CircularBuffer:IsFull() return self.maxSize == #self.entries end function ZO_CircularBuffer:SetMaxSize(maxSize) self.maxSize = maxSize or DEFAULT_MAX_SIZE self.index = self.index % self.maxSize end function ZO_CircularBuffer:GetEnumerator() local currentIndex = 0 local size = self:Size() return function() if currentIndex < size then currentIndex = currentIndex + 1 return currentIndex, self:At(currentIndex) end end end