annotate LibFarmbuyer.lua @ 51:857aea8ae33d

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