comparison Veneer.lua @ 47:1a322b92dbfa

file cleanup
author Nenue
date Thu, 28 Apr 2016 05:54:21 -0400
parents Init.lua@756e8aeb040b
children 9837069e366a
comparison
equal deleted inserted replaced
46:aa693607b813 47:1a322b92dbfa
1 --- Modulizer framework
2 -- OnInitialize
3 -- OnUpdate
4 -- OnEnable -- run when GetSpecialization() returns true
5
6 local ADDON, A = ...
7 Veneer = Veneer or CreateFrame('Frame', 'Veneer', UIParent)
8 local B = Veneer
9 local wipe, min, max, random, tinsert, tremove = table.wipe, math.min, math.max, math.random, table.insert, table.remove
10 local pairs, ipairs, select, unpack, _G = pairs, ipairs, select, unpack, _G
11 local type, tostring, format = type, tostring, string.format
12 A.frame = B
13
14 --- Cache tables
15 local initOnced
16 local modules = {}
17 local queuedModules = {}
18 local checkForConfig = {}
19 local moduleStack = {
20 }
21
22 --- Utilities
23 B.wipeall = function (...)
24 for i = 1, select('#', ...) do
25 wipe(select(i, ...))
26 end
27 end
28
29 --- Various region categories
30 B.displays = {}
31 B.configLayers = {}
32 B.configLayersRef = {}
33
34
35 --@debug@
36 --- Generates a print handler pointing to a static channel signature
37 -- @usage func = B.print(sig)
38 -- @param sig channel name or number
39 local printfuncs = {}
40 B.print = function(pref, ...)
41 if Devian and Devian.InWorkspace() then
42 printfuncs[pref] = printfuncs[pref] or function(...) print(pref, ...) end
43
44 return printfuncs[pref]
45 else
46 return function () end
47 end
48 end
49
50 local rgb = {}
51 local getcolor = function()
52 local n, p = 0, 4
53 for i = 1, 3 do
54 rgb[i] = min(random(n,p) * 64, 255)
55 if rgb[i] == 255 then
56 p = 4
57 elseif rgb[i] > 0 then
58 n = 2
59 end
60 end
61 return unpack(rgb)
62 end
63
64 local color = {}
65 local fprints = {}
66 B.fprint = function()
67 if not (Devian and Devian.InWorkspace()) then
68 return function() end
69 end
70
71
72 local sig = debugstack(2,1)
73 if fprints[sig] then
74 return fprints[sig]
75 end
76
77 local func = sig:match("%`(%a+)%'")
78 if not func then
79 func = sig:match("<(.-)>")
80 end
81 func = func:gsub('(%l+)(%u)', function(a, b) return a:sub(0,2) .. b end, 1)
82 func = func:gsub('^.+%\\', '')
83 if not func then
84 func = 'noname'
85 end
86
87 local r, g, b = getcolor()
88 color[sig] = color[sig] or format('|cFF%02X%02X%02X%s|r', r, g, b, func)
89
90 --print(color[func] .. ' ( ' .. table.concat(args, ', ')..' )' )
91 func = B.print(func)
92 fprints[sig] = func
93 return func
94 end
95
96 --@end-debug@
97 --[=[@non-debug@
98 B.print = function() end
99 --@end-non-debug@]=]
100
101 -- for the Mikk script
102 -- GLOBALS: NUM_LE_RAID_BUFF_TYPES
103 -- GLOBALS: BUFF_FLASH_TIME_ON, BUFF_FLASH_TIME_OFF, BUFF_MIN_ALPHA, BUFF_WARNING_TIME, BUFF_DURATION_WARNING_TIME
104 -- GLOBALS: BUFFS_PER_ROW, BUFF_MAX_DISPLAY, BUFF_ACTUAL_DISPLAY, DEBUFF_MAX_DISPLAY, DEBUFF_ACTUAL_DISPLAY, BUFF_ROW_SPACING
105 -- GLOBALS: CONSOLIDATED_BUFFS_PER_ROW, CONSOLIDATED_BUFF_ROW_HEIGHT, NUM_TEMP_ENCHANT_FRAMES
106 -- GLOBALS: BUFF_BUTTON_HEIGHT, BUFF_FRAME_BASE_EXTENT, BUFF_HORIZ_SPACING
107
108 local print = B.print('Bfl')
109
110 --- Template for making perpendicular traversals of the displays structure; also makes sure the table is there
111 B.Abstract = function(dest, key, table)
112 if table then
113 for _, v in pairs(dest) do
114 v[key] = {}
115 end
116 end
117 B[key] = setmetatable({}, {
118 __index = function(t, k)
119 return dest[k][key]
120 end,
121 __newindex = function(_, k, v)
122 print('abstract write ('..key..'):', k)
123 dest[k][key] = v
124 end,
125 __tostring = function() return 'Abstract:'..key..'' end
126 })
127
128
129 return B[key]
130 end
131
132
133 --- localize for speed
134 local layers, refs, displays = B.configLayers, B.configLayersRef, B.displays
135
136 local ModulesCall = function(func, flag)
137
138 local n = 0
139 for i = 1, #moduleStack do
140 print('calling level '..i)
141 local stackset = moduleStack[i]
142
143 for name, module in pairs(stackset) do
144 n = n + 1
145
146
147 if module[func] then
148 -- nil = pass
149 if not flag or module.Conf[flag] then
150 if (flag) then
151 print(' check', flag, '=', module.Conf[flag])
152 end
153
154 print(' ',n..' '..name..'.'..func..'()')
155 module[func](module, module.Conf)
156 end
157
158 end
159 end
160 end
161 end
162
163
164 local Enable = function()
165 end
166
167 --- The things that happen repeatedly
168 local Init = function ()
169 end
170
171
172 --- Things that happen immediately upon entering world
173 local InitOnce = function()
174 print('entering world first time')
175 local defaults = B.ConfDefaults
176 print('|cFFFFFF00Veneer|r')
177 if not VeneerData then
178 VeneerData = {}
179 for k,v in pairs(defaults) do
180
181
182 VeneerData[k] = v
183 end
184 print('Veneer defaults being used.')
185 end
186
187 B.Conf = setmetatable(VeneerData, {__index = function(_, k) return defaults[k] end})
188
189
190
191 -- suffix tables
192 for name, display in pairs(displays) do
193 display.conf = setmetatable({}, {
194 __index = function(_, k)
195 --print('config check '.. name .. k)
196 return B.Conf[name .. k] or B.Conf['BuffButton' .. k]
197 end,
198 __newindex = function(_, k , v)
199 B.Conf[name..k] = v
200 end,
201 })
202 end
203
204 -- To ensure that modules are run in controlled order, walk the dependency list; if the dep shows up
205 -- in the loaded manifest, remove the value. If the dep list isn't empty, move that module to the next
206 -- layer.
207 local loaded = {}
208 local stackLevels = #moduleStack
209 local i = 1
210 moduleStack[1] = modules
211 repeat
212 print('setting init level '.. i)
213 local queue = moduleStack[i]
214 for name, module in pairs(queue) do
215
216 if queuedModules[name] and #queuedModules[name] > 0 then
217 local p = #queuedModules[name]
218 for j = 1, p do
219 local dep = queuedModules[name][j]
220
221 if loaded[dep] then
222 print( ' ' .. dep .. ' OK')
223 queuedModules[name][j] = nil
224 for k = j, p do
225 print(' shift ' .. (k+1) .. ' ('..tostring(queuedModules[name][k+1])..') to ' .. k ..'')
226 queuedModules[name][k] = queuedModules[name][k+1]
227 end
228 end
229 end
230
231 if #queuedModules[name] == 0 then
232 queuedModules[name] = nil
233 print(' |cFF00FFFF'.. name ..'|r deps OK')
234 loaded[name] = true
235 else
236
237 print(' |cFFFF8800' .. name ..'|r pending')
238 local next = i+1
239 if not moduleStack[next] then
240 moduleStack[next] = {}
241 end
242 stackLevels = next
243 moduleStack[next][name] = module
244 queue[name] = nil
245 end
246
247 else
248 print(' |cFF00FF00'.. name ..'|r no deps')
249 loaded[name] = true
250 end
251 end
252 i = i + 1
253 until i > stackLevels
254
255
256 for level, batch in ipairs(moduleStack) do
257 print('config level', level)
258 for name, module in pairs(batch) do
259 if not VeneerData[name] then
260 VeneerData[name] = {}
261 end
262
263 if module.defaults then
264 print('setting defaults for module', name)
265 --[===[@non-debug@
266 if not VeneerData[name] then
267 --@end-non-debug@]===]
268 VeneerData[name] = {}
269 --[===[@non-debug@
270 end
271 --@end-non-debug@]===]
272 for k,v in pairs(module.defaults) do
273 VeneerData[name][k] = v
274 end
275 module.Conf = VeneerData[name]
276 end
277
278 if VeneerData[name].enabled == nil then
279 VeneerData[name].enabled = true
280 end
281
282 end
283 end
284
285
286 if #checkForConfig >= 1 then
287 local queuedFrame = tremove(checkForConfig)
288 while queuedFrame do
289 B.SetConfigLayers(queuedFrame)
290 B.UpdateXMLFrame(queuedFrame)
291 queuedFrame = tremove(checkForConfig)
292 end
293 end
294 -- remove from existing
295 end
296
297 --- Fires an update to all modules
298 local lastUpdate
299 function B.UpdateAll(...)
300 lastUpdate = GetTime()
301 ModulesCall('OnUpdate')
302 end
303
304 B:RegisterEvent('PLAYER_ENTERING_WORLD')
305 B:SetScript('OnEvent', function(self, event)
306 if event == 'PLAYER_ENTERING_WORLD' then
307 if not initOnced then
308 InitOnce()
309 ModulesCall('OnInitialize')
310 initOnced = true
311 C_Timer.After(1, function()
312 if GetSpecialization() then
313 print(GetSpecialization(), 'enabling')
314
315 ModulesCall('OnEnable', 'enabled')
316 B:SetScript('OnUpdate', nil)
317 end
318 end)
319 end
320 end
321
322 B.UpdateAll()
323
324 if event == 'PLAYER_ENTERING_WORLD' then
325 B.UpdateConfigLayers()
326 end
327
328 end)
329
330 --- Modulizer method
331 --
332 function B:RegisterModule (name, module, ...)
333 if modules[name] then
334 print('pulling modules[|cFFFF8800'.. tostring(name) ..'|r]')
335 return modules[name]
336 end
337
338 print('new module |cFF00BBFF'.. tostring(name) ..'|r')
339 if module then
340 if modules[name] then
341 error("Module table for '"..tostring(name).."' already exists.")
342 end
343 else
344 module = CreateFrame('Frame', 'Veneer' .. tostring(name) .. 'Handler', B, 'VeneerHandlerTemplate')
345 end
346 modules[name] = module
347 B[name] = module
348 if select('#', ...) >= 1 then
349 local numDeps = select('#', ...)
350 print(' '..numDeps..' deps detected')
351 for i = 1, numDeps do
352 local dep = select(i, ...)
353 -- means that init/enable funcs are ordered to run after deps do their things
354 queuedModules[name] = queuedModules[name] or {}
355 tinsert(queuedModules[name], dep)
356 print(' needs '..dep)
357 end
358 end
359 return module
360 end
361
362
363 B.SetConfigLayers = function(frame)
364 local print = B.fprint()
365 if not frame.config then
366 --print(frame:GetName(), 'has no config layers')
367 return
368 end
369 --print('Registering config layers from', frame:GetName())
370
371 for i, subframe in ipairs(frame.config) do
372 -- make sure there are no duplicates
373 if not refs[subframe] then
374 local key = #layers+1
375 layers[key] = subframe
376 refs[subframe] = key
377 end
378 --print(' ', i, subframe:GetName())
379 end
380 end
381
382 B.RemoveConfigLayers = function(frame)
383
384 local print = B.fprint()
385 print('|cFFFF0000RemoveConfigLayers', frame:GetName())
386 for i, subframe in pairs(layers) do
387 if subframe:GetParent() == frame then
388 print('|cFFFF8800 ', subframe:GetParent():GetName(), '|cFFFFFF00', subframe:GetName())
389 layers[i]:Hide()
390 layers[i] = nil
391 refs[subframe] = nil
392 end
393 end
394 end
395
396 B.UpdateConfigLayers = function()
397 local print = B.fprint()
398 local func = B.Conf.GuidesMode and 'Show' or 'Hide'
399 local numAnchors = 0
400 for name, display in pairs(displays) do
401 numAnchors = numAnchors + 1
402 display.anchor:EnableMouse(B.Conf.GuidesMode)
403 if B.Conf.GuidesMode then
404 display.anchor:SetScript('OnUpdate', display.anchor.OnUpdate)
405 else
406 display.anchor:SetScript('OnUpdate', nil)
407
408 for i, anchorButton in ipairs(display.anchor.anchorButton) do
409 anchorButton:Hide()
410 end
411
412 end
413 --print(B.Conf.ConfigMode)
414 display.anchor:EnableMouse(B.Conf.ConfigMode)
415 end
416 for id, region in pairs(layers) do
417 --print(id, region:GetName(), func)
418 region[func](region)
419 end
420
421 --print('['..func..'] updated', #layers, 'regions,', numAnchors, 'frames')
422 end
423
424 local XMLFrame_Enable = function(self, value)
425 local name = self:GetName()
426 local print = B.print('XML')
427
428 if not B.Conf[name] then
429 B.Conf[name] = {
430 enabled = true
431 }
432 end
433
434 print()
435 local enabled
436 if value == nil then
437 if B.Conf[name].enabled == nil then
438 print('toggle based on visibility')
439 enabled = (not self:IsVisible()) and true or false
440 else
441 print('toggle a config value =', B.Conf[name].enabled)
442 enabled = B.Conf[name].enabled
443 end
444
445 enabled = (enabled ~= true) and true or false
446 else
447 print('use argument value', value)
448 enabled = value
449 end
450
451 print('arg =', value, 'conf =', B.Conf[name].enabled, 'result=', enabled)
452
453 B.Conf[name].enabled = enabled
454
455 local stateFunc = enabled and 'Show' or 'Hide'
456 local eventFunc = enabled and 'OnToggle' or 'OnToggle'
457 --- taggled layers
458 if self.toggled then
459 for i, region in pairs(self.toggled) do
460 region[stateFunc](region)
461 end
462 end
463 --- toggle action
464 if self.OnToggle then
465 self:OnToggle(B.Conf[name].enabled)
466 end
467 --- do enable
468 if B.Conf[name].enabled then
469 if self.OnEnable then
470 self:OnEnable()
471 end
472 else
473 if self.OnDisable then
474 self:OnDisable()
475 end
476 end
477 end
478 --- Generic handlers for keeping track of XML-defined frames
479 local print = B.print('XML')
480 B.prototypes = {}
481 B.prototypes.OnDragStart = function(self)
482 local print = B.print('XML')
483 self.xA = self:GetLeft()
484 self.yA = self:GetBottom()
485 self.anchorTo, self.relativeTo, self.relativePoint, self.x, self.y = self:GetPoint(1)
486 print('acquire anchor', self:GetPoint(1))
487 print(self:GetName(), 'start moving ('..self.x..', '..self.y..')')
488 self:StartMoving()
489 end
490
491 B.prototypes.OnDragStop = function(self)
492 local print = B.print('XML')
493 local name = self:GetName()
494 print(name, 'stop moving ('..self:GetLeft()..', '..self:GetBottom()..')')
495 local xB = self:GetLeft() - self.xA
496 local yB = self:GetBottom() - self.yA
497 print('storing anchor point', self.anchorTo, self.relativePoint, self.x + xB, self.y + yB)
498
499 self:StopMovingOrSizing()
500 B.Conf[name].position = {self.anchorTo, self.relativePoint, self.x + xB, self.y + yB}
501 B.UpdateXMLFrame(self)
502 end
503
504
505 B.RegisterModuleFrame = function(self, moduleName)
506 local print = B.print('XML')
507 local name = self:GetName()
508 tinsert(checkForConfig, self)
509 self.Enable = XMLFrame_Enable
510 self.moduleName = moduleName
511 print('|cFF00FF00XML stuff related to '.. tostring(moduleName) .. ':', self:GetName())
512 ------------------------------------------------------------------------------------------
513 if not B[name] then
514 return
515 end
516
517 local scriptTypes = {'OnUpdate', 'OnEvent', 'OnDragStart', 'OnDragStop'}
518 for script in next(scriptTypes) do
519 if B[name][script] then
520 self:SetScript(script, B[name][script])
521 end
522 end
523
524 end
525
526 B.UpdateXMLFrame = function(self)
527 local print = B.print('XML')
528
529 local name = self:GetName()
530
531
532 if self.drag then
533 self:RegisterForDrag('LeftButton')
534 self:SetScript('OnDragStart', XMLFrame_OnDragStart)
535 if self.OnDragStop then
536 self:SetScript('OnDragStop', function(self, ...)
537 print('|cFFFF0088end of dragging')
538 self:OnDragStop(self, ...)
539 XMLFrame_OnDragStop(self, ...)
540 end)
541 else
542 self:SetScript('OnDragStop', XMLFrame_OnDragStop)
543 end
544 else
545 self:EnableMouse(false)
546 end
547
548 if not B.Conf[name] then
549 B.Conf[name] = {
550 enabled = self.enabled,
551 }
552 end
553 local c = B.Conf[name]
554
555 if not c.position then
556 local anchor, _, point, x, y = self:GetPoint(1)
557 print('seeding default position', anchor, point, x, y)
558 c.position = {anchor, point, x, y}
559 else
560
561 print('restoring frame position', unpack(c.position))
562 self:ClearAllPoints()
563 local anchorTo, relativePoint, x, y = unpack(c.position)
564 self:SetPoint(anchorTo, UIParent, relativePoint, x, y)
565 end
566 self:Enable(c.enabled)
567
568
569 end