Add table recycling, internal functions and code for TPS calcs. TPS not displayed anywhere yet.

This commit is contained in:
Xinhuan
2008-10-13 18:33:56 +08:00
parent ed04d0a92d
commit 70336d726c
2 changed files with 138 additions and 13 deletions
+3
View File
@@ -9,6 +9,9 @@ L["Enter Test Mode"] = true
L["Exit Test Mode"] = true
L["Unlock Omen"] = true
L["Open Config"] = true
L["Name"] = true
L["Threat [%]"] = true
L["TPS"] = true
-- Warnings
L["|cffff0000Error:|r Omen cannot use shake warning if you have turned on nameplates at least once since logging in."] = true
+135 -13
View File
@@ -71,7 +71,7 @@ local defaults = {
Locked = false,
PositionW = 200,
PositionH = 82,
VGrip1 = 120,
VGrip1 = 115,
Background = {
Texture = "Blizzard Parchment",
BorderTexture = "Blizzard Dialog",
@@ -189,6 +189,48 @@ for i = 1, 40 do
end
-----------------------------------------------------------------------------
-- Table Pool for recycling tables
local tablePool = {}
setmetatable(tablePool, {__mode = "kv"}) -- Weak table
-- Get a new table
local function newTable()
local t = next(tablePool) or {}
tablePool[t] = nil
return t
end
-- Delete table and return to pool -- Recursive!! -- Use with care!!
local function delTable(t)
if type(t) == "table" then
for k, v in pairs(t) do
if type(v) == "table" then
delTable(v) -- child tables get put into the pool
end
t[k] = nil
end
t[true] = true -- resize table to 1 item
t[true] = nil
setmetatable(t, nil)
tablePool[t] = true
end
return nil -- return nil to assign input reference
end
-- Empties a table of everything -- Non-recursive
local function clearTable(t)
if type(t) == "table" then
for k, v in pairs(t) do
t[k] = nil
end
t[true] = true
t[true] = nil
setmetatable(t, nil)
end
end
-----------------------------------------------------------------------------
-- Omen initialization and frame functions
@@ -747,6 +789,16 @@ do
bar.Text2:SetHeight(db.Bar.FontSize)
bar.Text2:SetNonSpaceWrap(false)
bar.Text3 = bar:CreateFontString(nil, nil, "GameFontNormalSmall")
bar.Text3:SetPoint("RIGHT", bar, "RIGHT", -5, 1)
bar.Text3:SetJustifyH("RIGHT")
bar.Text3:SetFont(LSM:Fetch("font", db.Bar.Font), db.Bar.FontSize, db.Bar.FontOutline)
bar.Text3:SetTextColor(color.r, color.g, color.b, color.a)
bar.Text3:SetWidth(Omen.BarList:GetWidth() - db.VGrip1 - 5)
bar.Text3:SetHeight(db.Bar.FontSize)
bar.Text3:SetNonSpaceWrap(false)
bar.Text3:Hide()
bar.texture = bar:CreateTexture()
bar.texture:SetTexture(LSM:Fetch("statusbar", db.Bar.Texture))
bar.texture:SetPoint("TOPLEFT", bar, "TOPLEFT")
@@ -757,6 +809,17 @@ do
bar.animationTime = 0.25
bar.AnimateTo = AnimateTo
if barID == 0 then
bar.Text1:SetText(L["Name"])
bar.Text2:SetText(L["Threat [%]"])
bar.Text3:SetText(L["TPS"])
elseif barID == 1 then
-- Parent our TPS update frame to the first bar, so that TPS updates
-- updates happen when at least 1 bar (the first bar) is shown.
Omen.TPSUpdateFrame = CreateFrame("Frame", bar)
Omen.TPSUpdateFrame:SetScript("OnUpdate", function(self, elapsed) Omen:UpdateTPS() end)
end
return bar
end})
end
@@ -936,12 +999,14 @@ r, g, b = GetThreatStatusColor(state)
Returns the colors used in the UI to represent each major threat state.
]]
local threatTable = {} -- Format: threatTable[guid] = threatValue
local sortTable = {} -- Format: threatTable[i] = guid -- used for sorting by sortfunction()
local tankGUID -- Used to store which unit is tanking and hence has 100% threat by definition
local lastWarn = { -- Used to store information for threat warnings
local threatTable -- Format: threatTable[guid] = threatValue
local sortTable = {} -- Format: threatTable[i] = guid -- used for sorting by sortfunction()
local tankGUID -- Used to store which unit is tanking and hence has 100% threat by definition
local lastWarn = { -- Used to store information for threat warnings
threatpercent = 0,
}
local threatStore = {} -- Format: threatStore[i] = threatTable[guid] -- used for storing past threatTables
local threatStoreTime = {} -- Format: threatStoreTime[i] = GetTime()
local function sortfunction(a, b)
return threatTable[a] > threatTable[b]
@@ -964,9 +1029,7 @@ function Omen:UpdateBars()
local mobGUID, mobTargetGUID
if testMode then
for k, v in pairs(threatTable) do
threatTable[k] = nil
end
threatTable = newTable()
for i = 1, 25 do
threatTable[i] = i*5000
end
@@ -1002,10 +1065,7 @@ function Omen:UpdateBars()
guidNameLookup[mobTargetGUID] = UnitName(mobTarget)
end
-- Clear the threat table
for k, v in pairs(threatTable) do
threatTable[k] = nil
end
threatTable = newTable()
threatTable[mobGUID] = -1
tankGUID = nil
@@ -1094,6 +1154,7 @@ function Omen:UpdateBars()
else
bar.texture:SetWidth(width)
end
bar.guid = guid
bar:Show()
i = i + 1
end
@@ -1109,7 +1170,9 @@ function Omen:UpdateBars()
self.BarList:Show()
-- Threat warnings
if not testMode then
if testMode then
threatTable = delTable(threatTable)
else
local pGUID = UnitGUID("player")
local pClass = guidClassLookup[pGUID]
local myThreatPercent = threatTable[pGUID] / tankThreat * 100
@@ -1122,8 +1185,18 @@ function Omen:UpdateBars()
self:Warn(t.Sound, t.Flash, t.Shake, t.Message and L["Passed %s%% of %s's threat!"]:format(t.Threshold, guidNameLookup[tankGUID or mobTargetGUID or sortTable[1]]))
end
end
-- Remove TPS data if the last scanned mob is different
if lastWarn.mobGUID ~= mobGUID then
delTable(threatStore)
threatStore = newTable()
clearTable(threatStoreTime)
end
tinsert(threatStore, threatTable)
tinsert(threatStoreTime, GetTime())
-- Store last scanned mob GUID
lastWarn.mobGUID = mobGUID
lastWarn.threatpercent = myThreatPercent
threatTable = nil
end
end
@@ -1139,8 +1212,57 @@ function Omen:ClearAll()
self.Anchor:Hide()
end
end
-- Store last scanned mob GUID
lastWarn.mobGUID = nil
lastWarn.threatpercent = 0
-- Remove TPS data
delTable(threatStore)
threatStore = newTable()
clearTable(threatStoreTime)
threatTable = nil
end
function Omen:UpdateTPS()
-- Remove data that is too old
local startTime = GetTime() - 10
while threatStoreTime[2] and startTime > threatStoreTime[2] do
delTable(tremove(threatStore, 1))
tremove(threatStoreTime, 1)
end
-- Now check that we still have enough data
local dataSize = #threatStoreTime
if dataSize == 0 or startTime <= threatStoreTime[1] then
-- We do not have enough data, 10 seconds has not passed
for i = 1, #bars do
bars[i].Text3:SetText("??")
end
return
end
-- Check for special case with just 1 data point past 10 seconds
if dataSize == 1 then
-- Threat generated is 0
for i = 1, #bars do
bars[i].Text3:SetText("0")
end
return
end
-- We have at least 2 data points
for i = 1, #bars do
if not bars[i]:IsShown() then return end
local guid = bars[i].guid
local baseThreat = threatStore[1][guid]
local secondThreat = threatStore[2][guid]
local finalThreat = threatStore[dataSize][guid]
if baseThreat and secondThreat and finalThreat then
-- Calculate TPS
local ratio = (startTime - threatStoreTime[1]) / (threatStoreTime[2] - threatStoreTime[1])
local startThreat = (secondThreat - baseThreat) * ratio + baseThreat
bars[i].Text3:SetFormattedText("%d", (finalThreat - startThreat) / 1000)
else
-- We don't have enough data for this unit
bars[i].Text3:SetText("??")
end
end
end