annotate LibFarmbuyer.lua @ 11:952c3ac0e783

GetItemQualityColor change and TOC bump for 4.2
author Farmbuyer of US-Kilrogg <farmbuyer@gmail.com>
date Tue, 28 Jun 2011 19:18:07 +0000
parents df3e27edbd60
children 5ee4edd24c13
rev   line source
farmbuyer@1 1 --[[
farmbuyer@1 2 Not really meant for public use. Stuff that I keep using everywhere and
farmbuyer@1 3 got tired of reimplementing, or even copy-and-pasting. The notes here are
farmbuyer@1 4 reminders to myself.
farmbuyer@1 5
farmbuyer@1 6 Library contents:
farmbuyer@1 7 - author_debug
farmbuyer@1 8 Evaluates to true if I'm hacking on something.
farmbuyer@1 9
farmbuyer@1 10 - tableprint(t)
farmbuyer@1 11 A single print() call to the contents of T, including nils; strings are
farmbuyer@1 12 cleaned up with respect to embedded '|'/control chars. If there is a
farmbuyer@1 13 global LIBFARMPRINT function, it is called with the cleaned-up T instead
farmbuyer@1 14 of directly calling print.
farmbuyer@1 15
farmbuyer@1 16 - safeprint(...)
farmbuyer@1 17 Same as tableprint() on the argument list.
farmbuyer@1 18
farmbuyer@1 19 - safeiprint(...)
farmbuyer@1 20 Same as safeprint() but with index numbers inserted. Ex:
farmbuyer@1 21 safeiprint(a,b,c) --> <1>,a,<2>,b,<3>,c
farmbuyer@1 22
farmbuyer@1 23 - CHAT(n)
farmbuyer@1 24 Returns a function suitable for assigning to LIBFARMPRINT, directing all
farmbuyer@1 25 output to builtin chat frame N.
farmbuyer@1 26
farmbuyer@1 27 - t = StaticPopup(t)
farmbuyer@1 28 Fills out "typical" settings inside T, especially if T contains any kind
farmbuyer@1 29 of editbox:
farmbuyer@1 30 + cannot accept an empty editbox
farmbuyer@1 31 + pressing Enter runs OnAccept
farmbuyer@1 32 + editbox grabs keyboard focus
farmbuyer@1 33 + OnAccept runs with editbox's text in dialog.usertext
farmbuyer@1 34 Returns T.
farmbuyer@1 35
farmbuyer@1 36 - nullfunc()
farmbuyer@1 37 Empty placeholder function. Will be less useful if WoW ever moves to Lua 5.2.
farmbuyer@1 38 This is a fascinating and educational place to insert print calls...
farmbuyer@1 39
farmbuyer@1 40 - tabledump(t)/dumptable(t)
farmbuyer@1 41 If author_debug, this runs the builtin /dump command on T. Otherwise nothing.
farmbuyer@1 42
farmbuyer@1 43 - DoOnceNextUpdate(f)
farmbuyer@1 44 Runs F on the next frame refresh cycle. Multiple calls in one cycle will
farmbuyer@1 45 stack LIFO. Calls *while* processing the stack are safe, and will be stacked
farmbuyer@1 46 up for the next cycle.
farmbuyer@6 47
farmbuyer@6 48 - safecall (func, ...)
farmbuyer@6 49 A modified copy of the xpcall wrapper duplicated in every Ace3 file in the
farmbuyer@6 50 whole damn library.
farmbuyer@6 51
farmbuyer@6 52 - new(...), del(t), copy(t), clear()
farmbuyer@6 53 Ditto for table recycling.
farmbuyer@1 54 ]]
farmbuyer@1 55
farmbuyer@6 56 local MAJOR, MINOR = "LibFarmbuyer", 9
farmbuyer@1 57 assert(LibStub,MAJOR.." requires LibStub")
farmbuyer@1 58 local lib = LibStub:NewLibrary(MAJOR, MINOR)
farmbuyer@1 59 if not lib then return end
farmbuyer@1 60
farmbuyer@1 61 _G[MAJOR] = lib
farmbuyer@1 62
farmbuyer@1 63 ----------------------------------------------------------------------
farmbuyer@6 64 --[[
farmbuyer@6 65 Recycling functions yoinked from AceConfigDialog and tweaked
farmbuyer@6 66 ]]
farmbuyer@1 67 local new, del, copy, clear
farmbuyer@6 68 do
farmbuyer@6 69 local pool = setmetatable({},{__mode="k"})
farmbuyer@6 70 function clear()
farmbuyer@6 71 wipe(pool)
farmbuyer@6 72 end
farmbuyer@6 73 function new(...) -- slightly modified variant, takes optional initializers
farmbuyer@6 74 local t = next(pool)
farmbuyer@6 75 if t then
farmbuyer@6 76 pool[t] = nil
farmbuyer@6 77 for i = 1, select('#',...) do
farmbuyer@6 78 t[i] = select(i,...)
farmbuyer@6 79 end
farmbuyer@6 80 return t
farmbuyer@6 81 else
farmbuyer@6 82 return {...}
farmbuyer@6 83 end
farmbuyer@6 84 end
farmbuyer@6 85 function copy(t)
farmbuyer@6 86 local c = new()
farmbuyer@6 87 for k, v in pairs(t) do
farmbuyer@6 88 c[k] = v
farmbuyer@6 89 end
farmbuyer@6 90 return c
farmbuyer@6 91 end
farmbuyer@6 92 function del(t)
farmbuyer@6 93 wipe(t)
farmbuyer@6 94 pool[t] = true
farmbuyer@6 95 end
farmbuyer@6 96 end
farmbuyer@6 97 lib.new, lib.del, lib.copy, lib.clear = new, del, copy, clear
farmbuyer@1 98
farmbuyer@1 99
farmbuyer@1 100 ----------------------------------------------------------------------
farmbuyer@1 101 --[[
farmbuyer@1 102 safeprint
farmbuyer@1 103 ]]
farmbuyer@1 104 local function undocontrol(c)
farmbuyer@1 105 return ("\\%.3d"):format(c:byte())
farmbuyer@1 106 end
farmbuyer@1 107 function lib.CHAT(n)
farmbuyer@1 108 local cf = _G["ChatFrame"..n]
farmbuyer@1 109 return function(t)
farmbuyer@1 110 local msg = table.concat(t,' ', i, tonumber(t.n) or #t)
farmbuyer@1 111 cf:AddMessage(msg)
farmbuyer@1 112 end
farmbuyer@1 113 end
farmbuyer@1 114 function lib.safeprint(...)
farmbuyer@1 115 local args = { n=select('#',...), ... }
farmbuyer@1 116 lib.tableprint(args)
farmbuyer@1 117 end
farmbuyer@1 118 function lib.safeiprint(...)
farmbuyer@1 119 local args = { n=select('#',...), ... }
farmbuyer@1 120 local last = args.n
farmbuyer@1 121 while last > 0 do
farmbuyer@1 122 table.insert (args, last, "<"..last..">")
farmbuyer@1 123 last = last - 1
farmbuyer@1 124 end
farmbuyer@1 125 args.n = 2 * args.n
farmbuyer@1 126 lib.tableprint(args)
farmbuyer@1 127 end
farmbuyer@1 128 function lib.tableprint(t)
farmbuyer@1 129 for i = 1, (tonumber(t.n) or #t) do
farmbuyer@1 130 t[i] = tostring(t[i]):gsub('\124','\124\124')
farmbuyer@1 131 :gsub('(%c)', undocontrol)
farmbuyer@1 132 end
farmbuyer@1 133 if type(_G.LIBFARMPRINT) == 'function' then
farmbuyer@1 134 return _G.LIBFARMPRINT(t)
farmbuyer@1 135 else
farmbuyer@1 136 return print(unpack(t))
farmbuyer@1 137 end
farmbuyer@1 138 end
farmbuyer@1 139
farmbuyer@1 140 -- See below for global versions.
farmbuyer@1 141
farmbuyer@1 142
farmbuyer@1 143 ----------------------------------------------------------------------
farmbuyer@1 144 local StaticPopupDialogs = _G.StaticPopupDialogs
farmbuyer@1 145
farmbuyer@1 146 local function EditBoxOnTextChanged_notempty (editbox) -- this is also called when first shown
farmbuyer@1 147 if editbox:GetText() ~= "" then
farmbuyer@1 148 editbox:GetParent().button1:Enable()
farmbuyer@1 149 else
farmbuyer@1 150 editbox:GetParent().button1:Disable()
farmbuyer@1 151 end
farmbuyer@1 152 end
farmbuyer@1 153 local function EditBoxOnEnterPressed_accept (editbox)
farmbuyer@1 154 local dialog = editbox:GetParent()
farmbuyer@1 155 StaticPopupDialogs[dialog.which].OnAccept (dialog, dialog.data, dialog.data2)
farmbuyer@1 156 dialog:Hide()
farmbuyer@1 157 end
farmbuyer@1 158 local function OnShow_witheditbox (dialog, data)
farmbuyer@1 159 local info = StaticPopupDialogs[dialog.which]
farmbuyer@1 160 dialog[info.hasWideEditBox and "wideEditBox" or "editBox"]:SetFocus()
farmbuyer@1 161 if info.farm_OnShow then
farmbuyer@1 162 return info.farm_OnShow (dialog, data)
farmbuyer@1 163 end
farmbuyer@1 164 end
farmbuyer@1 165 local function OnAccept_witheditbox (dialog, data, data2)
farmbuyer@1 166 local info = StaticPopupDialogs[dialog.which]
farmbuyer@1 167 dialog.usertext = dialog[info.hasWideEditBox and "wideEditBox" or "editBox"]:GetText():trim()
farmbuyer@1 168 if info.farm_OnAccept then
farmbuyer@1 169 return info.farm_OnAccept (dialog, data, data2)
farmbuyer@1 170 end
farmbuyer@1 171 end
farmbuyer@1 172
farmbuyer@1 173 --[[
farmbuyer@1 174 StaticPopup
farmbuyer@1 175 ]]
farmbuyer@1 176 function lib.StaticPopup (t)
farmbuyer@1 177 if t.hasEditBox then
farmbuyer@1 178 t.EditBoxOnTextChanged = EditBoxOnTextChanged_notempty
farmbuyer@1 179 t.EditBoxOnEnterPressed = EditBoxOnEnterPressed_accept
farmbuyer@1 180 if t.OnShow then
farmbuyer@1 181 t.farm_OnShow = t.OnShow
farmbuyer@1 182 end
farmbuyer@1 183 t.OnShow = OnShow_witheditbox
farmbuyer@1 184 if t.OnAccept then
farmbuyer@1 185 t.farm_OnAccept = t.OnAccept
farmbuyer@1 186 end
farmbuyer@1 187 t.OnAccept = OnAccept_witheditbox
farmbuyer@1 188 -- this calls OnCancel with "clicked", unless noCancelOnEscape is set
farmbuyer@1 189 t.EditBoxOnEscapePressed = StaticPopup_EscapePressed
farmbuyer@1 190 end
farmbuyer@1 191
farmbuyer@1 192 t.timeout = 0
farmbuyer@1 193 t.whileDead = true
farmbuyer@1 194 t.hideOnEscape = true
farmbuyer@1 195 t.enterClicksFirstButton = true
farmbuyer@1 196
farmbuyer@1 197 return t
farmbuyer@1 198 end
farmbuyer@1 199
farmbuyer@1 200
farmbuyer@1 201 ----------------------------------------------------------------------
farmbuyer@1 202 --[[
farmbuyer@1 203 This is ugly, but at least it all gets GC'd almost immediately.
farmbuyer@1 204 ]]
farmbuyer@1 205 function lib.nullfunc() end
farmbuyer@1 206
farmbuyer@1 207 if ({
farmbuyer@1 208 ["Bandwagon"] = true, ["Kilvin"] = true, ["Waterfaucet"] = true,
farmbuyer@1 209 ["Farmbuyer"] = true, ["Oxdeadbeef"] = true, ["Pointystick"] = true,
farmbuyer@1 210 ["Angryhobbit"] = true, ["Malrubius"] = true, ["Hemogoblin"] = true,
farmbuyer@1 211 })[UnitName("player")] then
farmbuyer@1 212 lib.author_debug = true
farmbuyer@1 213 _G.safeprint = lib.safeprint
farmbuyer@1 214 _G.safeiprint = lib.safeiprint
farmbuyer@1 215 function lib.tabledump(t)
farmbuyer@1 216 _G.UIParentLoadAddOn("Blizzard_DebugTools")
farmbuyer@1 217 _G.LibF_DEBUG = t
farmbuyer@1 218 _G.SlashCmdList.DUMP("LibF_DEBUG")
farmbuyer@1 219 end
farmbuyer@1 220 else
farmbuyer@1 221 lib.tabledump = lib.nullfunc
farmbuyer@1 222 end
farmbuyer@1 223 lib.dumptable = lib.tabledump
farmbuyer@1 224
farmbuyer@1 225
farmbuyer@1 226 ----------------------------------------------------------------------
farmbuyer@1 227 --[[
farmbuyer@1 228 DoOnceNextUpdate
farmbuyer@1 229 ]]
farmbuyer@1 230 do
farmbuyer@1 231 local frame = CreateFrame("Frame", "LibFarmbuyerDONUFrame")
farmbuyer@1 232 frame:Hide()
farmbuyer@1 233 frame:SetScript("OnUpdate", function()
farmbuyer@1 234 frame:Hide()
farmbuyer@1 235 local q = frame.nexttime
farmbuyer@1 236 local tmp
farmbuyer@1 237 frame.nexttime = nil
farmbuyer@1 238 while q do
farmbuyer@1 239 tmp = q
farmbuyer@1 240 q.f(frame)
farmbuyer@1 241 q = q.n
farmbuyer@1 242 del(tmp)
farmbuyer@1 243 end
farmbuyer@1 244 end)
farmbuyer@1 245
farmbuyer@1 246 function lib.DoOnceNextUpdate (func)
farmbuyer@1 247 local nextt = new()
farmbuyer@1 248 nextt.f = func
farmbuyer@1 249 nextt.n = frame.nexttime
farmbuyer@1 250 frame.nexttime = nextt
farmbuyer@1 251 frame:Show()
farmbuyer@1 252 end
farmbuyer@1 253 end
farmbuyer@1 254
farmbuyer@1 255
farmbuyer@1 256 ----------------------------------------------------------------------
farmbuyer@6 257 --[[
farmbuyer@6 258 safecall
farmbuyer@6 259 ]]
farmbuyer@1 260 do
farmbuyer@6 261 local xpcall = xpcall
farmbuyer@6 262
farmbuyer@6 263 local function errorhandler(err)
farmbuyer@6 264 --return geterrorhandler()(err)
farmbuyer@6 265 --print("in error handler", err)
farmbuyer@6 266 return err
farmbuyer@1 267 end
farmbuyer@6 268
farmbuyer@6 269 local template = ([[
farmbuyer@6 270 local xpcall, eh = ...
farmbuyer@6 271 local method, ARGS
farmbuyer@6 272 local function call() return method(ARGS) end
farmbuyer@6 273
farmbuyer@6 274 local function dispatch (func, ...)
farmbuyer@6 275 method = func
farmbuyer@6 276 if not method then return end
farmbuyer@6 277 ARGS = ...
farmbuyer@6 278 return xpcall (call, eh)
farmbuyer@1 279 end
farmbuyer@6 280
farmbuyer@6 281 return dispatch
farmbuyer@6 282 ]]):gsub('\t',' ')
farmbuyer@6 283
farmbuyer@6 284 local function CreateDispatcher(argCount)
farmbuyer@6 285 local ARGS = {}
farmbuyer@6 286 for i = 1, argCount do ARGS[i] = "arg"..i end
farmbuyer@6 287 local code = template:gsub("ARGS", table.concat(ARGS, ", "))
farmbuyer@6 288 return assert(loadstring(code, "LibF/safecall Dispatcher["..argCount.."]"))(xpcall, errorhandler)
farmbuyer@1 289 end
farmbuyer@6 290
farmbuyer@6 291 local Dispatchers = setmetatable({
farmbuyer@6 292 [0] = function(func)
farmbuyer@6 293 return xpcall (func, errorhandler)
farmbuyer@1 294 end
farmbuyer@6 295 }, {
farmbuyer@6 296 __index = function (Ds, argCount)
farmbuyer@6 297 local dispatcher = CreateDispatcher(argCount)
farmbuyer@6 298 Ds[argCount] = dispatcher
farmbuyer@6 299 return dispatcher
farmbuyer@6 300 end
farmbuyer@6 301 })
farmbuyer@6 302
farmbuyer@6 303 function lib.safecall (func, ...)
farmbuyer@6 304 if type(func) == 'function' then
farmbuyer@6 305 return Dispatchers[select('#', ...)](func, ...)
farmbuyer@6 306 end
farmbuyer@1 307 end
farmbuyer@1 308 end
farmbuyer@1 309
farmbuyer@6 310
farmbuyer@6 311 ----------------------------------------------------------------------
farmbuyer@6 312
farmbuyer@1 313 -- vim: noet