You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

314 lines
9.9 KiB

--lua function
local unpack, select, type, tostring, print, tonumber, pairs, error, tinsert, tremove
= unpack, select, type, tostring, print, tonumber, pairs, error, table.insert, table.remove
--WoW API
local LoadAddOn, UnitAffectingCombat
= LoadAddOn, UnitAffectingCombat
local BestInSlot, L, AceGUI = unpack(select(2, ...))
local MAXHISTORY = 250
local MAXTOOLTIPARRAY = 5
local BestInSlotConsole = {}
local history = {}
local window
local cleanupTimer
local DevTools_Dump
DevTools_Dump = function(value)
if not _G.DevTools_Dump then
LoadAddOn("Blizzard_DebugTools")
end
DevTools_Dump = _G.DevTools_Dump
DevTools_Dump(value)
end
--- Used to print BestInslot info
--@param #multiple str Something to be printed, if it's a string, nil, or a number, it will simply print out it's value. Otherwise it will call Blizzard's DevTools_Dump to dump the value
--@param #boolean overrideDebug Override the debug setting, if not set, it'll hide this message if the debug setting is disabled
--@param #boolean second Defines wether this message was part of a previous message.
function BestInSlot.Print(module, str, overrideDebug, second)
if BestInSlot.options.DEBUG or overrideDebug then
local normalColor = module.colorNormal
local colorHighlight = module.colorHighlight
local textFormatSize = 40
local maxSize = 255
local name = module.Description and "BestInSlotRedux "..module.Description or module.name or "BestInSlotRedux"
if type(str) == "string" or type(str) == "number" or type(str) == "nil" then
str = tostring(str)
if (#str + textFormatSize) > maxSize then
local printString
if not second then
printString = ("%s%s: %s%s..|r"):format(colorHighlight, name, normalColor, (str):sub(1,maxSize-textFormatSize))
else
printString = ("%s%s: %s..%s..|r"):format(colorHighlight, name, normalColor, (str):sub(1,maxSize-textFormatSize))
end
DEFAULT_CHAT_FRAME:AddMessage(printString)
module:Print((str):sub(maxSize - textFormatSize), overrideDebug, true)
else
if second then
DEFAULT_CHAT_FRAME:AddMessage(("%s%s: %s..%s|r"):format(colorHighlight, name, normalColor, str))
else
DEFAULT_CHAT_FRAME:AddMessage(("%s%s: %s%s|r"):format(colorHighlight, name, normalColor, str))
end
end
else
DEFAULT_CHAT_FRAME:AddMessage(("%s%s: %sDump of %s:|r"):format(BestInSlot.colorHighlight, name, BestInSlot.colorNormal, type(str)))
DevTools_Dump(str)
end
end
end
local function addNewItem(data)
data.hour = tonumber(date("%H"))
data.minute = tonumber(date("%M"))
data.second = tonumber(date("%S"))
tinsert(history, data)
while #history > MAXHISTORY do
tremove(history, 1) -- remove oldes
end
if window then
local scroll = window:GetUserData("scroll")
local scrollDown = scroll.scrollbar:GetValue() >= 1000 or not scroll.scrollbar:IsVisible()
local label = BestInSlotConsole:GetLabel(data)
scroll:AddChild(label)
if scrollDown then
scroll:SetScroll(1000)
end
end
if not cleanupTimer then
cleanupTimer = BestInSlot:ScheduleRepeatingTimer(BestInSlotConsole.Cleanup, 150)
end
end
--- Adds item to the BestInSlot console. This function will only work when DEBUG is enabled in the options
-- @param #string descr Any description which will be shown in the main window of the console
-- @param #any ... Any other parameters will be dumped in the OnHover tooltip
function BestInSlotConsole:Add(descr, ...)
if not BestInSlot.options.DEBUG then return end
local data = {
descr = descr,
param = {...},
}
addNewItem(data)
end
--- Adds item to the BestInSlot console as an error. Erros won't be cleaned up and are shown in red
-- @param #string descr Any description which will be shown in the main window of the console
-- @param #any ... Any other parameters will be dumped in the OnHover tooltip
function BestInSlotConsole:AddError(descr, ...)
local data = {
descr = descr,
param = {...},
error = true,
}
addNewItem(data)
end
--- Will get called by a timer to cleanup history data to free up memory.
function BestInSlotConsole:Cleanup()
if UnitAffectingCombat("player") then
BestInSlot:ScheduleTimer(BestInSlotConsole.Cleanup, 60) --delay the cleanup when in combat
return
end
local currentTime = tonumber(date("%H")) * 60 + tonumber(date("%M")) --currentTime in amount of minutes from 00:00
for i=#history, 1, -1 do
if not history[i].error then --Don't clean up errors
local time = history[i].hour * 60 + history[i].minute
local timeSince = ((currentTime - time + 1440) % 1440)
if timeSince >= 15 then
tremove(history, i)
end
end
end
if #history == 0 or BestInSlotConsole:HasOnlyErrors() then
BestInSlot:CancelTimer(cleanupTimer)
cleanupTimer = nil
end
end
--- Checks if the console contains only errors
-- @return #boolean True if it only contains errors, otherwise false
function BestInSlotConsole:HasOnlyErrors()
for i=1,#history do
if not history[i].error then
return false
end
end
return true
end
local function OnEvent(event, ...)
BestInSlotConsole:Add(event, ...)
end
function BestInSlotConsole:EnableConsole()
BestInSlot:RegisterEvent("*", OnEvent)
self:Add("Enabled console")
end
function BestInSlotConsole:DisableConsole()
BestInSlot:UnregisterEvent("*", OnEvent)
self:Add("Disabled console")
end
function BestInSlotConsole:GetErrors()
local errors = {}
for i=1,#history do
if history[i].error then
tinsert(errors, history[i])
end
end
return errors
end
local function windowOnClose()
window:Release()
window = nil
end
local function getLastIndex(table)
local last = 0
for i,v in pairs(table) do
if type(i) == "string" then error("Can only use this function with number indexes!") end
if i > last then
last = i
end
end
return last
end
local function tableSize(table)
local size = 0
for _ in pairs(table) do
size = size + 1
end
return size
end
local function helperDumpTable(table, GameTooltip, indent)
indent = indent or 2
if indent > 6 then return end
local size = tableSize(table)
local counter = 0
local indentString = (" "):rep(indent)
if indent == 2 then
GameTooltip:AddLine("{")
end
for k,v in pairs(table) do
counter = counter + 1
if type(v) == "table" then
GameTooltip:AddLine(indentString.."["..tostring(k).."] = {")
helperDumpTable(v, GameTooltip, indent + 2)
GameTooltip:AddLine(indentString.."},")
else
GameTooltip:AddLine(indentString.."["..tostring(k).."] = "..tostring(v)..",")
end
end
if indent == 2 then
GameTooltip:AddLine("}")
end
end
local function Label_OnEnter(label)
local data = label:GetUserData("param")
GameTooltip:SetOwner(window.frame)
GameTooltip:SetAnchorType("ANCHOR_NONE")
GameTooltip:SetPoint("TOPLEFT", window.frame, "TOPRIGHT")
GameTooltip:AddLine(("%s (%s):"):format(data.descr, BestInSlotConsole:GetTimeString(data)))
if getLastIndex(data.param) == 0 then
GameTooltip:AddLine("No extra parameters given")
else
local first = true
for i=1, getLastIndex(data.param) do
local param = data.param[i]
if not first then
GameTooltip:AddLine(" ")
end
local paramType
if type(param) == "table" then
paramType = tostring(param)
else
paramType = type(param)
end
GameTooltip:AddLine(("%sParameter %d (%s):|r"):format(BestInSlot.colorHighlight, i, paramType))
if type(param) == "table" then
helperDumpTable(param, GameTooltip)
else
GameTooltip:AddLine(tostring(param))
end
first = false
end
end
GameTooltip:Show()
end
local function Label_OnLeave(Label)
if GameTooltip:IsShown() then
GameTooltip:Hide()
end
end
function BestInSlotConsole:GetTimeString(data)
return ("%02d:%02d:%02d"):format(data.hour, data.minute, data.second)
end
function BestInSlotConsole:GetLabel(data)
local label = AceGUI:Create("InteractiveLabel")
local text = ("%s - %s"):format(self:GetTimeString(data), data.descr)
if data.error then
text = BestInSlot.colorHighlight..text.."|r"
end
label:SetText(text)
label:SetFullWidth(true)
label:SetUserData("param", data)
label:SetCallback("OnEnter", Label_OnEnter)
label:SetCallback("OnLeave", Label_OnLeave)
label:SetHighlight("Interface\\QuestFrame\\UI-QuestLogTitleHighlight")
return label
end
function BestInSlotConsole:ShowWindow()
if window then return end
window = AceGUI:Create("Window")
window:SetLayout("Fill")
window:SetWidth(400)
window:SetPoint("TOPRIGHT", -300, -200)
window:EnableResize(nil)
window:SetTitle("Best In Slot Console")
window:SetCallback("OnClose", windowOnClose)
local scroll = AceGUI:Create("ScrollFrame")
scroll:SetFullWidth(true)
scroll:SetFullHeight(true)
scroll:SetLayout("List")
window:AddChild(scroll)
window:SetUserData("scroll", scroll)
for i=1,#history do
local widget = self:GetLabel(history[i])
scroll:AddChild(widget)
scroll:DoLayout()
end
BestInSlot:ScheduleTimer(function()
if scroll.scrollbar:IsVisible() then
scroll:SetScroll(1000)
end
end, 0.1)
end
local function onSlashCommand()
BestInSlotConsole:ShowWindow()
end
if BestInSlot.options.DEBUG then
BestInSlotConsole:EnableConsole()
end
BestInSlot:RegisterEvent("DebugOptionsChanged", function(event, debug)
if debug then
BestInSlotConsole:EnableConsole()
else
BestInSlotConsole:DisableConsole()
end
end)
BestInSlot:RegisterSlashCmd("console", (L["%s - Shows a debugging console"]):format("/bis console"), onSlashCommand)
BestInSlot.console = BestInSlotConsole