vanilla-wow-addons – Rev 1
?pathlinks?
local L = AceLibrary("AceLocale-2.0"):new("FuBar_PerformanceFu")
local Tablet = AceLibrary("Tablet-2.0")
local Abacus = AceLibrary("Abacus-2.0")
local Crayon = AceLibrary("Crayon-2.0")
PerformanceFu = AceLibrary("AceAddon-2.0"):new("FuBarPlugin-2.0", "AceConsole-2.0", "AceEvent-2.0", "AceDB-2.0")
PerformanceFu.version = "2.0" .. string.sub("$Revision: 7559 $", 12, -3)
PerformanceFu.date = string.sub("$Date: 2006-08-09 22:43:29 -1000 (Wed, 09 Aug 2006) $", 8, 17)
PerformanceFu.hasIcon = true
local string_format = string.format
local table_concat = table.concat
local table_insert = table.insert
local table_setn = table.setn
PerformanceFu:RegisterDB("PerformanceFuDB")
PerformanceFu:RegisterDefaults("profile", {
showFramerate = true,
showLatency = true,
showMemory = true,
showRate = true,
warnGC = false,
})
function PerformanceFu:IsShowingFramerate()
return self.db.profile.showFramerate
end
function PerformanceFu:ToggleShowingFramerate()
self.db.profile.showFramerate = not self.db.profile.showFramerate
self:Update()
end
function PerformanceFu:IsShowingLatency()
return self.db.profile.showLatency
end
function PerformanceFu:ToggleShowingLatency()
self.db.profile.showLatency = not self.db.profile.showLatency
self:Update()
end
function PerformanceFu:IsShowingRate()
return self.db.profile.showRate
end
function PerformanceFu:ToggleShowingRate()
self.db.profile.showRate = not self.db.profile.showRate
self:Update()
end
function PerformanceFu:IsShowingMemory()
return self.db.profile.showMemory
end
function PerformanceFu:ToggleShowingMemory()
self.db.profile.showMemory = not self.db.profile.showMemory
self:Update()
end
function PerformanceFu:IsWarningOnGC()
return self.db.profile.warnGC
end
function PerformanceFu:ToggleWarningOnGC()
self.db.profile.warnGC = not self.db.profile.warnGC
end
local beeps5 = 0
local beeps15 = 0
local beeps30 = 0
local beeps60 = 0
local beeps180 = 0
local beeps600 = 0
local initialMemory, gcThreshold, currentMemory
local mem1, mem2, mem3, mem4, mem5, mem6, mem7, mem8, mem9, mem10
local timeSinceLastUpdate
local justEntered
local gcTime
function PerformanceFu:OnEnable()
initialMemory, gcThreshold = gcinfo()
currentMemory = initialMemory
mem1 = currentMemory
mem2 = currentMemory
mem3 = currentMemory
mem4 = currentMemory
mem5 = currentMemory
mem6 = currentMemory
mem7 = currentMemory
mem8 = currentMemory
mem9 = currentMemory
mem10 = currentMemory
timeSinceLastUpdate = 0
gcTime = time()
justEntered = true
self:ScheduleRepeatingEvent(self.OnUpdate, 1, self)
end
local options = {
type = 'group',
args = {
framerate = {
type = 'toggle',
name = L"Show framerate",
desc = L"Toggle whether to framerate",
get = "IsShowingFramerate",
set = "ToggleShowingFramerate",
},
latency = {
type = 'toggle',
name = L"Show latency",
desc = L"Toggle whether to latency (lag)",
get = "IsShowingLatency",
set = "ToggleShowingLatency",
},
memory = {
type = 'toggle',
name = L"Show memory usage",
desc = L"Toggle whether to show current memory usage",
get = "IsShowingMemory",
set = "ToggleShowingMemory",
},
rate = {
type = 'toggle',
name = L"Show rate of increasing memory usage",
desc = L"Toggle whether to show increasing rate of memory",
get = "IsShowingRate",
set = "ToggleShowingRate",
},
warn = {
type = 'toggle',
name = L"Warn on garbage collection",
desc = L"Toggle whether to warn on an upcoming garbage collection",
get = "IsWarningOnGC",
set = "ToggleWarningOnGC",
},
forcegc = {
type = 'execute',
name = L"Force garbage collection",
desc = L"Force a garbage collection to happen",
order = 101,
func = collectgarbage
}
}
}
PerformanceFu:RegisterChatCommand(L:GetTable("AceConsole-options"), options)
PerformanceFu.OnMenuRequest = options
local gccheck = setmetatable({[{}]=true}, {__mode = "k"})
function PerformanceFu:OnUpdate()
if justEntered then
if not timeSinceLastUpdate then
timeSinceLastUpdate = 0
end
timeSinceLastUpdate = timeSinceLastUpdate + 1
if timeSinceLastUpdate >= 10 then
initialMemory, gcThreshold = gcinfo()
currentMemory = initialMemory
mem1 = currentMemory
mem2 = currentMemory
mem3 = currentMemory
mem4 = currentMemory
mem5 = currentMemory
mem6 = currentMemory
mem7 = currentMemory
mem8 = currentMemory
mem9 = currentMemory
mem10 = currentMemory
timeSinceLastUpdate = nil
gcTime = time()
justEntered = false
end
else
local t = time()
timeSinceLastUpdate = 0
mem1, mem2, mem3, mem4, mem5, mem6, mem7, mem8, mem9, mem10 =
currentMemory, mem1, mem2, mem3, mem4, mem5, mem6, mem7, mem8, mem9
currentMemory, gcThreshold = gcinfo()
if not next(gccheck) then
gccheck[{}] = true
initialMemory = currentMemory
gcTime = t
mem10, mem9, mem9, mem8, mem7, mem6, mem5, mem4, mem3, mem2, mem1 =
currentMemory, currentMemory, currentMemory, currentMemory, currentMemory, currentMemory, currentMemory, currentMemory, currentMemory, currentMemory
beeps5 = 0
beeps5 = 0
beeps15 = 0
beeps30 = 0
beeps60 = 0
beeps180 = 0
beeps600 = 0
if self:IsWarningOnGC() then
self:Print(L"Garbage collection occurred")
end
end
local averageRate = (currentMemory - initialMemory) / (t - gcTime)
local totalSecs = (gcThreshold - currentMemory) / averageRate
if self:IsWarningOnGC() then
if totalSecs <= 5 and beeps5 < t - 15 then
self:Print(L"Garbage collection in %s", Abacus:FormatDurationShort(totalSecs, false, true))
beeps600 = t
beeps180 = t
beeps60 = t
beeps30 = t
beeps15 = t
beeps5 = t
elseif totalSecs <= 15 and beeps15 < t - 30 then
self:Print(L"Garbage collection in %s", Abacus:FormatDurationShort(totalSecs, false, true))
beeps600 = t
beeps180 = t
beeps60 = t
beeps30 = t
beeps15 = t
elseif totalSecs <= 30 and beeps30 < t - 45 then
self:Print(L"Garbage collection in %s", Abacus:FormatDurationShort(totalSecs, false, true))
beeps600 = t
beeps180 = t
beeps60 = t
beeps30 = t
elseif totalSecs <= 60 and beeps60 < t - 90 then
self:Print(L"Garbage collection in %s", Abacus:FormatDurationShort(totalSecs, false, true))
beeps600 = t
beeps180 = t
beeps60 = t
elseif totalSecs <= 180 and beeps180 < t - 270 then
self:Print(L"Garbage collection in %s", Abacus:FormatDurationShort(totalSecs, false, true))
beeps600 = t
beeps180 = t
elseif totalSecs <= 600 and beeps600 < t - 900 then
self:Print(L"Garbage collection in %s", Abacus:FormatDurationShort(totalSecs, false, true))
beeps600 = t
end
end
self:Update()
end
end
local t = {}
function PerformanceFu:OnTextUpdate()
if not mem10 then
mem10 = currentMemory
end
local currentRate = (currentMemory - mem10) / 10
if self:IsShowingFramerate() then
local framerate = floor(GetFramerate() + 0.5)
table_insert(t, format("|cff%s%d|r fps", Crayon:GetThresholdHexColor(framerate / 60), framerate))
end
if self:IsShowingLatency() then
local _,_,latency = GetNetStats()
table_insert(t, format("|cff%s%d|r ms", Crayon:GetThresholdHexColor(latency, 1000, 500, 250, 100, 0), latency))
end
if self:IsShowingMemory() then
table_insert(t, format("|cff%s%.1f|r MiB", Crayon:GetThresholdHexColor(currentMemory, 51200, 40960, 30520, 20480, 10240), currentMemory / 1024))
end
if self:IsShowingRate() then
table_insert(t, format("|cff%s%.1f|r KiB/s", Crayon:GetThresholdHexColor(currentRate, 30, 10, 3, 1, 0), currentRate))
end
self:SetText(table_concat(t, " "))
for k in pairs(t) do
t[k] = nil
k = nil
end
table_setn(t, 0)
end
function PerformanceFu:OnTooltipUpdate()
local cat = Tablet:AddCategory(
'columns', 2,
'child_textR', 1,
'child_textG', 1,
'child_textB', 0
)
local framerate = GetFramerate()
local r, g, b = Crayon:GetThresholdColor(framerate / 60)
cat:AddLine(
'text', L"Framerate:",
'text2', string_format("%.1f fps", framerate),
'text2R', r,
'text2G', g,
'text2B', b
)
cat = Tablet:AddCategory(
'text', L"Network status",
'columns', 2,
'child_textR', 1,
'child_textG', 1,
'child_textB', 0,
'child_text2R', 1,
'child_text2G', 1,
'child_text2B', 1
)
local bandwidthIn, bandwidthOut, latency = GetNetStats()
bandwidthIn, bandwidthOut = bandwidthIn * 1024, bandwidthOut * 1024
local r, g, b = Crayon:GetThresholdColor(latency, 3000, 1000, 250, 100, 0)
cat:AddLine(
'text', L"Latency:",
'text2', string_format("%d ms", latency),
'text2R', r,
'text2G', g,
'text2B', b
)
cat:AddLine(
'text', L"Bandwidth in:",
'text2', string_format("%d B/s", bandwidthIn)
)
cat:AddLine(
'text', L"Bandwidth out:",
'text2', string_format("%d B/s", bandwidthOut)
)
local averageRate = (currentMemory - initialMemory) / (time() - gcTime)
cat = Tablet:AddCategory(
'text', L"Memory usage",
'columns', 2,
'child_textR', 1,
'child_textG', 1,
'child_textB', 0,
'child_text2R', 1,
'child_text2G', 1,
'child_text2B', 1
)
local currentRate = (currentMemory - mem10) / 10
local r, g, b = Crayon:GetThresholdColor(currentMemory, 51200, 40960, 30520, 20480, 10240)
cat:AddLine(
'text', L"Current memory:",
'text2', string_format("%.1f MiB", currentMemory / 1024),
'text2R', r,
'text2G', g,
'text2B', b
)
r, g, b = Crayon:GetThresholdColor(initialMemory, 51200, 40960, 30520, 20480, 10240)
cat:AddLine(
'text', L"Initial memory:",
'text2', string_format("%.1f MiB", initialMemory / 1024),
'text2R', r,
'text2G', g,
'text2B', b
)
r, g, b = Crayon:GetThresholdColor(currentRate, 30, 10, 3, 1, 0)
cat:AddLine(
'text', L"Increasing rate:",
'text2', string_format("%.1f KiB/s", currentRate),
'text2R', r,
'text2G', g,
'text2B', b
)
r, g, b = Crayon:GetThresholdColor(averageRate, 30, 10, 3, 1, 0)
cat:AddLine(
'text', L"Average increasing rate:",
'text2', format("%.1f KiB/s", averageRate),
'text2R', r,
'text2G', g,
'text2B', b
)
cat = Tablet:AddCategory(
'text', L"Garbage collection",
'columns', 2,
'child_textR', 1,
'child_textG', 1,
'child_textB', 0,
'child_text2R', 1,
'child_text2G', 1,
'child_text2B', 1
)
local totalSecs = (gcThreshold - currentMemory) / averageRate
local timeToNext = Abacus:FormatDurationFull(totalSecs)
local r, g, b = Crayon:GetThresholdColor(gcThreshold, 51200, 40960, 30520, 20480, 10240)
cat:AddLine(
'text', L"Threshold:",
'text2', format("%.1f MiB", gcThreshold / 1024),
'text2R', r,
'text2G', g,
'text2B', b
)
local r, g, b = Crayon:GetThresholdColor(totalSecs, 0, 900, 1800, 2700, 3600)
cat:AddLine(
'text', L"Time to next:",
'text2', timeToNext,
'text2R', r,
'text2G', g,
'text2B', b
)
end