режим предателя + UI референсы и DragonUI
This commit is contained in:
@@ -0,0 +1,571 @@
|
||||
EVENT_TRACE_EVENT_HEIGHT = 16;
|
||||
EVENT_TRACE_MAX_ENTRIES = 1000;
|
||||
|
||||
DEBUGLOCALS_LEVEL = 4;
|
||||
local _normalFontColor = { 1, .82, 0, 1 };
|
||||
|
||||
EVENT_TRACE_SYSTEM_TIMES = {};
|
||||
EVENT_TRACE_SYSTEM_TIMES["System"] = true;
|
||||
EVENT_TRACE_SYSTEM_TIMES["Elapsed"] = true;
|
||||
|
||||
EVENT_TRACE_EVENT_COLORS = {};
|
||||
EVENT_TRACE_EVENT_COLORS["System"] = _normalFontColor;
|
||||
EVENT_TRACE_EVENT_COLORS["Elapsed"] = { .6, .6, .6, 1 };
|
||||
|
||||
local _EventTraceFrame;
|
||||
|
||||
_framesSinceLast = 0;
|
||||
_timeSinceLast = 0;
|
||||
|
||||
local _timer = CreateFrame("FRAME");
|
||||
_timer:SetScript("OnUpdate", function (self, elapsed) _framesSinceLast = _framesSinceLast + 1; _timeSinceLast = _timeSinceLast + elapsed; end);
|
||||
|
||||
function EventTraceFrame_OnLoad (self)
|
||||
self.buttons = {};
|
||||
self.events = {};
|
||||
self.times = {};
|
||||
self.rawtimes = {};
|
||||
self.args = { {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {} };
|
||||
self.ignoredEvents = {};
|
||||
self.lastIndex = 0;
|
||||
self.visibleButtons = 0;
|
||||
_EventTraceFrame = self;
|
||||
self:SetScript("OnSizeChanged", EventTraceFrame_OnSizeChanged);
|
||||
EventTraceFrame_OnSizeChanged(self, self:GetWidth(), self:GetHeight());
|
||||
self:EnableMouse(true);
|
||||
self:EnableMouseWheel(true);
|
||||
self:SetScript("OnMouseWheel", EventTraceFrame_OnMouseWheel);
|
||||
end
|
||||
|
||||
local _workTable = {};
|
||||
function EventTraceFrame_OnEvent (self, event, ...)
|
||||
if ( not self.ignoredEvents[event] ) then
|
||||
if ( not self.ignoreElapsed and _framesSinceLast ~= 0 ) then
|
||||
self.ignoreElapsed = true;
|
||||
EventTraceFrame_OnEvent(self, "On Update");
|
||||
self.ignoreElapsed = nil;
|
||||
end
|
||||
|
||||
local nextIndex = self.lastIndex + 1;
|
||||
if ( nextIndex > EVENT_TRACE_MAX_ENTRIES ) then
|
||||
local staleIndex = nextIndex - EVENT_TRACE_MAX_ENTRIES;
|
||||
self.events[staleIndex] = nil;
|
||||
self.times[staleIndex] = nil;
|
||||
self.rawtimes[staleIndex] = nil;
|
||||
for k, v in next, self.args do
|
||||
self.args[k][staleIndex] = nil;
|
||||
end
|
||||
end
|
||||
|
||||
if ( string.match(event, "Begin Capture") or string.match(event, "End Capture") ) then
|
||||
self.times[nextIndex] = "System";
|
||||
if ( self.eventsToCapture ) then
|
||||
self.events[nextIndex] = string.format("%s (%s events)", event, tostring(self.eventsToCapture));
|
||||
else
|
||||
self.events[nextIndex] = event;
|
||||
end
|
||||
elseif ( event == "On Update" ) then
|
||||
self.times[nextIndex] = "Elapsed";
|
||||
self.events[nextIndex] = string.format(string.format("%.3f sec", _timeSinceLast) .. " - %d frame(s)", _framesSinceLast);
|
||||
_timeSinceLast = 0;
|
||||
_framesSinceLast = 0;
|
||||
else
|
||||
self.events[nextIndex] = event;
|
||||
local seconds = GetTime();
|
||||
local minutes = math.floor(math.floor(seconds) / 60);
|
||||
local hours = math.floor(minutes / 60);
|
||||
seconds = seconds - 60 * minutes;
|
||||
minutes = minutes - 60 * hours;
|
||||
hours = hours % 1000;
|
||||
self.times[nextIndex] = string.format("%.2d:%.2d:%06.3f", hours, minutes, seconds);
|
||||
|
||||
local numArgs = select("#", ...);
|
||||
for i=1, numArgs do
|
||||
if ( not self.args[i] ) then
|
||||
self.args[i] = {};
|
||||
end
|
||||
self.args[i][nextIndex] = select(i, ...);
|
||||
end
|
||||
|
||||
if ( self.eventsToCapture ) then
|
||||
self.eventsToCapture = self.eventsToCapture - 1;
|
||||
end
|
||||
end
|
||||
|
||||
self.rawtimes[nextIndex] = GetTime();
|
||||
self.lastIndex = nextIndex;
|
||||
EventTraceFrame_Update ();
|
||||
if ( self.eventsToCapture and self.eventsToCapture <= 0 ) then
|
||||
self.eventsToCapture = nil;
|
||||
EventTraceFrame_StopEventCapture();
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function EventTraceFrame_OnUpdate (self, elapsed)
|
||||
EventTraceFrame_Update();
|
||||
end
|
||||
|
||||
function EventTraceFrame_OnSizeChanged (self, width, height)
|
||||
local numButtonsToDisplay = math.floor((height - 36)/EVENT_TRACE_EVENT_HEIGHT);
|
||||
local numButtonsCreated = #self.buttons;
|
||||
|
||||
if ( numButtonsCreated < numButtonsToDisplay ) then
|
||||
for i = numButtonsCreated + 1, numButtonsToDisplay do
|
||||
local button = CreateFrame("BUTTON", "EventTraceFrameButton" .. i, self, "EventTraceEventTemplate");
|
||||
button:SetPoint("BOTTOMLEFT", 12, (16 * (i - 1)) + 12);
|
||||
button:SetPoint("RIGHT", -28, 0);
|
||||
tinsert(self.buttons, button);
|
||||
end
|
||||
for i = self.visibleButtons + 1, numButtonsToDisplay do
|
||||
self.buttons[i]:Show();
|
||||
end
|
||||
self.visibleButtons = numButtonsToDisplay;
|
||||
EventTraceFrame_Update();
|
||||
elseif ( self.visibleButtons < numButtonsToDisplay ) then
|
||||
for i = self.visibleButtons + 1, numButtonsToDisplay do
|
||||
self.buttons[i]:Show();
|
||||
end
|
||||
self.visibleButtons = numButtonsToDisplay;
|
||||
EventTraceFrame_Update();
|
||||
elseif ( numButtonsToDisplay < self.visibleButtons ) then
|
||||
for i = numButtonsToDisplay + 1, self.visibleButtons do
|
||||
self.buttons[i]:Hide();
|
||||
end
|
||||
self.visibleButtons = numButtonsToDisplay;
|
||||
end
|
||||
end
|
||||
|
||||
function EventTraceFrame_Update ()
|
||||
local offset = 0;
|
||||
|
||||
local scrollBar = _G["EventTraceFrameScroll"];
|
||||
local scrollBarValue = scrollBar:GetValue();
|
||||
local minValue, maxValue = scrollBar:GetMinMaxValues();
|
||||
|
||||
local firstID = max(1, _EventTraceFrame.lastIndex - EVENT_TRACE_MAX_ENTRIES + 1);
|
||||
local lastID = _EventTraceFrame.lastIndex or 1;
|
||||
|
||||
if ( firstID >= lastID ) then
|
||||
scrollBar:SetMinMaxValues(firstID-1, lastID);
|
||||
else
|
||||
scrollBar:SetMinMaxValues(firstID, lastID);
|
||||
end
|
||||
if ( scrollBarValue < firstID ) then
|
||||
scrollBar:SetValue(firstID);
|
||||
scrollBarValue = firstID;
|
||||
end
|
||||
|
||||
if ( scrollBarValue < 1 ) then
|
||||
scrollBarValue = 1;
|
||||
elseif ( not _EventTraceFrame.selectedEvent ) then
|
||||
if ( scrollBarValue == maxValue ) then
|
||||
scrollBar:SetValue(_EventTraceFrame.lastIndex);
|
||||
end
|
||||
end
|
||||
|
||||
for i = 1, _EventTraceFrame.visibleButtons do
|
||||
local button = _EventTraceFrame.buttons[i];
|
||||
if ( button ) then
|
||||
local index = scrollBarValue - (i - 1);
|
||||
local event = _EventTraceFrame.events[index];
|
||||
if ( event ) then
|
||||
local timeString = _EventTraceFrame.times[index]
|
||||
button.index = index;
|
||||
button.time:SetText(timeString);
|
||||
button.event:SetText(event);
|
||||
local color = EVENT_TRACE_EVENT_COLORS[event] or EVENT_TRACE_EVENT_COLORS[timeString];
|
||||
if ( color ) then
|
||||
button.time:SetTextColor(unpack(color));
|
||||
button.event:SetTextColor(unpack(color));
|
||||
else
|
||||
button.time:SetTextColor(1, 1, 1, 1);
|
||||
button.event:SetTextColor(1, 1, 1, 1);
|
||||
end
|
||||
button:Show();
|
||||
if ( _EventTraceFrame.selectedEvent ) then
|
||||
if ( index == _EventTraceFrame.selectedEvent ) then
|
||||
EventTraceFrameEvent_DisplayTooltip(button);
|
||||
button:GetHighlightTexture():SetVertexColor(.15, .25, 1, .35);
|
||||
button:LockHighlight(true);
|
||||
button.wasSelected = true;
|
||||
elseif ( button.wasSelected ) then
|
||||
button.wasSelected = nil;
|
||||
button:GetHighlightTexture():SetVertexColor(.8, .8, 1, .15);
|
||||
button:UnlockHighlight();
|
||||
end
|
||||
else
|
||||
if ( button.wasSelected ) then
|
||||
button.wasSelected = nil;
|
||||
button:GetHighlightTexture():SetVertexColor(.8, .8, 1, .15);
|
||||
button:UnlockHighlight();
|
||||
end
|
||||
if ( button:IsMouseOver() ) then
|
||||
EventTraceFrameEvent_OnEnter(button);
|
||||
end
|
||||
end
|
||||
else
|
||||
button.index = index;
|
||||
button:Hide();
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
EventTraceFrame_UpdateKeyboardStatus();
|
||||
end
|
||||
|
||||
function EventTraceFrame_StartEventCapture ()
|
||||
if ( _EventTraceFrame.started ) then -- Nothing to do?
|
||||
return;
|
||||
end
|
||||
|
||||
_EventTraceFrame.started = true;
|
||||
_framesSinceLast = 0;
|
||||
_timeSinceLast = 0;
|
||||
_EventTraceFrame:RegisterAllEvents();
|
||||
EventTraceFrame_OnEvent(_EventTraceFrame, "Begin Capture");
|
||||
end
|
||||
|
||||
function EventTraceFrame_StopEventCapture ()
|
||||
if ( not _EventTraceFrame.started ) then -- Nothing to do!
|
||||
return;
|
||||
end
|
||||
|
||||
_EventTraceFrame.started = false;
|
||||
_framesSinceLast = 0;
|
||||
_timeSinceLast = 0;
|
||||
_EventTraceFrame:UnregisterAllEvents();
|
||||
EventTraceFrame_OnEvent(_EventTraceFrame, "End Capture");
|
||||
end
|
||||
|
||||
function EventTraceFrame_HandleSlashCmd (msg)
|
||||
msg = strlower(msg);
|
||||
if ( msg == "start" ) then
|
||||
EventTraceFrame_StartEventCapture();
|
||||
elseif ( msg == "stop" ) then
|
||||
EventTraceFrame_StopEventCapture();
|
||||
elseif ( tonumber(msg) and tonumber(msg) > 0 ) then
|
||||
if ( not _EventTraceFrame.started ) then
|
||||
_EventTraceFrame.eventsToCapture = tonumber(msg);
|
||||
EventTraceFrame_StartEventCapture();
|
||||
end
|
||||
elseif ( msg == "" ) then
|
||||
if ( not _EventTraceFrame:IsShown() ) then
|
||||
_EventTraceFrame:Show();
|
||||
if ( _EventTraceFrame.started == nil ) then
|
||||
EventTraceFrame_StartEventCapture(); -- If this is the first time we're showing the window, start capturing events immediately.
|
||||
end
|
||||
else
|
||||
_EventTraceFrame:Hide();
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function EventTraceFrame_OnMouseWheel (self, delta)
|
||||
local scrollBar = _G["EventTraceFrameScroll"];
|
||||
local minVal, maxVal = scrollBar:GetMinMaxValues();
|
||||
local currentValue = scrollBar:GetValue();
|
||||
|
||||
local newValue = currentValue - ( delta * 3 );
|
||||
newValue = max(newValue, minVal);
|
||||
newValue = min(newValue, maxVal);
|
||||
if ( newValue ~= currentValue ) then
|
||||
scrollBar:SetValue(newValue);
|
||||
end
|
||||
end
|
||||
|
||||
function EventTraceFrame_UpdateKeyboardStatus ()
|
||||
if ( _EventTraceFrame.selectedEvent ) then
|
||||
local focus = GetMouseFocus();
|
||||
if ( focus == _EventTraceFrame or (focus and focus:GetParent() == _EventTraceFrame) ) then
|
||||
_EventTraceFrame:EnableKeyboard(true);
|
||||
return;
|
||||
end
|
||||
end
|
||||
_EventTraceFrame:EnableKeyboard(false);
|
||||
end
|
||||
|
||||
function EventTraceFrame_OnKeyUp (self, key)
|
||||
if ( key == "ESCAPE" ) then
|
||||
self.selectedEvent = nil;
|
||||
EventTraceTooltip:Hide();
|
||||
EventTraceFrame_Update();
|
||||
end
|
||||
end
|
||||
|
||||
local TIME_ENTRY_FORMAT = "Time:";
|
||||
local DETAILS_ENTRY_FORMAT = "Details:";
|
||||
local ARGUMENT_ENTRY_FORMAT = "arg %d:";
|
||||
|
||||
local function EventTrace_FormatArgValue (val)
|
||||
if ( type(val) == "string" ) then
|
||||
return string.format('"%s"', val);
|
||||
elseif ( type(val) == "number" ) then
|
||||
return tostring(val);
|
||||
elseif ( type(val) == "bool" ) then
|
||||
return string.format('|cffaaaaff%s|r', tostring(val));
|
||||
elseif ( type(val) == "table" or type(val) == "bool" ) then
|
||||
return string.format('|cffffaaaa%s|r', tostring(val));
|
||||
end
|
||||
end
|
||||
|
||||
function EventTraceFrameEvent_DisplayTooltip (eventButton)
|
||||
local index = eventButton.index;
|
||||
if ( not index ) then
|
||||
return;
|
||||
end
|
||||
|
||||
local tooltip = _G["EventTraceTooltip"];
|
||||
tooltip:SetOwner(eventButton, "ANCHOR_NONE");
|
||||
tooltip:SetPoint("TOPLEFT", eventButton, "TOPRIGHT", 24, 2);
|
||||
local timeString = _EventTraceFrame.times[index]
|
||||
if ( EVENT_TRACE_SYSTEM_TIMES[timeString] ) then
|
||||
tooltip:AddLine(timeString, 1, 1, 1);
|
||||
tooltip:AddDoubleLine(string.format(TIME_ENTRY_FORMAT), _EventTraceFrame.rawtimes[index], 1, .82, 0, 1, 1, 1);
|
||||
tooltip:AddDoubleLine(string.format(DETAILS_ENTRY_FORMAT), _EventTraceFrame.events[index], 1, .82, 0, 1, 1, 1);
|
||||
else
|
||||
tooltip:AddLine(_EventTraceFrame.events[index], 1, 1, 1);
|
||||
tooltip:AddDoubleLine(string.format(TIME_ENTRY_FORMAT), _EventTraceFrame.rawtimes[index], 1, .82, 0, 1, 1, 1);
|
||||
for k, v in ipairs(EventTraceFrame.args) do
|
||||
if ( v[index] ) then
|
||||
tooltip:AddDoubleLine(string.format(ARGUMENT_ENTRY_FORMAT, k), EventTrace_FormatArgValue(v[index]), 1, .82, 0, 1, 1, 1);
|
||||
end
|
||||
end
|
||||
end
|
||||
tooltip:Show();
|
||||
end
|
||||
|
||||
function EventTraceFrameEvent_OnEnter (self)
|
||||
if ( _EventTraceFrame.selectedEvent ) then
|
||||
return;
|
||||
else
|
||||
EventTraceFrameEvent_DisplayTooltip(self);
|
||||
end
|
||||
end
|
||||
|
||||
function EventTraceFrameEvent_OnLeave (self)
|
||||
if ( not _EventTraceFrame.selectedEvent ) then
|
||||
EventTraceTooltip:Hide();
|
||||
end
|
||||
end
|
||||
|
||||
function EventTraceFrameEvent_OnClick (self)
|
||||
if ( _EventTraceFrame.selectedEvent == self.index ) then
|
||||
_EventTraceFrame.selectedEvent = nil;
|
||||
else
|
||||
_EventTraceFrame.selectedEvent = self.index;
|
||||
end
|
||||
EventTraceFrame_Update();
|
||||
end
|
||||
|
||||
local ERROR_FORMAT = [[|cffffd200Message:|cffffffff %s
|
||||
|cffffd200Time:|cffffffff %s
|
||||
|cffffd200Count:|cffffffff %s
|
||||
|cffffd200Stack:|cffffffff %s
|
||||
|cffffd200Locals:|cffffffff %s]];
|
||||
|
||||
local INDEX_ORDER_FORMAT = "%d / %d"
|
||||
|
||||
local _ScriptErrorsFrame;
|
||||
|
||||
function ScriptErrorsFrame_OnLoad (self)
|
||||
self.title:SetText(LUA_ERROR);
|
||||
self:RegisterForDrag("LeftButton");
|
||||
self.seen = {};
|
||||
self.order = {};
|
||||
self.count = {};
|
||||
self.messages = {};
|
||||
self.times = {};
|
||||
self.locals = {};
|
||||
_ScriptErrorsFrame = self;
|
||||
end
|
||||
|
||||
function ScriptErrorsFrame_OnShow (self)
|
||||
ScriptErrorsFrame_Update();
|
||||
end
|
||||
|
||||
function ScriptErrorsFrame_OnError (message, keepHidden)
|
||||
local stack = debugstack(DEBUGLOCALS_LEVEL);
|
||||
|
||||
local messageStack = message..stack; -- Fix me later
|
||||
|
||||
if ( _ScriptErrorsFrame ) then
|
||||
local index = _ScriptErrorsFrame.seen[messageStack];
|
||||
if ( index ) then
|
||||
_ScriptErrorsFrame.count[index] = _ScriptErrorsFrame.count[index] + 1;
|
||||
_ScriptErrorsFrame.messages[index] = message;
|
||||
_ScriptErrorsFrame.times[index] = date();
|
||||
_ScriptErrorsFrame.locals[index] = debuglocals(DEBUGLOCALS_LEVEL);
|
||||
else
|
||||
tinsert(_ScriptErrorsFrame.order, stack);
|
||||
index = #_ScriptErrorsFrame.order;
|
||||
_ScriptErrorsFrame.count[index] = 1;
|
||||
_ScriptErrorsFrame.messages[index] = message;
|
||||
_ScriptErrorsFrame.times[index] = date();
|
||||
_ScriptErrorsFrame.seen[messageStack] = index;
|
||||
_ScriptErrorsFrame.locals[index] = debuglocals(DEBUGLOCALS_LEVEL);
|
||||
end
|
||||
|
||||
if ( not _ScriptErrorsFrame:IsShown() and not keepHidden ) then
|
||||
_ScriptErrorsFrame.index = index;
|
||||
_ScriptErrorsFrame:Show();
|
||||
else
|
||||
ScriptErrorsFrame_Update();
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function ScriptErrorsFrame_Update ()
|
||||
local editBox = ScriptErrorsFrameScrollFrameText;
|
||||
local index = _ScriptErrorsFrame.index;
|
||||
if ( not index or not _ScriptErrorsFrame.order[index] ) then
|
||||
index = #_ScriptErrorsFrame.order;
|
||||
_ScriptErrorsFrame.index = index;
|
||||
end
|
||||
|
||||
if ( index == 0 ) then
|
||||
editBox:SetText("");
|
||||
ScriptErrorsFrame_UpdateButtons();
|
||||
return;
|
||||
end
|
||||
|
||||
local text = string.format(
|
||||
ERROR_FORMAT,
|
||||
_ScriptErrorsFrame.messages[index],
|
||||
_ScriptErrorsFrame.times[index],
|
||||
_ScriptErrorsFrame.count[index],
|
||||
_ScriptErrorsFrame.order[index],
|
||||
_ScriptErrorsFrame.locals[index]
|
||||
);
|
||||
|
||||
local parent = editBox:GetParent();
|
||||
local prevText = editBox.text;
|
||||
editBox.text = text;
|
||||
if ( prevText ~= text ) then
|
||||
editBox:SetText(text);
|
||||
editBox:HighlightText(0);
|
||||
editBox:SetCursorPosition(0);
|
||||
else
|
||||
ScrollingEdit_OnTextChanged(editBox, parent);
|
||||
end
|
||||
parent:SetVerticalScroll(0);
|
||||
|
||||
ScriptErrorsFrame_UpdateButtons();
|
||||
end
|
||||
|
||||
function ScriptErrorsFrame_UpdateButtons ()
|
||||
local index = _ScriptErrorsFrame.index;
|
||||
local numErrors = #_ScriptErrorsFrame.order;
|
||||
if ( index == 0 ) then
|
||||
_ScriptErrorsFrame.next:Disable();
|
||||
_ScriptErrorsFrame.previous:Disable();
|
||||
else
|
||||
if ( numErrors == 1 ) then
|
||||
_ScriptErrorsFrame.next:Disable();
|
||||
_ScriptErrorsFrame.previous:Disable();
|
||||
elseif ( index == 1 ) then
|
||||
_ScriptErrorsFrame.next:Enable();
|
||||
_ScriptErrorsFrame.previous:Disable();
|
||||
elseif ( index == numErrors ) then
|
||||
_ScriptErrorsFrame.next:Disable();
|
||||
_ScriptErrorsFrame.previous:Enable();
|
||||
else
|
||||
_ScriptErrorsFrame.next:Enable();
|
||||
_ScriptErrorsFrame.previous:Enable();
|
||||
end
|
||||
end
|
||||
|
||||
_ScriptErrorsFrame.indexLabel:SetText(string.format(INDEX_ORDER_FORMAT, index, numErrors));
|
||||
end
|
||||
|
||||
function ScriptErrorsFrame_DeleteError (index)
|
||||
if ( _ScriptErrorsFrame.order[index] ) then
|
||||
_ScriptErrorsFrame.seen[_ScriptErrorsFrame.messages[index] .. _ScriptErrorsFrame.order[index]] = nil;
|
||||
tremove(_ScriptErrorsFrame.order, index);
|
||||
tremove(_ScriptErrorsFrame.messages, index);
|
||||
tremove(_ScriptErrorsFrame.times, index);
|
||||
tremove(_ScriptErrorsFrame.count, index);
|
||||
end
|
||||
end
|
||||
|
||||
function ScriptErrorsFrameButton_OnClick (self)
|
||||
local id = self:GetID();
|
||||
|
||||
|
||||
if ( id == 1 ) then
|
||||
_ScriptErrorsFrame.index = _ScriptErrorsFrame.index + 1;
|
||||
else
|
||||
_ScriptErrorsFrame.index = _ScriptErrorsFrame.index - 1;
|
||||
end
|
||||
|
||||
ScriptErrorsFrame_Update();
|
||||
end
|
||||
|
||||
--[[ function ScriptErrorsFrameDelete_OnClick (self);
|
||||
local index = _ScriptErrorsFrame.index;
|
||||
ScriptErrorsFrame_DeleteError(index);
|
||||
|
||||
local numErrors = #_ScriptErrorsFrame.order;
|
||||
if ( numErrors == 0 ) then
|
||||
_ScriptErrorsFrame.index = 0;
|
||||
elseif ( index > numErrors ) then
|
||||
_ScriptErrorsFrame.index = numErrors;
|
||||
end
|
||||
|
||||
ScriptErrorsFrame_Update();
|
||||
end ]]
|
||||
|
||||
function DebugTooltip_OnLoad(self)
|
||||
self:SetFrameLevel(self:GetFrameLevel() + 2);
|
||||
self:SetBackdropBorderColor(TOOLTIP_DEFAULT_COLOR.r, TOOLTIP_DEFAULT_COLOR.g, TOOLTIP_DEFAULT_COLOR.b);
|
||||
self:SetBackdropColor(TOOLTIP_DEFAULT_BACKGROUND_COLOR.r, TOOLTIP_DEFAULT_BACKGROUND_COLOR.g, TOOLTIP_DEFAULT_BACKGROUND_COLOR.b);
|
||||
self.statusBar2 = getglobal(self:GetName().."StatusBar2");
|
||||
self.statusBar2Text = getglobal(self:GetName().."StatusBar2Text");
|
||||
end
|
||||
|
||||
function FrameStackTooltip_Toggle (showHidden)
|
||||
local tooltip = _G["FrameStackTooltip"];
|
||||
if ( tooltip:IsVisible() ) then
|
||||
tooltip:Hide();
|
||||
else
|
||||
tooltip:SetOwner(UIParent, "ANCHOR_NONE");
|
||||
tooltip:SetPoint("BOTTOMRIGHT", UIParent, "BOTTOMRIGHT", -CONTAINER_OFFSET_X - 13, CONTAINER_OFFSET_Y);
|
||||
tooltip.default = 1;
|
||||
tooltip.showHidden = showHidden;
|
||||
tooltip:SetFrameStack(showHidden);
|
||||
end
|
||||
end
|
||||
|
||||
FRAMESTACK_UPDATE_TIME = .1
|
||||
local _timeSinceLast = 0
|
||||
function FrameStackTooltip_OnUpdate (self, elapsed)
|
||||
_timeSinceLast = _timeSinceLast - elapsed;
|
||||
if ( _timeSinceLast <= 0 ) then
|
||||
_timeSinceLast = FRAMESTACK_UPDATE_TIME;
|
||||
self:SetFrameStack(self.showHidden);
|
||||
end
|
||||
end
|
||||
|
||||
function FrameStackTooltip_OnShow (self)
|
||||
local parent = self:GetParent() or UIParent;
|
||||
local ps = parent:GetEffectiveScale();
|
||||
local px, py = parent:GetCenter();
|
||||
px, py = px * ps, py * ps;
|
||||
local x, y = GetCursorPosition();
|
||||
self:ClearAllPoints();
|
||||
if (x > px) then
|
||||
if (y > py) then
|
||||
self:SetPoint("BOTTOMLEFT", parent, "BOTTOMLEFT", 20, 20);
|
||||
else
|
||||
self:SetPoint("TOPLEFT", parent, "TOPLEFT", 20, -20);
|
||||
end
|
||||
else
|
||||
if (y > py) then
|
||||
self:SetPoint("BOTTOMRIGHT", parent, "BOTTOMRIGHT", -20, 20);
|
||||
else
|
||||
self:SetPoint("TOPRIGHT", parent, "TOPRIGHT", -20, -20);
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
FrameStackTooltip_OnEnter = FrameStackTooltip_OnShow;
|
||||
@@ -0,0 +1,12 @@
|
||||
## Interface: 30300
|
||||
## Title: Blizzard UI Debug Tools
|
||||
## Notes: Tools for developing addons
|
||||
## Secure: 1
|
||||
## Author: Blizzard Entertainment
|
||||
## Special Thanks: Iriel, Kirov, Esamynn
|
||||
## Version: 1.0
|
||||
## LoadOnDemand: 1
|
||||
Dump.lua
|
||||
Blizzard_DebugTools.lua
|
||||
Blizzard_DebugTools.xml
|
||||
Localization.lua
|
||||
@@ -0,0 +1,349 @@
|
||||
<Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/
|
||||
..\..\FrameXML\UI.xsd">
|
||||
<FontString name="EventTraceTimeFont" font="fonts\arialn.ttf" justifyH="RIGHT" virtual="true">
|
||||
<FontHeight val="10"/>
|
||||
<Color r="1" g="1" b="1" a="1"/>
|
||||
</FontString>
|
||||
|
||||
<Button name="EventTraceEventTemplate" virtual="true">
|
||||
<Size x="0" y="16"/>
|
||||
<Layers>
|
||||
<Layer level="ARTWORK">
|
||||
<FontString parentKey="time" inherits="EventTraceTimeFont">
|
||||
<Anchors>
|
||||
<Anchor point="TOPLEFT"/>
|
||||
<Anchor point="TOPRIGHT" relativePoint="TOPLEFT">
|
||||
<Offset x="62" y="0"/>
|
||||
</Anchor>
|
||||
<Anchor point="BOTTOM"/>
|
||||
</Anchors>
|
||||
</FontString>
|
||||
<FontString parentKey="event" inherits="GameFontHighlightSmallLeft">
|
||||
<Anchors>
|
||||
<Anchor point="TOPRIGHT"/>
|
||||
<Anchor point="TOPLEFT">
|
||||
<Offset x="70" y="0"/>
|
||||
</Anchor>
|
||||
<Anchor point="BOTTOM"/>
|
||||
</Anchors>
|
||||
</FontString>
|
||||
</Layer>
|
||||
</Layers>
|
||||
<Scripts>
|
||||
<OnLoad>
|
||||
self:GetHighlightTexture():SetAlpha(.15);
|
||||
</OnLoad>
|
||||
<OnEnter function="EventTraceFrameEvent_OnEnter"/>
|
||||
<OnLeave function="EventTraceFrameEvent_OnLeave"/>
|
||||
<OnClick function="EventTraceFrameEvent_OnClick"/>
|
||||
</Scripts>
|
||||
<HighlightTexture setAllPoints="true" alphaMode="ADD">
|
||||
<Color r=".8" g=".8" b="1" a="1"/>
|
||||
</HighlightTexture>
|
||||
</Button>
|
||||
|
||||
<Frame name="EventTraceFrame" parent="UIParent" movable="true" clampedToScreen="true" hidden="true" frameStrata="MEDIUM" toplevel="true">
|
||||
<Size x="306" y="505"/>
|
||||
<Anchors>
|
||||
<Anchor point="LEFT">
|
||||
<Offset x="64" y="0"/>
|
||||
</Anchor>
|
||||
</Anchors>
|
||||
<Layers>
|
||||
<Layer level="BACKGROUND">
|
||||
<Texture name="$parentTitleBG" file="Interface\PaperDollInfoFrame\UI-GearManager-Title-Background">
|
||||
<Anchors>
|
||||
<Anchor point="TOPLEFT">
|
||||
<Offset x="9" y="-6"/>
|
||||
</Anchor>
|
||||
<Anchor point="BOTTOMRIGHT" relativePoint="TOPRIGHT">
|
||||
<Offset x="-28" y="-24"/>
|
||||
</Anchor>
|
||||
</Anchors>
|
||||
</Texture>
|
||||
<Texture name="$parentDialogBG" file="Interface\Tooltips\UI-Tooltip-Background">
|
||||
<Anchors>
|
||||
<Anchor point="TOPLEFT">
|
||||
<Offset x="8" y="-24"/>
|
||||
</Anchor>
|
||||
<Anchor point="BOTTOMRIGHT">
|
||||
<Offset x="-6" y="8"/>
|
||||
</Anchor>
|
||||
</Anchors>
|
||||
<Color r="0" g="0" b="0" a=".75"/>
|
||||
</Texture>
|
||||
</Layer>
|
||||
<Layer level="BORDER">
|
||||
<Texture name="$parentTopLeft" file="Interface\PaperDollInfoFrame\UI-GearManager-Border">
|
||||
<Size x="64" y="64"/>
|
||||
<Anchors>
|
||||
<Anchor point="TOPLEFT"/>
|
||||
</Anchors>
|
||||
<TexCoords left="0.501953125" right="0.625" top="0" bottom="1"/>
|
||||
</Texture>
|
||||
<Texture name="$parentTopRight" file="Interface\PaperDollInfoFrame\UI-GearManager-Border">
|
||||
<Size x="64" y="64"/>
|
||||
<Anchors>
|
||||
<Anchor point="TOPRIGHT"/>
|
||||
</Anchors>
|
||||
<TexCoords left="0.625" right="0.75" top="0" bottom="1"/>
|
||||
</Texture>
|
||||
<Texture name="$parentTop" file="Interface\PaperDollInfoFrame\UI-GearManager-Border">
|
||||
<Size x="0" y="64"/>
|
||||
<Anchors>
|
||||
<Anchor point="TOPLEFT" relativeTo="$parentTopLeft" relativePoint="TOPRIGHT"/>
|
||||
<Anchor point="TOPRIGHT" relativeTo="$parentTopRight" relativePoint="TOPLEFT"/>
|
||||
</Anchors>
|
||||
<TexCoords left="0.25" right="0.369140625" top="0" bottom="1"/>
|
||||
</Texture>
|
||||
<Texture name="$parentBottomLeft" file="Interface\PaperDollInfoFrame\UI-GearManager-Border">
|
||||
<Size x="64" y="64"/>
|
||||
<Anchors>
|
||||
<Anchor point="BOTTOMLEFT"/>
|
||||
</Anchors>
|
||||
<TexCoords left="0.751953125" right="0.875" top="0" bottom="1"/>
|
||||
</Texture>
|
||||
<Texture name="$parentBottomRight" file="Interface\PaperDollInfoFrame\UI-GearManager-Border">
|
||||
<Size x="64" y="64"/>
|
||||
<Anchors>
|
||||
<Anchor point="BOTTOMRIGHT"/>
|
||||
</Anchors>
|
||||
<TexCoords left="0.875" right="1" top="0" bottom="1"/>
|
||||
</Texture>
|
||||
<Texture name="$parentBottom" file="Interface\PaperDollInfoFrame\UI-GearManager-Border">
|
||||
<Size x="0" y="64"/>
|
||||
<Anchors>
|
||||
<Anchor point="BOTTOMLEFT" relativeTo="$parentBottomLeft" relativePoint="BOTTOMRIGHT"/>
|
||||
<Anchor point="BOTTOMRIGHT" relativeTo="$parentBottomRight" relativePoint="BOTTOMLEFT"/>
|
||||
</Anchors>
|
||||
<TexCoords left="0.376953125" right="0.498046875" top="0" bottom="1"/>
|
||||
</Texture>
|
||||
<Texture name="$parentLeft" file="Interface\PaperDollInfoFrame\UI-GearManager-Border">
|
||||
<Size x="64" y="0"/>
|
||||
<Anchors>
|
||||
<Anchor point="TOPLEFT" relativeTo="$parentTopLeft" relativePoint="BOTTOMLEFT"/>
|
||||
<Anchor point="BOTTOMLEFT" relativeTo="$parentBottomLeft" relativePoint="TOPLEFT"/>
|
||||
</Anchors>
|
||||
<TexCoords left="0.001953125" right="0.125" top="0" bottom="1"/>
|
||||
</Texture>
|
||||
<Texture name="$parentRight" file="Interface\PaperDollInfoFrame\UI-GearManager-Border">
|
||||
<Size x="64" y="0"/>
|
||||
<Anchors>
|
||||
<Anchor point="TOPRIGHT" relativeTo="$parentTopRight" relativePoint="BOTTOMRIGHT"/>
|
||||
<Anchor point="BOTTOMRIGHT" relativeTo="$parentBottomRight" relativePoint="TOPRIGHT"/>
|
||||
</Anchors>
|
||||
<TexCoords left="0.1171875" right="0.2421875" top="0" bottom="1"/>
|
||||
</Texture>
|
||||
</Layer>
|
||||
<Layer level="OVERLAY">
|
||||
<FontString name="$parentTitle" inherits="GameFontNormal" text="EVENTS_LABEL">
|
||||
<Anchors>
|
||||
<Anchor point="TOPLEFT">
|
||||
<Offset x="12" y="-8"/>
|
||||
</Anchor>
|
||||
<Anchor point="TOPRIGHT">
|
||||
<Offset x="-32" y="-8"/>
|
||||
</Anchor>
|
||||
</Anchors>
|
||||
</FontString>
|
||||
</Layer>
|
||||
</Layers>
|
||||
<Frames>
|
||||
<Button name="$parentCloseButton" inherits="UIPanelCloseButton">
|
||||
<Size>
|
||||
<AbsDimension x="32" y="32"/>
|
||||
</Size>
|
||||
<Anchors>
|
||||
<Anchor point="TOPRIGHT">
|
||||
<Offset x="2" y="1"/>
|
||||
</Anchor>
|
||||
</Anchors>
|
||||
</Button>
|
||||
<Frame name="$parentTitleButton">
|
||||
<Anchors>
|
||||
<Anchor point="TOPLEFT" relativeTo="$parentTitleBG"/>
|
||||
<Anchor point="BOTTOMRIGHT" relativeTo="$parentTitleBG"/>
|
||||
</Anchors>
|
||||
<Frames>
|
||||
<Frame name="$parentHighlight" setAllPoints="true" hidden="true">
|
||||
<Layers>
|
||||
<Layer level="OVERLAY">
|
||||
<Texture file="Interface\Buttons\UI-ListBox-Highlight" setAllPoints="true">
|
||||
<Color r="1" g="1" b="1" a="0.4"/>
|
||||
</Texture>
|
||||
</Layer>
|
||||
</Layers>
|
||||
</Frame>
|
||||
</Frames>
|
||||
<Scripts>
|
||||
<OnLoad>
|
||||
self:RegisterForDrag("LeftButton");
|
||||
</OnLoad>
|
||||
<OnDragStart>
|
||||
local eventTraceFrame = _G["EventTraceFrame"];
|
||||
eventTraceFrame.moving = true;
|
||||
eventTraceFrame:StartMoving();
|
||||
</OnDragStart>
|
||||
<OnDragStop>
|
||||
local eventTraceFrame = _G["EventTraceFrame"];
|
||||
eventTraceFrame.moving = nil;
|
||||
eventTraceFrame:StopMovingOrSizing();
|
||||
</OnDragStop>
|
||||
</Scripts>
|
||||
</Frame>
|
||||
<Slider name="$parentScroll">
|
||||
<Size x="16" y="0"/>
|
||||
<Anchors>
|
||||
<Anchor point="TOPRIGHT">
|
||||
<Offset x="-7" y="-28"/>
|
||||
</Anchor>
|
||||
<Anchor point="BOTTOMRIGHT">
|
||||
<Offset x="-7" y="10"/>
|
||||
</Anchor>
|
||||
</Anchors>
|
||||
<Layers>
|
||||
<Layer level="BACKGROUND">
|
||||
<Texture name="$parentBG" setAllPoints="true">
|
||||
<Color r=".8" g=".8" b="1" a="0.1"/>
|
||||
</Texture>
|
||||
</Layer>
|
||||
</Layers>
|
||||
<Scripts>
|
||||
<OnLoad>
|
||||
self:SetFrameLevel(self:GetFrameLevel() + 1);
|
||||
self:SetValue(0);
|
||||
self:SetValueStep(1);
|
||||
</OnLoad>
|
||||
</Scripts>
|
||||
<ThumbTexture parentKey="thumb" file="Interface\Buttons\UI-ScrollBar-Knob">
|
||||
<Size x="16" y="16"/>
|
||||
<TexCoords left="0.25" right="0.75" top="0.25" bottom="0.75"/>
|
||||
</ThumbTexture>
|
||||
</Slider>
|
||||
</Frames>
|
||||
<Scripts>
|
||||
<OnLoad function="EventTraceFrame_OnLoad"/>
|
||||
<OnEvent function="EventTraceFrame_OnEvent"/>
|
||||
<OnUpdate function="EventTraceFrame_OnUpdate"/>
|
||||
<OnKeyUp function="EventTraceFrame_OnKeyUp"/>
|
||||
<!-- <OnSizeChanged function="EventTraceFrame_OnSizeChanged"/> Set in EventTraceFrame_OnLoad -->
|
||||
</Scripts>
|
||||
</Frame>
|
||||
<Frame name="ScriptErrorsFrame" inherits="UIPanelDialogTemplate" movable="true" clampedToScreen="true" hidden="true" toplevel="true">
|
||||
<Size x="384" y="260"/>
|
||||
<Anchors>
|
||||
<Anchor point="CENTER"/>
|
||||
</Anchors>
|
||||
<Layers>
|
||||
<Layer level="ARTWORK">
|
||||
<FontString parentKey="indexLabel" font="GameFontNormalCenter">
|
||||
<Size x="70" y="16"/>
|
||||
<Anchors>
|
||||
<Anchor point="BOTTOMLEFT">
|
||||
<Offset x="208" y="16"/>
|
||||
</Anchor>
|
||||
</Anchors>
|
||||
</FontString>
|
||||
</Layer>
|
||||
</Layers>
|
||||
<Frames>
|
||||
<Frame name="$parentTitleButton">
|
||||
<Anchors>
|
||||
<Anchor point="TOPLEFT" relativeTo="$parentTitleBG"/>
|
||||
<Anchor point="BOTTOMRIGHT" relativeTo="$parentTitleBG"/>
|
||||
</Anchors>
|
||||
<Scripts>
|
||||
<OnLoad>
|
||||
self:RegisterForDrag("LeftButton");
|
||||
</OnLoad>
|
||||
<OnDragStart>
|
||||
local frame = _G["ScriptErrorsFrame"];
|
||||
frame.moving = true;
|
||||
frame:StartMoving();
|
||||
</OnDragStart>
|
||||
<OnDragStop>
|
||||
local frame = _G["ScriptErrorsFrame"];
|
||||
frame.moving = nil;
|
||||
frame:StopMovingOrSizing();
|
||||
</OnDragStop>
|
||||
</Scripts>
|
||||
</Frame>
|
||||
<ScrollFrame name="$parentScrollFrame" inherits="UIPanelScrollFrameTemplate">
|
||||
<Size x="343" y="194"/>
|
||||
<Anchors>
|
||||
<Anchor point="TOPLEFT">
|
||||
<Offset x="12" y="-30"/>
|
||||
</Anchor>
|
||||
</Anchors>
|
||||
<ScrollChild>
|
||||
<EditBox name="$parentText" multiLine="true" letters="4000" autoFocus="false">
|
||||
<Size x="343" y="194"/>
|
||||
<Scripts>
|
||||
<OnCursorChanged function="ScrollingEdit_OnCursorChanged"/>
|
||||
<OnUpdate>
|
||||
ScrollingEdit_OnUpdate(self, elapsed, self:GetParent());
|
||||
</OnUpdate>
|
||||
<OnEditFocusGained>
|
||||
self:HighlightText(0);
|
||||
</OnEditFocusGained>
|
||||
<OnEscapePressed function="EditBox_ClearFocus"/>
|
||||
</Scripts>
|
||||
<FontString inherits="GameFontHighlightSmall"/>
|
||||
</EditBox>
|
||||
</ScrollChild>
|
||||
</ScrollFrame>
|
||||
<Button parentKey="previous" inherits="UIPanelButtonTemplate" text="PREVIOUS" id="2">
|
||||
<Size x="96" y="24"/>
|
||||
<Anchors>
|
||||
<Anchor point="BOTTOMLEFT">
|
||||
<Offset x="12" y="12"/>
|
||||
</Anchor>
|
||||
</Anchors>
|
||||
<Scripts>
|
||||
<OnClick function="ScriptErrorsFrameButton_OnClick"/>
|
||||
</Scripts>
|
||||
</Button>
|
||||
<Button parentKey="next" inherits="UIPanelButtonTemplate" text="NEXT" id="1">
|
||||
<Size x="96" y="24"/>
|
||||
<Anchors>
|
||||
<Anchor point="BOTTOMLEFT">
|
||||
<Offset x="112" y="12"/>
|
||||
</Anchor>
|
||||
</Anchors>
|
||||
<Scripts>
|
||||
<OnClick function="ScriptErrorsFrameButton_OnClick"/>
|
||||
</Scripts>
|
||||
</Button>
|
||||
<Button parentKey="close" inherits="UIPanelButtonTemplate" text="CLOSE">
|
||||
<Size x="96" y="24"/>
|
||||
<Anchors>
|
||||
<Anchor point="BOTTOMRIGHT">
|
||||
<Offset x="-8" y="12"/>
|
||||
</Anchor>
|
||||
</Anchors>
|
||||
<Scripts>
|
||||
<OnClick function="HideParentPanel"/>
|
||||
</Scripts>
|
||||
</Button>
|
||||
</Frames>
|
||||
<Scripts>
|
||||
<OnLoad function="ScriptErrorsFrame_OnLoad"/>
|
||||
<OnShow function="ScriptErrorsFrame_OnShow"/>
|
||||
</Scripts>
|
||||
</Frame>
|
||||
|
||||
<GameTooltip name="FrameStackTooltip" frameStrata="TOOLTIP" hidden="true" parent="WorldFrame" inherits="GameTooltipTemplate">
|
||||
<Scripts>
|
||||
<OnLoad function="DebugTooltip_OnLoad"/>
|
||||
<OnShow function="FrameStackTooltip_OnShow"/>
|
||||
<OnEnter function="FrameStackTooltip_OnEnter"/>
|
||||
<OnUpdate function="FrameStackTooltip_OnUpdate"/>
|
||||
</Scripts>
|
||||
</GameTooltip>
|
||||
|
||||
<GameTooltip name="EventTraceTooltip" frameStrata="TOOLTIP" hidden="true" parent="EventTraceFrame" inherits="GameTooltipTemplate">
|
||||
<Scripts>
|
||||
<OnLoad function="DebugTooltip_OnLoad"/>
|
||||
</Scripts>
|
||||
</GameTooltip>
|
||||
</Ui>
|
||||
@@ -0,0 +1,408 @@
|
||||
------------------------------------------------------------------------------
|
||||
-- Dump.lua
|
||||
--
|
||||
-- Contributed by Iriel, Esamynn and Kirov from DevTools v1.11
|
||||
-- /dump Implementation
|
||||
--
|
||||
-- Globals: DevTools, SLASH_DEVTOOLSDUMP1, DevTools_Dump, DevTools_RunDump
|
||||
-- Globals: DEVTOOLS_MAX_ENTRY_CUTOFF, DEVTOOLS_LONG_STRING_CUTOFF
|
||||
-- Globals: DEVTOOLS_DEPTH_CUTOFF, DEVTOOLS_INDENT
|
||||
-- Globals: DEVTOOLS_USE_TABLE_CACHE, DEVTOOLS_USE_FUNCTION_CACHE
|
||||
-- Globals: DEVTOOLS_USE_USERDATA_CACHE
|
||||
---------------------------------------------------------------------------
|
||||
local DT = {};
|
||||
|
||||
DEVTOOLS_MAX_ENTRY_CUTOFF = 30; -- Maximum table entries shown
|
||||
DEVTOOLS_LONG_STRING_CUTOFF = 200; -- Maximum string size shown
|
||||
DEVTOOLS_DEPTH_CUTOFF = 10; -- Maximum table depth
|
||||
DEVTOOLS_USE_TABLE_CACHE = true; -- Look up table names
|
||||
DEVTOOLS_USE_FUNCTION_CACHE = true;-- Look up function names
|
||||
DEVTOOLS_USE_USERDATA_CACHE = true;-- Look up userdata names
|
||||
DEVTOOLS_INDENT=' '; -- Indentation string
|
||||
|
||||
local DEVTOOLS_TYPE_COLOR="|cff88ff88";
|
||||
local DEVTOOLS_TABLEREF_COLOR="|cffffcc00";
|
||||
local DEVTOOLS_CUTOFF_COLOR="|cffff0000";
|
||||
local DEVTOOLS_TABLEKEY_COLOR="|cff88ccff";
|
||||
|
||||
local FORMATS = {};
|
||||
-- prefix type suffix
|
||||
FORMATS["opaqueTypeVal"] = "%s" .. DEVTOOLS_TYPE_COLOR .. "<%s>|r%s";
|
||||
-- prefix type name suffix
|
||||
FORMATS["opaqueTypeValName"] = "%s" .. DEVTOOLS_TYPE_COLOR .. "<%s %s>|r%s";
|
||||
-- type
|
||||
FORMATS["opaqueTypeKey"] = "<%s>";
|
||||
-- type name
|
||||
FORMATS["opaqueTypeKeyName"] = "<%s %s>";
|
||||
-- value
|
||||
FORMATS["bracketTableKey"] = "[%s]";
|
||||
-- prefix value
|
||||
FORMATS["tableKeyAssignPrefix"] = DEVTOOLS_TABLEKEY_COLOR .. "%s%s|r=";
|
||||
-- prefix cutoff
|
||||
FORMATS["tableEntriesSkipped"] = "%s" .. DEVTOOLS_CUTOFF_COLOR .. "<skipped %s>|r";
|
||||
-- prefix suffix
|
||||
FORMATS["tableTooDeep"] = "%s" .. DEVTOOLS_CUTOFF_COLOR .. "<table (too deep)>|r%s";
|
||||
-- prefix value suffix
|
||||
FORMATS["simpleValue"] = "%s%s%s";
|
||||
-- prefix tablename suffix
|
||||
FORMATS["tableReference"] = "%s" .. DEVTOOLS_TABLEREF_COLOR .. "%s|r%s";
|
||||
|
||||
-- Grab a copy various oft-used functions
|
||||
local rawget = rawget;
|
||||
local type = type;
|
||||
local string_len = string.len;
|
||||
local string_sub = string.sub;
|
||||
local string_gsub = string.gsub;
|
||||
local string_format = string.format;
|
||||
local string_match = string.match;
|
||||
|
||||
local function WriteMessage(msg)
|
||||
DEFAULT_CHAT_FRAME:AddMessage(msg);
|
||||
end
|
||||
|
||||
local function prepSimple(val, context)
|
||||
local valType = type(val);
|
||||
if (valType == "nil") then
|
||||
return "nil";
|
||||
elseif (valType == "number") then
|
||||
return val;
|
||||
elseif (valType == "boolean") then
|
||||
if (val) then
|
||||
return "true";
|
||||
else
|
||||
return "false";
|
||||
end
|
||||
elseif (valType == "string") then
|
||||
local l = string_len(val);
|
||||
if ((l > DEVTOOLS_LONG_STRING_CUTOFF) and
|
||||
(DEVTOOLS_LONG_STRING_CUTOFF > 0)) then
|
||||
local more = l - DEVTOOLS_LONG_STRING_CUTOFF;
|
||||
val = string_sub(val, 1, DEVTOOLS_LONG_STRING_CUTOFF);
|
||||
return string_gsub(string_format("%q...+%s",val,more),"[|]", "||");
|
||||
else
|
||||
return string_gsub(string_format("%q",val),"[|]", "||");
|
||||
end
|
||||
elseif (valType == "function") then
|
||||
local fName = context:GetFunctionName(val);
|
||||
if (fName) then
|
||||
return string_format(FORMATS.opaqueTypeKeyName, valType, fName);
|
||||
else
|
||||
return string_format(FORMATS.opaqueTypeKey, valType);
|
||||
end
|
||||
return string_format(FORMATS.opaqueTypeKey, valType);
|
||||
elseif (valType == "userdata") then
|
||||
local uName = context:GetUserdataName(val);
|
||||
if (uName) then
|
||||
return string_format(FORMATS.opaqueTypeKeyName, valType, uName);
|
||||
else
|
||||
return string_format(FORMATS.opaqueTypeKey, valType);
|
||||
end
|
||||
elseif (valType == 'table') then
|
||||
local tName = context:GetTableName(val);
|
||||
if (tName) then
|
||||
return string_format(FORMATS.opaqueTypeKeyName, valType, tName);
|
||||
else
|
||||
return string_format(FORMATS.opaqueTypeKey, valType);
|
||||
end
|
||||
end
|
||||
error("Bad type '" .. valType .. "' to prepSimple");
|
||||
end
|
||||
|
||||
local function prepSimpleKey(val, context)
|
||||
local valType = type(val);
|
||||
if (valType == "string") then
|
||||
local l = string_len(val);
|
||||
if ((l <= DEVTOOLS_LONG_STRING_CUTOFF) or
|
||||
(DEVTOOLS_LONG_STRING_CUTOFF <= 0)) then
|
||||
if (string_match(val, "^[a-zA-Z_][a-zA-Z0-9_]*$")) then
|
||||
return val;
|
||||
end
|
||||
end
|
||||
end
|
||||
return string_format(FORMATS.bracketTableKey, prepSimple(val, context));
|
||||
end
|
||||
|
||||
local function DevTools_InitFunctionCache(context)
|
||||
local ret = {};
|
||||
|
||||
for _,k in ipairs(DT.functionSymbols) do
|
||||
local v = getglobal(k);
|
||||
if (type(v) == 'function') then
|
||||
ret[v] = '[' .. k .. ']';
|
||||
end
|
||||
end
|
||||
|
||||
for k,v in pairs(getfenv(0)) do
|
||||
if (type(v) == 'function') then
|
||||
if (not ret[v]) then
|
||||
ret[v] = '[' .. k .. ']';
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return ret;
|
||||
end
|
||||
|
||||
local function DevTools_InitUserdataCache(context)
|
||||
local ret = {};
|
||||
|
||||
for _,k in ipairs(DT.userdataSymbols) do
|
||||
local v = getglobal(k);
|
||||
if (type(v) == 'table') then
|
||||
local u = rawget(v,0);
|
||||
if (type(u) == 'userdata') then
|
||||
ret[u] = k .. '[0]';
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
for k,v in pairs(getfenv(0)) do
|
||||
if (type(v) == 'table') then
|
||||
local u = rawget(v, 0);
|
||||
if (type(u) == 'userdata') then
|
||||
if (not ret[u]) then
|
||||
ret[u] = k .. '[0]';
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return ret;
|
||||
end
|
||||
|
||||
local function DevTools_Cache_Nil(self, value, newName)
|
||||
return nil;
|
||||
end
|
||||
|
||||
local function DevTools_Cache_Function(self, value, newName)
|
||||
if (not self.fCache) then
|
||||
self.fCache = DevTools_InitFunctionCache(self);
|
||||
end
|
||||
local name = self.fCache[value];
|
||||
if ((not name) and newName) then
|
||||
self.fCache[value] = newName;
|
||||
end
|
||||
return name;
|
||||
end
|
||||
|
||||
local function DevTools_Cache_Userdata(self, value, newName)
|
||||
if (not self.uCache) then
|
||||
self.uCache = DevTools_InitUserdataCache(self);
|
||||
end
|
||||
local name = self.uCache[value];
|
||||
if ((not name) and newName) then
|
||||
self.uCache[value] = newName;
|
||||
end
|
||||
return name;
|
||||
end
|
||||
|
||||
local function DevTools_Cache_Table(self, value, newName)
|
||||
if (not self.tCache) then
|
||||
self.tCache = {};
|
||||
end
|
||||
local name = self.tCache[value];
|
||||
if ((not name) and newName) then
|
||||
self.tCache[value] = newName;
|
||||
end
|
||||
return name;
|
||||
end
|
||||
|
||||
local function DevTools_Write(self, msg)
|
||||
DEFAULT_CHAT_FRAME:AddMessage(msg);
|
||||
end
|
||||
|
||||
local DevTools_DumpValue;
|
||||
|
||||
local function DevTools_DumpTableContents(val, prefix, firstPrefix, context)
|
||||
local showCount = 0;
|
||||
local oldDepth = context.depth;
|
||||
local oldKey = context.key;
|
||||
|
||||
-- Use this to set the cache name
|
||||
context:GetTableName(val, oldKey or 'value');
|
||||
|
||||
local iter = pairs(val);
|
||||
local nextK, nextV = iter(val, nil);
|
||||
|
||||
while (nextK) do
|
||||
local k,v = nextK, nextV;
|
||||
nextK, nextV = iter(val, k);
|
||||
|
||||
showCount = showCount + 1;
|
||||
if ((showCount <= DEVTOOLS_MAX_ENTRY_CUTOFF) or
|
||||
(DEVTOOLS_MAX_ENTRY_CUTOFF <= 0)) then
|
||||
local prepKey = prepSimpleKey(k, context);
|
||||
if (oldKey == nil) then
|
||||
context.key = prepKey;
|
||||
elseif (string_sub(prepKey, 1, 1) == "[") then
|
||||
context.key = oldKey .. prepKey
|
||||
else
|
||||
context.key = oldKey .. "." .. prepKey
|
||||
end
|
||||
context.depth = oldDepth + 1;
|
||||
|
||||
local rp = string_format(FORMATS.tableKeyAssignPrefix, firstPrefix,
|
||||
prepKey);
|
||||
firstPrefix = prefix;
|
||||
DevTools_DumpValue(v, prefix, rp,
|
||||
(nextK and ",") or '',
|
||||
context);
|
||||
end
|
||||
end
|
||||
local cutoff = showCount - DEVTOOLS_MAX_ENTRY_CUTOFF;
|
||||
if ((cutoff > 0) and (DEVTOOLS_MAX_ENTRY_CUTOFF > 0)) then
|
||||
context:Write(string_format(FORMATS.tableEntriesSkipped,firstPrefix,
|
||||
cutoff));
|
||||
end
|
||||
context.key = oldKey;
|
||||
context.depth = oldDepth;
|
||||
return (showCount > 0)
|
||||
end
|
||||
|
||||
-- Return the specified value
|
||||
function DevTools_DumpValue(val, prefix, firstPrefix, suffix, context)
|
||||
local valType = type(val);
|
||||
|
||||
if (valType == "userdata") then
|
||||
local uName = context:GetUserdataName(val, 'value');
|
||||
if (uName) then
|
||||
context:Write(string_format(FORMATS.opaqueTypeValName,
|
||||
firstPrefix, valType, uName, suffix));
|
||||
else
|
||||
context:Write(string_format(FORMATS.opaqueTypeVal,
|
||||
firstPrefix, valType, suffix));
|
||||
end
|
||||
return;
|
||||
elseif (valType == "function") then
|
||||
local fName = context:GetFunctionName(val, 'value');
|
||||
if (fName) then
|
||||
context:Write(string_format(FORMATS.opaqueTypeValName,
|
||||
firstPrefix, valType, fName, suffix));
|
||||
else
|
||||
context:Write(string_format(FORMATS.opaqueTypeVal,
|
||||
firstPrefix, valType, suffix));
|
||||
end
|
||||
return;
|
||||
elseif (valType ~= "table") then
|
||||
context:Write(string_format(FORMATS.simpleValue,
|
||||
firstPrefix,prepSimple(val, context),
|
||||
suffix));
|
||||
return;
|
||||
end
|
||||
|
||||
local cacheName = context:GetTableName(val);
|
||||
if (cacheName) then
|
||||
context:Write(string_format(FORMATS.tableReference,
|
||||
firstPrefix, cacheName, suffix));
|
||||
return;
|
||||
end
|
||||
|
||||
if ((context.depth >= DEVTOOLS_DEPTH_CUTOFF) and
|
||||
(DEVTOOLS_DEPTH_CUTOFF > 0)) then
|
||||
context:Write(string_format(FORMATS.tableTooDeep,
|
||||
firstPrefix, suffix));
|
||||
return;
|
||||
end
|
||||
|
||||
firstPrefix = firstPrefix .. "{";
|
||||
local oldPrefix = prefix;
|
||||
prefix = prefix .. DEVTOOLS_INDENT;
|
||||
|
||||
context:Write(firstPrefix);
|
||||
firstPrefix = prefix;
|
||||
local anyContents = DevTools_DumpTableContents(val, prefix, firstPrefix,
|
||||
context);
|
||||
context:Write(oldPrefix .. "}" .. suffix);
|
||||
end
|
||||
|
||||
local function Pick_Cache_Function(func, setting)
|
||||
if (setting) then
|
||||
return func;
|
||||
else
|
||||
return DevTools_Cache_Nil;
|
||||
end
|
||||
end
|
||||
|
||||
function DevTools_RunDump(value, context)
|
||||
local prefix = "";
|
||||
local firstPrefix = prefix;
|
||||
|
||||
local valType = type(value);
|
||||
if (type(value) == 'table') then
|
||||
local any =
|
||||
DevTools_DumpTableContents(value, prefix, firstPrefix, context);
|
||||
if (context.Result) then
|
||||
return context:Result();
|
||||
end
|
||||
if (not any) then
|
||||
context:Write("empty result");
|
||||
end
|
||||
return;
|
||||
end
|
||||
|
||||
DevTools_DumpValue(value, '', '', '', context);
|
||||
if (context.Result) then
|
||||
return context:Result();
|
||||
end
|
||||
end
|
||||
|
||||
-- Dump the specified list of value
|
||||
function DevTools_Dump(value, startKey)
|
||||
local context = {
|
||||
depth = 0,
|
||||
key = startKey,
|
||||
};
|
||||
|
||||
context.GetTableName = Pick_Cache_Function(DevTools_Cache_Table,
|
||||
DEVTOOLS_USE_TABLE_CACHE);
|
||||
context.GetFunctionName = Pick_Cache_Function(DevTools_Cache_Function,
|
||||
DEVTOOLS_USE_FUNCTION_CACHE);
|
||||
context.GetUserdataName = Pick_Cache_Function(DevTools_Cache_Userdata,
|
||||
DEVTOOLS_USE_USERDATA_CACHE);
|
||||
context.Write = DevTools_Write;
|
||||
|
||||
DevTools_RunDump(value, context);
|
||||
end
|
||||
|
||||
function DevTools_DumpCommand(msg, editBox)
|
||||
forceinsecure();
|
||||
if (string_match(msg,"^[A-Za-z_][A-Za-z0-9_]*$")) then
|
||||
WriteMessage("Dump: " .. msg);
|
||||
local val = _G[msg];
|
||||
local tmp = {};
|
||||
if (val == nil) then
|
||||
local key = string_format(FORMATS.tableKeyAssignPrefix,
|
||||
'', prepSimpleKey(msg, {}));
|
||||
WriteMessage(key .. "nil,");
|
||||
else
|
||||
tmp[msg] = val;
|
||||
end
|
||||
DevTools_Dump(tmp);
|
||||
return;
|
||||
end
|
||||
|
||||
WriteMessage("Dump: value=" .. msg);
|
||||
local func,err = loadstring("return " .. msg);
|
||||
if (not func) then
|
||||
WriteMessage("Dump: ERROR: " .. err);
|
||||
else
|
||||
DevTools_Dump({ func() }, "value");
|
||||
end
|
||||
end
|
||||
|
||||
DT.functionSymbols = {};
|
||||
DT.userdataSymbols = {};
|
||||
|
||||
local funcSyms = DT.functionSymbols;
|
||||
local userSyms = DT.userdataSymbols;
|
||||
|
||||
for k,v in pairs(getfenv(0)) do
|
||||
if (type(v) == 'function') then
|
||||
table.insert(funcSyms, k);
|
||||
elseif (type(v) == 'table') then
|
||||
if (type(rawget(v,0)) == 'userdata') then
|
||||
table.insert(userSyms, k);
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
-- This file is executed at the end of addon load
|
||||
Reference in New Issue
Block a user