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