v9.7.2: Ebonhold Database integration and core logic refinements
This commit is contained in:
@@ -0,0 +1,537 @@
|
||||
local QuestieProfiler = QuestieLoader:CreateModule("Profiler")
|
||||
|
||||
--- COMPATIBILITY ---
|
||||
local C_Timer = QuestieCompat.C_Timer
|
||||
local BackdropTemplateMixin = not QuestieCompat.Is335 and BackdropTemplateMixin
|
||||
|
||||
QuestieProfiler.hooks = {}
|
||||
QuestieProfiler.alreadyHooked = {}
|
||||
QuestieProfiler.needsHook = {}
|
||||
QuestieProfiler.hookCallCount = {}
|
||||
QuestieProfiler.hookTimeCount = {}
|
||||
QuestieProfiler.lowerCaseLookup = {}
|
||||
QuestieProfiler.shortestName = {}
|
||||
QuestieProfiler.lookupToHook = {}
|
||||
QuestieProfiler.hooks = {}
|
||||
QuestieProfiler.needsHookCount = 0
|
||||
QuestieProfiler.finishedHookCount = 0
|
||||
QuestieProfiler.hookedFunctionCount = 0
|
||||
QuestieProfiler.highestMS = 0
|
||||
QuestieProfiler.highestCalls = 0
|
||||
QuestieProfiler.searchFilter = nil
|
||||
|
||||
QuestieProfiler.condensedMode = false
|
||||
|
||||
QuestieProfiler.scriptsToWatch = {
|
||||
"OnUpdate",
|
||||
"OnShow",
|
||||
"OnHide"
|
||||
}
|
||||
|
||||
function QuestieProfiler:HookFunction(key, val, table, name)
|
||||
local lookupKey = name .. "." .. tostring(key)
|
||||
QuestieProfiler.shortestName[val] = lookupKey
|
||||
QuestieProfiler.alreadyHooked[val] = true
|
||||
QuestieProfiler.lookupToHook[lookupKey] = val
|
||||
local hook = {}
|
||||
hook.original = val
|
||||
hook.originalKey = key
|
||||
hook.originalParent = table
|
||||
|
||||
QuestieProfiler.hookCallCount[lookupKey] = 0
|
||||
QuestieProfiler.hookTimeCount[lookupKey] = 0
|
||||
hook.override = function(...)
|
||||
--local _, _, name = strsplit("\\", debugstack(2))
|
||||
--print(name)
|
||||
--print("Hookboy run " .. name .. "->"..key)
|
||||
local htc = QuestieProfiler.hookCallCount[lookupKey] + 1
|
||||
QuestieProfiler.hookCallCount[lookupKey] = htc
|
||||
if htc > QuestieProfiler.highestCalls then
|
||||
QuestieProfiler.highestCalls = htc
|
||||
end
|
||||
local start = debugprofilestop()
|
||||
local ret = { hook.original(...) }
|
||||
start = debugprofilestop() - start
|
||||
htc = QuestieProfiler.hookTimeCount[lookupKey] + start
|
||||
QuestieProfiler.hookTimeCount[lookupKey] = htc
|
||||
if htc > QuestieProfiler.highestMS then
|
||||
QuestieProfiler.highestMS = htc
|
||||
end
|
||||
return unpack(ret)
|
||||
end
|
||||
QuestieProfiler.lowerCaseLookup[lookupKey] = string.lower(lookupKey)
|
||||
tinsert(QuestieProfiler.hooks, hook)
|
||||
table[key] = hook.override
|
||||
QuestieProfiler.hookedFunctionCount = QuestieProfiler.hookedFunctionCount + 1
|
||||
end
|
||||
|
||||
function QuestieProfiler:HookTable(table, name)
|
||||
QuestieProfiler.alreadyHooked[table] = true
|
||||
for key, val in pairs(table) do
|
||||
if QuestieProfiler.alreadyHooked[val] then
|
||||
if QuestieProfiler.shortestName[val] then
|
||||
local lookupKey
|
||||
if type(key) == "table" then
|
||||
lookupKey = name .. ".(key)" .. tostring(key)
|
||||
else
|
||||
lookupKey = name .. "." .. tostring(key)
|
||||
end
|
||||
if string.len(lookupKey) < string.len(QuestieProfiler.shortestName[val]) then
|
||||
QuestieProfiler.shortestName[val] = lookupKey
|
||||
QuestieProfiler.lowerCaseLookup[lookupKey] = string.lower(lookupKey)
|
||||
--print("Shorter name: " .. lookupKey)
|
||||
end
|
||||
end
|
||||
else
|
||||
--QuestieProfiler.alreadyHooked[val] = true
|
||||
local typ = type(val)
|
||||
if type(key) == "table" then
|
||||
tinsert(QuestieProfiler.needsHook, { key, name .. ".(key)" .. tostring(key) })
|
||||
QuestieProfiler.needsHookCount = QuestieProfiler.needsHookCount + 1
|
||||
end
|
||||
if typ == "function" then
|
||||
if key == "GetScript" then -- get all scripts
|
||||
for _, script in pairs(QuestieProfiler.scriptsToWatch) do
|
||||
local res, ret = pcall(val, table, script)
|
||||
if res then
|
||||
QuestieProfiler:HookScript(script, ret, table, name)
|
||||
end
|
||||
end
|
||||
end
|
||||
--print("["..QuestieProfiler.finishedHookCount.."/"..QuestieProfiler.needsHookCount.."]Hooking function " .. name .. "->" .. key)
|
||||
QuestieProfiler:HookFunction(key, val, table, name)
|
||||
elseif typ == "table" then
|
||||
--QuestieProfiler:HookTable(val, name .. "->"..key)
|
||||
|
||||
tinsert(QuestieProfiler.needsHook, { val, name .. "." .. tostring(key) })
|
||||
QuestieProfiler.needsHookCount = QuestieProfiler.needsHookCount + 1
|
||||
end
|
||||
end
|
||||
end
|
||||
QuestieProfiler.finishedHookCount = QuestieProfiler.finishedHookCount + 1
|
||||
end
|
||||
|
||||
function QuestieProfiler:HookModules()
|
||||
for moduleName, module in pairs(QuestieLoader._modules) do
|
||||
print("Hooking module " .. moduleName)
|
||||
QuestieProfiler:HookTable(module, moduleName)
|
||||
end
|
||||
end
|
||||
|
||||
function QuestieProfiler:HookFrames()
|
||||
-- bit of a hack but I want to keep questie's code 100% unaffected, this should be a stand-alone module.
|
||||
-- that also makes sure the profiler doesnt mess with the performance of the addon when its not running (which is almost always)
|
||||
--C_Timer.NewTicker(2, function()
|
||||
-- QuestieProfiler:HookTable(QuestieFramePool, "QuestieFramePool") -- update framepool functions
|
||||
--end)
|
||||
end
|
||||
|
||||
function QuestieProfiler:CreateUI()
|
||||
local base = CreateFrame("Frame", nil, UIParent, BackdropTemplateMixin and "BackdropTemplate" or nil)
|
||||
base:SetFrameStrata("TOOLTIP")
|
||||
base:SetSize(840, 580)
|
||||
base:SetPoint("Center", UIParent, 0, 50)
|
||||
|
||||
base:SetMovable(true)
|
||||
base:EnableMouse(true)
|
||||
base:RegisterForDrag("LeftButton")
|
||||
|
||||
base:SetBackdrop({
|
||||
bgFile = "Interface\\DialogFrame\\UI-DialogBox-Background-Dark",
|
||||
edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
|
||||
tile = true,
|
||||
edgeSize = 16,
|
||||
insets = { left = 4, right = 4, top = 4, bottom = 4 },
|
||||
})
|
||||
|
||||
local scrollFrameTemplete
|
||||
if Questie.IsWotlk and (not QuestieCompat.Is335) then
|
||||
scrollFrameTemplete = "ScrollFrameTemplate"
|
||||
else
|
||||
scrollFrameTemplete = "UIPanelScrollFrameTemplate"
|
||||
end
|
||||
|
||||
base.scrollFrame = CreateFrame("ScrollFrame", "QuestieProfilerScrollFrame", base, scrollFrameTemplete)
|
||||
base.scrollFrame:SetFrameStrata("TOOLTIP")
|
||||
base.scrollFrame:SetPoint("TOPLEFT", base, 0, -40)
|
||||
base.scrollFrame:SetPoint("BOTTOMRIGHT", base, 0, 30)
|
||||
|
||||
if QuestieCompat.Is335 then
|
||||
base.scrollFrame.ScrollBar = _G[base.scrollFrame:GetName() .. "ScrollBar"]
|
||||
base.scrollFrame.ScrollBar:ClearAllPoints()
|
||||
base.scrollFrame.ScrollBar:SetPoint("TOPRIGHT", -6, -16)
|
||||
base.scrollFrame.ScrollBar:SetPoint("BOTTOMRIGHT", -6, 16)
|
||||
base.scrollFrame.ScrollBar.Show = function() end
|
||||
end
|
||||
base.scrollFrame.ScrollBar:Hide()
|
||||
|
||||
base.scrollContainer = CreateFrame("Frame")
|
||||
base.scrollContainer:SetFrameStrata("TOOLTIP")
|
||||
|
||||
local lineCounter = 0
|
||||
base.scrollContainer.ResetLines = function()
|
||||
lineCounter = 0
|
||||
end
|
||||
|
||||
local lines = {}
|
||||
base.scrollContainer.CreateLineFrame = function()
|
||||
local label = base.scrollContainer:CreateFontString(nil, "ARTWORK", "GameFontNormal")
|
||||
label:SetText("")
|
||||
label:SetPoint("TOPLEFT", base.scrollContainer, 0, -lineCounter * 10)
|
||||
|
||||
label:SetWidth(base.scrollFrame:GetWidth() - 270)
|
||||
label:SetJustifyH("RIGHT")
|
||||
|
||||
local label2 = base.scrollContainer:CreateFontString(nil, "ARTWORK", "GameFontNormal")
|
||||
label2:SetText("")
|
||||
label2:SetPoint("TOPLEFT", base.scrollContainer, base.scrollFrame:GetWidth() - 260, -lineCounter * 10)
|
||||
|
||||
local label3 = base.scrollContainer:CreateFontString(nil, "ARTWORK", "GameFontNormal")
|
||||
label3:SetText("")
|
||||
label3:SetPoint("TOPLEFT", base.scrollContainer, base.scrollFrame:GetWidth() - 150, -lineCounter * 10)
|
||||
|
||||
base.scrollContainer:SetSize(base.scrollFrame:GetWidth(), lineCounter * 10)
|
||||
|
||||
return { label, label2, label3 }
|
||||
end
|
||||
|
||||
base.scrollContainer.GetNextLine = function()
|
||||
lineCounter = lineCounter + 1
|
||||
if not lines[lineCounter] then
|
||||
lines[lineCounter] = base.scrollContainer.CreateLineFrame()
|
||||
end
|
||||
return lines[lineCounter]
|
||||
end
|
||||
|
||||
base.scrollContainer:SetSize(base.scrollFrame:GetWidth(), (base.scrollFrame:GetHeight() * 2))
|
||||
|
||||
base.scrollFrame:SetScrollChild(base.scrollContainer)
|
||||
base.scrollFrame:Show()
|
||||
|
||||
QuestieProfiler.baseUI = base
|
||||
|
||||
-- should maybe be exposed in QuestieLib
|
||||
local function RGBToHex(r, g, b)
|
||||
if r > 255 then r = 255 end
|
||||
if g > 255 then g = 255 end
|
||||
if b > 255 then b = 255 end
|
||||
if r < 0 then r = 0 end
|
||||
if g < 0 then g = 0 end
|
||||
if b < 0 then b = 0 end
|
||||
return string.format("\124cFF%02x%02x%02x", r, g, b)
|
||||
end
|
||||
|
||||
local function FloatRGBToHex(r, g, b) return RGBToHex(r * 254, g * 254, b * 254) end
|
||||
|
||||
local function valToHex(float)
|
||||
if float < .49 then return FloatRGBToHex(1, 0 + float / .5, 0) end
|
||||
if float == .50 then return FloatRGBToHex(1, 1, 0) end
|
||||
if float > .50 then return FloatRGBToHex(1 - float / 2, 1, 0) end
|
||||
end
|
||||
|
||||
local statusLabel = base:CreateFontString(nil, "ARTWORK", "GameFontNormal")
|
||||
statusLabel:SetText("This is a test.")
|
||||
statusLabel:SetPoint("BOTTOMLEFT", base, 10, 10)
|
||||
statusLabel:Show()
|
||||
base.lastIndex = 0
|
||||
base.update = function()
|
||||
base.scrollContainer.ResetLines()
|
||||
local sorted = {}
|
||||
local index = 0
|
||||
local timeCount = QuestieProfiler.hookTimeCount
|
||||
local callCount = QuestieProfiler.hookCallCount
|
||||
local highestMS = QuestieProfiler.highestMS
|
||||
local highestCalls = QuestieProfiler.highestCalls
|
||||
|
||||
if QuestieProfiler.condensedMode then
|
||||
timeCount = {}
|
||||
callCount = {}
|
||||
highestMS = 0
|
||||
highestCalls = 0
|
||||
for call, _ in pairs(QuestieProfiler.hookTimeCount) do
|
||||
local callStack = {}
|
||||
index = 0
|
||||
for token in string.gmatch(call, "[^.]+") do
|
||||
--print(token)
|
||||
tinsert(callStack, token)
|
||||
index = index + 1
|
||||
end
|
||||
--local ncall = (callStack[index-2] or "?") .. "." .. (callStack[index-1] or "?") .. ":" .. callStack[index].."()"
|
||||
--local ncall = (callStack[index-1] or "?") .. ":" .. callStack[index].."()"
|
||||
local ncall = callStack[index] .. "()"
|
||||
if callStack[index - 1] and not tonumber(callStack[index - 1]) then
|
||||
ncall = callStack[index - 1] .. "." .. ncall
|
||||
end
|
||||
if callStack[index - 2] and not tonumber(callStack[index - 2]) then
|
||||
ncall = callStack[index - 2] .. "." .. ncall
|
||||
end
|
||||
|
||||
if not timeCount[ncall] then
|
||||
timeCount[ncall] = 0
|
||||
callCount[ncall] = 0
|
||||
end
|
||||
local time = timeCount[ncall] + QuestieProfiler.hookTimeCount[call]
|
||||
local calls = callCount[ncall] + QuestieProfiler.hookCallCount[call]
|
||||
timeCount[ncall] = time
|
||||
callCount[ncall] = calls
|
||||
QuestieProfiler.lowerCaseLookup[ncall] = string.lower(ncall)
|
||||
if time > highestMS then
|
||||
highestMS = time
|
||||
end
|
||||
if calls > highestCalls then
|
||||
highestCalls = calls
|
||||
end
|
||||
end
|
||||
end
|
||||
for call, count in pairs(timeCount) do
|
||||
if ((count > 0 and not QuestieProfiler.searchFilter) or (callCount[call] > 0 and QuestieProfiler.searchFilter and string.match(QuestieProfiler.lowerCaseLookup[call], QuestieProfiler.searchFilter))) then
|
||||
tinsert(sorted, { call, count })
|
||||
index = index + 1
|
||||
end
|
||||
end
|
||||
table.sort(sorted, function(a, b) return a[2] > b[2] end)
|
||||
|
||||
statusLabel:SetText(string.format("Total functions hooked: %d Highest call count: %d Highest time: %.2fms", QuestieProfiler.hookedFunctionCount, highestCalls, highestMS))
|
||||
|
||||
index = 0
|
||||
for call in pairs(sorted) do
|
||||
call = sorted[call][1]
|
||||
local count = timeCount[call]
|
||||
|
||||
local line = base.scrollContainer.GetNextLine()
|
||||
local color
|
||||
|
||||
if mod(index, 2) == 1 then
|
||||
color = "\124cFFFFFFFF"
|
||||
--color2 = "\124cFF88FFAA"
|
||||
else
|
||||
color = "\124cFFEEEEEE"
|
||||
--color2 = "\124cFF77EE99"
|
||||
end
|
||||
local color2 = valToHex(1 - (count / (highestMS / 2))) or "\124cFFFF0000"
|
||||
local color3 = valToHex(1 - (callCount[call] / (highestCalls / 2))) or "\124cFFFF0000"
|
||||
--print("Highest ms: " .. QuestieProfiler.highestMS)
|
||||
--print("Highest calls: " .. QuestieProfiler.highestCalls)
|
||||
local callstr = QuestieProfiler.shortestName[QuestieProfiler.lookupToHook[call]] or call
|
||||
|
||||
if (string.len(callstr) > 64) then
|
||||
callstr = "..." .. string.sub(callstr, string.len(callstr) - 64)
|
||||
end
|
||||
|
||||
line[1]:SetText(color .. callstr)
|
||||
line[2]:SetText(color2 .. string.format("time=%.2fms", count))
|
||||
line[3]:SetText(color3 .. "call count=" .. callCount[call])
|
||||
index = index + 1
|
||||
if index > 150 then
|
||||
break
|
||||
end
|
||||
end
|
||||
if base.lastIndex > index then
|
||||
for _ = index, base.lastIndex do
|
||||
local line = base.scrollContainer.GetNextLine()
|
||||
line[1]:SetText("")
|
||||
line[2]:SetText("")
|
||||
line[3]:SetText("")
|
||||
end
|
||||
end
|
||||
base.lastIndex = index
|
||||
end
|
||||
base.update()
|
||||
|
||||
|
||||
local button = CreateFrame("Button", nil, base)
|
||||
button:SetPoint("TOPLEFT", base, 10, -10)
|
||||
button:SetWidth(80)
|
||||
button:SetHeight(24)
|
||||
|
||||
button:SetText("Reset")
|
||||
|
||||
button:SetNormalFontObject("GameFontNormal")
|
||||
|
||||
local function buildTexture(str)
|
||||
local tex = button:CreateTexture()
|
||||
tex:SetTexture(str)
|
||||
tex:SetTexCoord(0, 0.625, 0, 0.6875)
|
||||
tex:SetAllPoints()
|
||||
return tex
|
||||
end
|
||||
|
||||
button:SetNormalTexture(buildTexture("Interface/Buttons/UI-Panel-Button-Up"))
|
||||
button:SetHighlightTexture(buildTexture("Interface/Buttons/UI-Panel-Button-Highlight"))
|
||||
button:SetPushedTexture(buildTexture("Interface/Buttons/UI-Panel-Button-Down"))
|
||||
button:SetScript("OnClick", function(self, ...)
|
||||
self:Disable()
|
||||
QuestieProfiler:Unhook()
|
||||
QuestieProfiler:DoHooks(function()
|
||||
for key in pairs(QuestieProfiler.hookCallCount) do
|
||||
QuestieProfiler.hookCallCount[key] = 0
|
||||
QuestieProfiler.hookTimeCount[key] = 0
|
||||
end
|
||||
QuestieProfiler.highestMS = 0
|
||||
QuestieProfiler.highestCalls = 0
|
||||
for _, line in pairs(lines) do
|
||||
line[1]:SetText("")
|
||||
line[2]:SetText("")
|
||||
line[3]:SetText("")
|
||||
end
|
||||
self:Enable()
|
||||
end)
|
||||
end)
|
||||
|
||||
button = CreateFrame("Button", nil, base)
|
||||
button:SetPoint("TOPLEFT", base, base:GetWidth() - 70, -10)
|
||||
button:SetWidth(60)
|
||||
button:SetHeight(24)
|
||||
|
||||
button:SetText("Close")
|
||||
|
||||
button:SetNormalFontObject("GameFontNormal")
|
||||
button:SetNormalTexture(buildTexture("Interface/Buttons/UI-Panel-Button-Up"))
|
||||
button:SetHighlightTexture(buildTexture("Interface/Buttons/UI-Panel-Button-Highlight"))
|
||||
button:SetPushedTexture(buildTexture("Interface/Buttons/UI-Panel-Button-Down"))
|
||||
button:SetScript("OnClick", function()
|
||||
QuestieProfiler:Unhook()
|
||||
base:Hide()
|
||||
end)
|
||||
|
||||
button = CreateFrame("Button", nil, base)
|
||||
button:SetPoint("TOPLEFT", base, 90, -10)
|
||||
button:SetWidth(140)
|
||||
button:SetHeight(24)
|
||||
|
||||
button:SetText("Mode: Full")
|
||||
button:SetNormalFontObject("GameFontNormal")
|
||||
button:SetNormalTexture(buildTexture("Interface/Buttons/UI-Panel-Button-Up"))
|
||||
button:SetHighlightTexture(buildTexture("Interface/Buttons/UI-Panel-Button-Highlight"))
|
||||
button:SetPushedTexture(buildTexture("Interface/Buttons/UI-Panel-Button-Down"))
|
||||
|
||||
button:SetScript("OnClick", function(...)
|
||||
QuestieProfiler.condensedMode = not QuestieProfiler.condensedMode
|
||||
if QuestieProfiler.condensedMode then
|
||||
button:SetText("Mode: Condensed")
|
||||
else
|
||||
button:SetText("Mode: Full")
|
||||
end
|
||||
for key in pairs(QuestieProfiler.hookCallCount) do
|
||||
QuestieProfiler.hookCallCount[key] = 0
|
||||
QuestieProfiler.hookTimeCount[key] = 0
|
||||
end
|
||||
QuestieProfiler.highestMS = 0
|
||||
QuestieProfiler.highestCalls = 0
|
||||
for _, line in pairs(lines) do
|
||||
line[1]:SetText("")
|
||||
line[2]:SetText("")
|
||||
line[3]:SetText("")
|
||||
end
|
||||
end)
|
||||
|
||||
local searchBox = CreateFrame("Frame", nil, base, BackdropTemplateMixin and "BackdropTemplate")
|
||||
searchBox:SetPoint("TOPLEFT", base, 260, -10)
|
||||
searchBox:SetWidth(192)
|
||||
searchBox:SetHeight(24)
|
||||
searchBox:Show()
|
||||
|
||||
searchBox:SetBackdrop({
|
||||
bgFile = "Interface\\DialogFrame\\UI-DialogBox-Background",
|
||||
edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
|
||||
tile = true,
|
||||
tileSize = 0,
|
||||
edgeSize = 16,
|
||||
insets = { left = 0, right = 0, top = 0, bottom = 0 }
|
||||
})
|
||||
|
||||
local search = CreateFrame("EditBox", nil, searchBox, BackdropTemplateMixin and "BackdropTemplate" or nil)
|
||||
search:SetMultiLine(false)
|
||||
search:SetFontObject(ChatFontNormal)
|
||||
search:SetWidth(180)
|
||||
search:SetHeight(20)
|
||||
search:SetFrameStrata("TOOLTIP")
|
||||
search:SetPoint("TOPLEFT", searchBox, 6, -1)
|
||||
search:SetText("\124cFF888888Filter...")
|
||||
|
||||
search:HookScript("OnMouseDown", function()
|
||||
if search:GetText() == "\124cFF888888Filter..." then
|
||||
search:SetText("")
|
||||
end
|
||||
end)
|
||||
local function clearFocus()
|
||||
search:ClearFocus()
|
||||
if string.len(search:GetText()) == 0 then
|
||||
search:SetText("\124cFF888888Filter...")
|
||||
end
|
||||
end
|
||||
search:SetAutoFocus(false)
|
||||
search:SetScript("OnEscapePressed", clearFocus)
|
||||
search:HookScript(QuestieCompat.Is335 and "OnTextChanged" or "OnKeyUp", function(self, userInput)
|
||||
local txt = string.lower(search:GetText())
|
||||
if string.len(txt) == 0 or userInput == false then
|
||||
txt = nil
|
||||
end
|
||||
QuestieProfiler.searchFilter = txt
|
||||
end)
|
||||
base:SetScript("OnMouseDown", clearFocus)
|
||||
base:SetScript("OnDragStart", function()
|
||||
base:StartMoving()
|
||||
clearFocus()
|
||||
end)
|
||||
base:SetScript("OnDragStop", function()
|
||||
base:StopMovingOrSizing()
|
||||
end)
|
||||
search:Show()
|
||||
|
||||
base:Show()
|
||||
C_Timer.NewTicker(0.5, base.update)
|
||||
end
|
||||
|
||||
function QuestieProfiler:DoHooks(after)
|
||||
local timer
|
||||
|
||||
-- libstub modules. TODO: check debugstack() to only include calls made by questie
|
||||
--QuestieProfiler.needsHookCount = QuestieProfiler.needsHookCount + 1
|
||||
--tinsert(QuestieProfiler.needsHook, {LibStub, "LibStub"})
|
||||
|
||||
for moduleName, module in pairs(QuestieLoader._modules) do
|
||||
if module ~= QuestieProfiler then
|
||||
QuestieProfiler.needsHookCount = QuestieProfiler.needsHookCount + 1
|
||||
tinsert(QuestieProfiler.needsHook, { module, moduleName })
|
||||
end
|
||||
end
|
||||
|
||||
timer = C_Timer.NewTicker(0.01, function()
|
||||
for _ = 0, 512 do
|
||||
local toHook = tremove(QuestieProfiler.needsHook)
|
||||
if toHook then
|
||||
QuestieProfiler:HookTable(toHook[1], toHook[2])
|
||||
else
|
||||
timer:Cancel()
|
||||
if after then after() end
|
||||
return
|
||||
end
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
function QuestieProfiler:Unhook()
|
||||
for _, hook in pairs(QuestieProfiler.hooks) do
|
||||
hook.originalParent[hook.originalKey] = hook.original
|
||||
end
|
||||
QuestieProfiler.hooks = {}
|
||||
QuestieProfiler.alreadyHooked = {}
|
||||
QuestieProfiler.needsHookCount = 0
|
||||
QuestieProfiler.finishedHookCount = 0
|
||||
QuestieProfiler.hookedFunctionCount = 0
|
||||
QuestieProfiler.highestMS = 0
|
||||
QuestieProfiler.highestCalls = 0
|
||||
end
|
||||
|
||||
function QuestieProfiler:Start() -- call ingame when developing /run QuestieLoader:ImportModule("Profiler"):Start()
|
||||
print("Starting profiler...")
|
||||
QuestieProfiler:DoHooks(function()
|
||||
QuestieProfiler:HookFrames()
|
||||
if QuestieProfiler.baseUI then
|
||||
QuestieProfiler.baseUI:Show()
|
||||
else
|
||||
QuestieProfiler:CreateUI()
|
||||
end
|
||||
end)
|
||||
end
|
||||
Reference in New Issue
Block a user