Thread Tools Display Modes
02/23/14, 02:12 PM   #1
SinusPi
AddOn Author - Click to view addons
Join Date: Feb 2014
Posts: 18
[AddOn] Zgoo - data inspection tool

To make the life of AddOn developers easier, here's Zgoo - made by @Errc and me.

Zgoo allows you to browse through tables and userdata to example their components in a nice and easy interface.

To use Zgoo, the chat command /zgoo is used.

/zgoo global
or
/zgoo _G

Examines the global table.

/zgoo GuiRoot
From there you can see all the children in the GetChildren table.

/zgoo Any_Variable
Examine any Lua variable or function result.

/zgoo mouse
Will examine the UI control that currently has your mouse's focus.

Click the [+] button to expand tables and user data. Click [.] or [:] to call functions.

Extras:
- GetChildren function added for all userdata elements. This allows for easy access and visibility to all children. (This is not available by default)
- A__Zgoo_ToggleHidden is an alias to ToggleHidden. Moved it up the list for easy access.


Zgoo Event Tracker

Track events in real time. Can unregister events by hitting the X button (reload to undo this). Hit + to expand the arguments for the event.

To use, type:

/zgoo events


Also for convenience (maybe):

/zgoo free
Will unlock your mouse from the reticle so you can freely move it around the screen.


Known Issues:
- if some function call breaks it all, hold CTRL to disable automatic calling of Get*,Is*,Can* functions.

Last edited by Cairenn : 02/24/14 at 07:22 AM. Reason: Removed zip, since it's now uploaded ~ Cairenn
  Reply With Quote
02/23/14, 03:13 PM   #2
Seerah
Fishing Trainer
 
Seerah's Avatar
WoWInterface Super Mod
AddOn Author - Click to view addons
Join Date: Feb 2014
Posts: 648
This should be uploaded to our Developer Mods category.
http://www.esoui.com/downloads/cat159.html
  Reply With Quote
02/23/14, 04:38 PM   #3
Cairenn
Credendo Vides
 
Cairenn's Avatar
Premium Member
WoWInterface Admin
Join Date: Mar 2004
Posts: 437
What Seerah said!

It looks really good, SinusPi, I can see it getting a ton of use.
  Reply With Quote
02/23/14, 11:00 PM   #4
Nynaeve
 
Nynaeve's Avatar
Join Date: Feb 2014
Posts: 12
Looks awesome!
I used to use a macro/script in wow to find what's under the mouse, so much better with an add-on, though.

That said, for the last part, I thought there was already a keybind ingame ( . ) to bring you from the crosshair mode into cursor mode.
  Reply With Quote
02/23/14, 11:11 PM   #5
Seerah
Fishing Trainer
 
Seerah's Avatar
WoWInterface Super Mod
AddOn Author - Click to view addons
Join Date: Feb 2014
Posts: 648
That keybind disappeared with yesterday's patch.
  Reply With Quote
02/24/14, 05:16 AM   #6
Nynaeve
 
Nynaeve's Avatar
Join Date: Feb 2014
Posts: 12
Originally Posted by Seerah View Post
That keybind disappeared with yesterday's patch.
Ahh. I suppose/hope that's a bug, as they even have it as one of the loading screen tips.

Thanks for the workaround, SinusPi!
  Reply With Quote
02/28/14, 02:15 AM   #7
zork
 
