There are a couple issues I'm seeing. First of all, it's not a good idea to replace the metatable of a frame unless you absolutely need to. Also, you're creating an extra frame that you're not using for any specific purpose that needs a frame. Taking these issues in hand and some further optimizations, here is the code that I'd propose.
Lua Code:
-- Settings
local MaxDisplay=5;
local UpdateSpeed=1;
-- Init table
local AddonData={};
for i=1,GetNumAddOns() do
AddonData[i]={ID=i,Name=GetAddOnInfo(i),Value=0};
end
-- Format time func
local function AddCPULine(tooltip,name,secs)
if secs > 3600 then
tooltip:AddDoubleLine(name,format('%.2f h',secs/3600),1,1,1,1,0.2,0.2);
elseif secs > 60 then
tooltip:AddDoubleLine(name,format('%.2f m',secs/60),1,1,1,1,1,0.2);
elseif secs >= 1 then
tooltip:AddDoubleLine(name,format('%.1f s',secs),1,1,1,0.2,1,0.2);
elseif secs > 0 then
tooltip:AddDoubleLine(name,format('%.1f ms',secs*1000),1,1,1,0.2,1,0.2);
end
end
-- Format memory func
local function AddMemoryLine(tooltip,name, size)
if size>1000 then
tooltip:AddDoubleLine(name,format('%.2f mb',size/1000),1,1,1,1,1,0.2);
elseif size>0 then
tooltip:AddDoubleLine(name,format('%.2f kb',size),1,1,1,0.2,1,0.2);
end
end
-- GameTooltip calls this OnUpdate if it exists
local LastUpdate=0;
function MiniMapTrackingButton:UpdateTooltip()
-- FPS and latency
local down,up,latency=GetNetStats();
local fps=format('FPS: %.1f',GetFramerate());
local net=format('Ping: %d ms',latency);
GameTooltip:SetOwner(self,"ANCHOR_BOTTOMLEFT",0,self:GetHeight());
GameTooltip:ClearLines();
GameTooltip:AddDoubleLine(fps,net,1,1,1,1,1,1);
GameTooltip:AddLine("--------------------------------------------------");
-- Update throttle
local now=GetTime();
if now-LastUpdate>UpdateSpeed then
local watchingCPU=(GetCVar("scriptProfile")=="1" and not IsModifierKeyDown());
-- Request game client to update internal cache
if watchingCPU then
UpdateAddOnCPUUsage();
else
UpdateAddOnMemoryUsage();
end
-- Update data
local total=0;
for i,j in ipairs(AddonData) do
local val=(watchingCPU and GetAddOnCPUUsage(j.ID)/1000 or GetAddOnMemoryUsage(j.ID));
j.Value=val;
total=total+val;
end
-- Sort data
for i=1,#AddonData-1 do
local max,id=0;
for j=i+1,#AddonData do
local val=AddonData[j].Value;
if val>max then max,id=val,j; end
end
if AddonData[i].Value<max then
AddonData[i],AddonData[id]=AddonData[id],AddonData[i];
end
end
if watchingCPU then
GameTooltip:AddLine("Addon CPU Usage");
GameTooltip:AddLine("--------------------------------------------------");
for i,j in ipairs(AddonData) do
if i>MaxDisplay then break; end
AddCPULine(GameTooltip,j.Name,j.Value);
end
GameTooltip:AddLine("--------------------------------------------------");
AddCPULine(GameTooltip,"Total",total);
else
GameTooltip:AddLine("Addon Memory Usage");
GameTooltip:AddLine("--------------------------------------------------");
for i,j in ipairs(AddonData) do
if i>MaxDisplay then break; end
AddMemoryLine(GameTooltip,j.Name,j.Value);
end
GameTooltip:AddLine("--------------------------------------------------");
AddMemoryLine(GameTooltip,"Total",total);
end
end
GameTooltip:Show()
end
MiniMapTrackingButton:SetScript("OnEnter",function(self)
GameTooltip:SetOwner(self,"ANCHOR_BOTTOMLEFT",0,self:GetHeight());
self:UpdateTooltip();
end);
MiniMapTrackingButton:SetScript("OnLeave",function() GameTooltip:Hide(); end);