zork's Avatar
AddOn Author - Click to view addons
Join Date: Feb 2014
Posts: 29
Here is the content of the debugutils.lua that I have found:
Lua Code:
  1. local function EmitMessage(text)
  2.     if(CHAT_SYSTEM)
  3.     then
  4.         if(text == "")
  5.         then
  6.             text = "[Empty String]"
  7.         end
  8.        
  9.         CHAT_SYSTEM:AddMessage(text)
  10.     end
  11. end
  12.  
  13. local function EmitTable(t, indent, tableHistory)
  14.     indent          = indent or "."
  15.     tableHistory    = tableHistory or {}
  16.    
  17.     for k, v in pairs(t)
  18.     do
  19.         local vType = type(v)
  20.  
  21.         EmitMessage(indent.."("..vType.."): "..tostring(k).." = "..tostring(v))
  22.        
  23.         if(vType == "table")
  24.         then
  25.             if(tableHistory[v])
  26.             then
  27.                 EmitMessage(indent.."Avoiding cycle on table...")
  28.             else
  29.                 tableHistory[v] = true
  30.                 EmitTable(v, indent.."  ", tableHistory)
  31.             end
  32.         end
  33.     end    
  34. end
  35.  
  36. function d(...)    
  37.     for i = 1, select("#", ...) do
  38.         local value = select(i, ...)
  39.         if(type(value) == "table")
  40.         then
  41.             EmitTable(value)
  42.         else
  43.             EmitMessage(tostring (value))
  44.         end
  45.     end
  46. end
  47.  
  48. function countGlobals(desiredType)
  49.     if(desiredType == nil)
  50.     then
  51.         countGlobals("number")
  52.         countGlobals("string")
  53.         countGlobals("boolean")
  54.         countGlobals("table")
  55.         countGlobals("function")
  56.         countGlobals("thread")
  57.         countGlobals("userdata")
  58.         return
  59.     end
  60.  
  61.     local count = 0
  62.     desiredType = tostring(desiredType)
  63.    
  64.     for k, v in pairs(_G)
  65.     do
  66.         if(type(v) == desiredType)
  67.         then
  68.             count = count + 1
  69.         end
  70.     end
  71.    
  72.     d("There are "..count.." variables of type "..desiredType)
  73. end
  74.  
  75. function eventArgumentDebugger(...)
  76.     local arg = { ... }    
  77.     local numArgs = #arg
  78.    
  79.     if(numArgs == 0)
  80.     then
  81.         return "[Unamed event, without arguments]"
  82.     end
  83.    
  84.     local eventName = arg[1]
  85.    
  86.     if(EVENT_NAME_LOOKUP) -- nice, we can get a string look up for this event code!  (TODO: just expose these as strings?)
  87.     then
  88.         eventName = EVENT_NAME_LOOKUP[eventName] or eventName
  89.     end
  90.    
  91.     local argString = "["..eventName.."]"
  92.     local currentArg
  93.    
  94.     for i = 2, numArgs
  95.     do
  96.         currentArg = arg[i]
  97.         if(type(currentArg) ~= "userdata")
  98.         then
  99.             argString = argString.."|c00ff00["..i.."]:|r "..tostring(currentArg)
  100.         else
  101.             -- Assume it's a control...which may not always be correct
  102.             argString = argString.."|c00ff00["..i.."]:|r "..currentArg:GetName()
  103.         end
  104.        
  105.         if(i < numArgs) then argString = argString..", " end
  106.     end
  107.    
  108.     return argString
  109. end
  110.  
  111. local eventRegistry = {}
  112.  
  113. function ZO_Debug_EventNotification(eventCode, register, allEvents)
  114.     local eventManager = GetEventManager()
  115.     local eventName = "ZO_Debug_EventNotification"..eventCode
  116.    
  117.     if(register and not eventRegistry[eventName])
  118.     then
  119.         eventRegistry[eventName] = true
  120.        
  121.         if(allEvents)
  122.         then
  123.             eventManager:RegisterForAllEvents(eventName, function(...) d(eventArgumentDebugger(...)) end)
  124.         else
  125.             eventManager:RegisterForEvent(eventName, eventCode, function(...) d(eventArgumentDebugger(...)) end)
  126.         end
  127.     else
  128.         eventRegistry[eventName] = nil
  129.         eventManager:UnregisterForEvent(eventName)
  130.     end
  131. end
  132.  
  133. -- Because typing is painful.
  134. e = ZO_Debug_EventNotification
  135.  
  136. function all() e(0, true, true) end
  137.  
  138. -- Convenience for multiple event registration only using event variables.
  139. -- Pass in multiple comma delimited events as the arguments:
  140. -- ZO_Debug_MultiEventRegister(EVENT_QUEST_LIST_UPDATED, EVENT_QUEST_CONDITION_COUNTER_CHANGED, EVENT_QUEST_TOOL_UPDATED, etc...)
  141. function ZO_Debug_MultiEventRegister(...)
  142.     for i = 1, select("#", ...)
  143.     do
  144.         -- NOTE: should be able to use arg[i] here, but it's not reliable...
  145.         local eventCode = select(i, ...)
  146.         e(eventCode, true, false)
  147.     end
  148. end
  149.  
  150. m = ZO_Debug_MultiEventRegister
  151.  
  152. --
  153. -- Execute a command with a well-known pattern over a range of numbers.
  154. -- You give a base command (like: "]createitem")
  155. -- and a range (start id, end id)
  156. -- This function executes it using ExecuteChatCommand(finalCommand) n times where n = end - start
  157. -- and where the id fed to ExecuteChatCommand is start + i.
  158. function ExecutePatternedChatCommand(commandBase, startId, endId)
  159.     if(type(startId) == "number" and type(endId) == "number" and endId > startId)
  160.     then
  161.         for i = startId, endId
  162.         do
  163.             ExecuteChatCommand(string.format("%s %s", commandBase, tostring(i)))
  164.         end
  165.     end
  166. end
  167.  
  168. expat = ExecutePatternedChatCommand
  169.  
  170. --
  171. -- Utility to grab the current mouse over window and display its details.
  172. -- stands for MouseOverName
  173. --
  174. function mon()
  175.     local control = moc()
  176.    
  177.     if(control and type(control) == "userdata")
  178.     then
  179.         d(control)
  180.     else
  181.         d("Mouse isn't over a control, or isn't over a mouseEnabled control.")
  182.     end
  183.    
  184.     return control
  185. end
  186.  
  187. function moc()
  188.     return WINDOW_MANAGER:GetMouseOverControl()
  189. end
  190.  
  191. local tierToString =
  192. {
  193.     [DT_LOW] = "LOW",
  194.     [DT_MEDIUM] = "MEDIUM",
  195.     [DT_HIGH] = "HIGH",
  196.     [DT_PARENT] = "PARENT",
  197. }
  198.  
  199. local layerToString =
  200. {
  201.     [DL_BACKGROUND] = "BACKGROUND",
  202.     [DL_CONTROLS] = "CONTROLS",
  203.     [DL_TEXT] = "TEXT",
  204.     [DL_OVERLAY] = "OVERLAY",
  205. }
  206.  
  207. local function drawInfo(control)
  208.     local drawTier = tierToString[control:GetDrawTier()] or tostring(control:GetDrawTier())
  209.     local drawLayer = layerToString[control:GetDrawLayer()] or tostring(control:GetDrawLayer())
  210.  
  211.     d(string.format("|c00ff00DrawInfo of: %s\n    Tier[%s] Layer[%s] Level[%d]", control:GetName(), drawTier, drawLayer, control:GetDrawLevel()))
  212. end
  213.  
  214. di = drawInfo

Not sure if all those functions are still alive the file is from last year.

Last edited by zork : 02/28/14 at 02:20 AM.
  Reply With Quote
02/28/14, 08:53 AM   #8
SinusPi
AddOn Author - Click to view addons
Join Date: Feb 2014
Posts: 18
Well, yeah, the table cycle check is in EmitMessage used by d() because it tries to output it all at once. Zgoo displays just the selected branches of a table, so cycles are permitted.
  Reply With Quote
04/11/14, 05:20 PM   #9
Joviex
 
Joviex's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2014
Posts: 42
Dude, excellent tool. Dont know how I missed this for so long.

Truely excellent.

Thanks
  Reply With Quote
04/25/14, 07:40 PM   #10
LilBudyWizer
AddOn Author - Click to view addons
Join Date: Apr 2014
Posts: 32
I would say it's by most used addon. It's priceless for both debugging and figuring out what function and whatnot that I need.
  Reply With Quote

ESOUI » Developer Discussions » Dev Tools » [AddOn] Zgoo - data inspection tool

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off