Mercurial > wow > buffalo2
diff Veneer.lua @ 47:1a322b92dbfa
file cleanup
author | Nenue |
---|---|
date | Thu, 28 Apr 2016 05:54:21 -0400 |
parents | Init.lua@756e8aeb040b |
children | 9837069e366a |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Veneer.lua Thu Apr 28 05:54:21 2016 -0400 @@ -0,0 +1,569 @@ +--- Modulizer framework +-- OnInitialize +-- OnUpdate +-- OnEnable -- run when GetSpecialization() returns true + +local ADDON, A = ... +Veneer = Veneer or CreateFrame('Frame', 'Veneer', UIParent) +local B = Veneer +local wipe, min, max, random, tinsert, tremove = table.wipe, math.min, math.max, math.random, table.insert, table.remove +local pairs, ipairs, select, unpack, _G = pairs, ipairs, select, unpack, _G +local type, tostring, format = type, tostring, string.format +A.frame = B + +--- Cache tables +local initOnced +local modules = {} +local queuedModules = {} +local checkForConfig = {} +local moduleStack = { +} + +--- Utilities +B.wipeall = function (...) + for i = 1, select('#', ...) do + wipe(select(i, ...)) + end +end + +--- Various region categories +B.displays = {} +B.configLayers = {} +B.configLayersRef = {} + + +--@debug@ +--- Generates a print handler pointing to a static channel signature +-- @usage func = B.print(sig) +-- @param sig channel name or number +local printfuncs = {} +B.print = function(pref, ...) + if Devian and Devian.InWorkspace() then + printfuncs[pref] = printfuncs[pref] or function(...) print(pref, ...) end + + return printfuncs[pref] + else + return function () end + end +end + +local rgb = {} +local getcolor = function() + local n, p = 0, 4 + for i = 1, 3 do + rgb[i] = min(random(n,p) * 64, 255) + if rgb[i] == 255 then + p = 4 + elseif rgb[i] > 0 then + n = 2 + end + end + return unpack(rgb) +end + +local color = {} +local fprints = {} +B.fprint = function() + if not (Devian and Devian.InWorkspace()) then + return function() end + end + + + local sig = debugstack(2,1) + if fprints[sig] then + return fprints[sig] + end + + local func = sig:match("%`(%a+)%'") + if not func then + func = sig:match("<(.-)>") + end + func = func:gsub('(%l+)(%u)', function(a, b) return a:sub(0,2) .. b end, 1) + func = func:gsub('^.+%\\', '') + if not func then + func = 'noname' + end + + local r, g, b = getcolor() + color[sig] = color[sig] or format('|cFF%02X%02X%02X%s|r', r, g, b, func) + + --print(color[func] .. ' ( ' .. table.concat(args, ', ')..' )' ) + func = B.print(func) + fprints[sig] = func + return func +end + +--@end-debug@ +--[=[@non-debug@ +B.print = function() end +--@end-non-debug@]=] + +-- for the Mikk script +-- GLOBALS: NUM_LE_RAID_BUFF_TYPES +-- GLOBALS: BUFF_FLASH_TIME_ON, BUFF_FLASH_TIME_OFF, BUFF_MIN_ALPHA, BUFF_WARNING_TIME, BUFF_DURATION_WARNING_TIME +-- GLOBALS: BUFFS_PER_ROW, BUFF_MAX_DISPLAY, BUFF_ACTUAL_DISPLAY, DEBUFF_MAX_DISPLAY, DEBUFF_ACTUAL_DISPLAY, BUFF_ROW_SPACING +-- GLOBALS: CONSOLIDATED_BUFFS_PER_ROW, CONSOLIDATED_BUFF_ROW_HEIGHT, NUM_TEMP_ENCHANT_FRAMES +-- GLOBALS: BUFF_BUTTON_HEIGHT, BUFF_FRAME_BASE_EXTENT, BUFF_HORIZ_SPACING + +local print = B.print('Bfl') + +--- Template for making perpendicular traversals of the displays structure; also makes sure the table is there +B.Abstract = function(dest, key, table) + if table then + for _, v in pairs(dest) do + v[key] = {} + end + end + B[key] = setmetatable({}, { + __index = function(t, k) + return dest[k][key] + end, + __newindex = function(_, k, v) + print('abstract write ('..key..'):', k) + dest[k][key] = v + end, + __tostring = function() return 'Abstract:'..key..'' end + }) + + + return B[key] +end + + +--- localize for speed +local layers, refs, displays = B.configLayers, B.configLayersRef, B.displays + +local ModulesCall = function(func, flag) + + local n = 0 + for i = 1, #moduleStack do + print('calling level '..i) + local stackset = moduleStack[i] + + for name, module in pairs(stackset) do + n = n + 1 + + + if module[func] then + -- nil = pass + if not flag or module.Conf[flag] then + if (flag) then + print(' check', flag, '=', module.Conf[flag]) + end + + print(' ',n..' '..name..'.'..func..'()') + module[func](module, module.Conf) + end + + end + end + end +end + + +local Enable = function() +end + +--- The things that happen repeatedly +local Init = function () +end + + +--- Things that happen immediately upon entering world +local InitOnce = function() + print('entering world first time') + local defaults = B.ConfDefaults + print('|cFFFFFF00Veneer|r') + if not VeneerData then + VeneerData = {} + for k,v in pairs(defaults) do + + + VeneerData[k] = v + end + print('Veneer defaults being used.') + end + + B.Conf = setmetatable(VeneerData, {__index = function(_, k) return defaults[k] end}) + + + + -- suffix tables + for name, display in pairs(displays) do + display.conf = setmetatable({}, { + __index = function(_, k) + --print('config check '.. name .. k) + return B.Conf[name .. k] or B.Conf['BuffButton' .. k] + end, + __newindex = function(_, k , v) + B.Conf[name..k] = v + end, + }) + end + + -- To ensure that modules are run in controlled order, walk the dependency list; if the dep shows up + -- in the loaded manifest, remove the value. If the dep list isn't empty, move that module to the next + -- layer. + local loaded = {} + local stackLevels = #moduleStack + local i = 1 + moduleStack[1] = modules + repeat + print('setting init level '.. i) + local queue = moduleStack[i] + for name, module in pairs(queue) do + + if queuedModules[name] and #queuedModules[name] > 0 then + local p = #queuedModules[name] + for j = 1, p do + local dep = queuedModules[name][j] + + if loaded[dep] then + print( ' ' .. dep .. ' OK') + queuedModules[name][j] = nil + for k = j, p do + print(' shift ' .. (k+1) .. ' ('..tostring(queuedModules[name][k+1])..') to ' .. k ..'') + queuedModules[name][k] = queuedModules[name][k+1] + end + end + end + + if #queuedModules[name] == 0 then + queuedModules[name] = nil + print(' |cFF00FFFF'.. name ..'|r deps OK') + loaded[name] = true + else + + print(' |cFFFF8800' .. name ..'|r pending') + local next = i+1 + if not moduleStack[next] then + moduleStack[next] = {} + end + stackLevels = next + moduleStack[next][name] = module + queue[name] = nil + end + + else + print(' |cFF00FF00'.. name ..'|r no deps') + loaded[name] = true + end + end + i = i + 1 + until i > stackLevels + + + for level, batch in ipairs(moduleStack) do + print('config level', level) + for name, module in pairs(batch) do + if not VeneerData[name] then + VeneerData[name] = {} + end + + if module.defaults then + print('setting defaults for module', name) + --[===[@non-debug@ + if not VeneerData[name] then + --@end-non-debug@]===] + VeneerData[name] = {} + --[===[@non-debug@ + end + --@end-non-debug@]===] + for k,v in pairs(module.defaults) do + VeneerData[name][k] = v + end + module.Conf = VeneerData[name] + end + + if VeneerData[name].enabled == nil then + VeneerData[name].enabled = true + end + + end + end + + + if #checkForConfig >= 1 then + local queuedFrame = tremove(checkForConfig) + while queuedFrame do + B.SetConfigLayers(queuedFrame) + B.UpdateXMLFrame(queuedFrame) + queuedFrame = tremove(checkForConfig) + end + end + -- remove from existing +end + +--- Fires an update to all modules +local lastUpdate +function B.UpdateAll(...) + lastUpdate = GetTime() + ModulesCall('OnUpdate') +end + +B:RegisterEvent('PLAYER_ENTERING_WORLD') +B:SetScript('OnEvent', function(self, event) + if event == 'PLAYER_ENTERING_WORLD' then + if not initOnced then + InitOnce() + ModulesCall('OnInitialize') + initOnced = true + C_Timer.After(1, function() + if GetSpecialization() then + print(GetSpecialization(), 'enabling') + + ModulesCall('OnEnable', 'enabled') + B:SetScript('OnUpdate', nil) + end + end) + end + end + + B.UpdateAll() + + if event == 'PLAYER_ENTERING_WORLD' then + B.UpdateConfigLayers() + end + +end) + +--- Modulizer method +-- +function B:RegisterModule (name, module, ...) + if modules[name] then + print('pulling modules[|cFFFF8800'.. tostring(name) ..'|r]') + return modules[name] + end + + print('new module |cFF00BBFF'.. tostring(name) ..'|r') + if module then + if modules[name] then + error("Module table for '"..tostring(name).."' already exists.") + end + else + module = CreateFrame('Frame', 'Veneer' .. tostring(name) .. 'Handler', B, 'VeneerHandlerTemplate') + end + modules[name] = module + B[name] = module + if select('#', ...) >= 1 then + local numDeps = select('#', ...) + print(' '..numDeps..' deps detected') + for i = 1, numDeps do + local dep = select(i, ...) + -- means that init/enable funcs are ordered to run after deps do their things + queuedModules[name] = queuedModules[name] or {} + tinsert(queuedModules[name], dep) + print(' needs '..dep) + end + end + return module +end + + +B.SetConfigLayers = function(frame) + local print = B.fprint() + if not frame.config then + --print(frame:GetName(), 'has no config layers') + return + end + --print('Registering config layers from', frame:GetName()) + + for i, subframe in ipairs(frame.config) do + -- make sure there are no duplicates + if not refs[subframe] then + local key = #layers+1 + layers[key] = subframe + refs[subframe] = key + end + --print(' ', i, subframe:GetName()) + end +end + +B.RemoveConfigLayers = function(frame) + + local print = B.fprint() + print('|cFFFF0000RemoveConfigLayers', frame:GetName()) + for i, subframe in pairs(layers) do + if subframe:GetParent() == frame then + print('|cFFFF8800 ', subframe:GetParent():GetName(), '|cFFFFFF00', subframe:GetName()) + layers[i]:Hide() + layers[i] = nil + refs[subframe] = nil + end + end +end + +B.UpdateConfigLayers = function() + local print = B.fprint() + local func = B.Conf.GuidesMode and 'Show' or 'Hide' + local numAnchors = 0 + for name, display in pairs(displays) do + numAnchors = numAnchors + 1 + display.anchor:EnableMouse(B.Conf.GuidesMode) + if B.Conf.GuidesMode then + display.anchor:SetScript('OnUpdate', display.anchor.OnUpdate) + else + display.anchor:SetScript('OnUpdate', nil) + + for i, anchorButton in ipairs(display.anchor.anchorButton) do + anchorButton:Hide() + end + + end + --print(B.Conf.ConfigMode) + display.anchor:EnableMouse(B.Conf.ConfigMode) + end + for id, region in pairs(layers) do + --print(id, region:GetName(), func) + region[func](region) + end + + --print('['..func..'] updated', #layers, 'regions,', numAnchors, 'frames') +end + +local XMLFrame_Enable = function(self, value) + local name = self:GetName() + local print = B.print('XML') + + if not B.Conf[name] then + B.Conf[name] = { + enabled = true + } + end + + print() + local enabled + if value == nil then + if B.Conf[name].enabled == nil then + print('toggle based on visibility') + enabled = (not self:IsVisible()) and true or false + else + print('toggle a config value =', B.Conf[name].enabled) + enabled = B.Conf[name].enabled + end + + enabled = (enabled ~= true) and true or false + else + print('use argument value', value) + enabled = value + end + + print('arg =', value, 'conf =', B.Conf[name].enabled, 'result=', enabled) + + B.Conf[name].enabled = enabled + + local stateFunc = enabled and 'Show' or 'Hide' + local eventFunc = enabled and 'OnToggle' or 'OnToggle' + --- taggled layers + if self.toggled then + for i, region in pairs(self.toggled) do + region[stateFunc](region) + end + end + --- toggle action + if self.OnToggle then + self:OnToggle(B.Conf[name].enabled) + end + --- do enable + if B.Conf[name].enabled then + if self.OnEnable then + self:OnEnable() + end + else + if self.OnDisable then + self:OnDisable() + end + end +end +--- Generic handlers for keeping track of XML-defined frames +local print = B.print('XML') +B.prototypes = {} +B.prototypes.OnDragStart = function(self) + local print = B.print('XML') + self.xA = self:GetLeft() + self.yA = self:GetBottom() + self.anchorTo, self.relativeTo, self.relativePoint, self.x, self.y = self:GetPoint(1) + print('acquire anchor', self:GetPoint(1)) + print(self:GetName(), 'start moving ('..self.x..', '..self.y..')') + self:StartMoving() +end + +B.prototypes.OnDragStop = function(self) + local print = B.print('XML') + local name = self:GetName() + print(name, 'stop moving ('..self:GetLeft()..', '..self:GetBottom()..')') + local xB = self:GetLeft() - self.xA + local yB = self:GetBottom() - self.yA + print('storing anchor point', self.anchorTo, self.relativePoint, self.x + xB, self.y + yB) + + self:StopMovingOrSizing() + B.Conf[name].position = {self.anchorTo, self.relativePoint, self.x + xB, self.y + yB} + B.UpdateXMLFrame(self) +end + + +B.RegisterModuleFrame = function(self, moduleName) + local print = B.print('XML') + local name = self:GetName() + tinsert(checkForConfig, self) + self.Enable = XMLFrame_Enable + self.moduleName = moduleName + print('|cFF00FF00XML stuff related to '.. tostring(moduleName) .. ':', self:GetName()) + ------------------------------------------------------------------------------------------ + if not B[name] then + return + end + + local scriptTypes = {'OnUpdate', 'OnEvent', 'OnDragStart', 'OnDragStop'} + for script in next(scriptTypes) do + if B[name][script] then + self:SetScript(script, B[name][script]) + end + end + +end + +B.UpdateXMLFrame = function(self) + local print = B.print('XML') + + local name = self:GetName() + + + if self.drag then + self:RegisterForDrag('LeftButton') + self:SetScript('OnDragStart', XMLFrame_OnDragStart) + if self.OnDragStop then + self:SetScript('OnDragStop', function(self, ...) + print('|cFFFF0088end of dragging') + self:OnDragStop(self, ...) + XMLFrame_OnDragStop(self, ...) + end) + else + self:SetScript('OnDragStop', XMLFrame_OnDragStop) + end + else + self:EnableMouse(false) + end + + if not B.Conf[name] then + B.Conf[name] = { + enabled = self.enabled, + } + end + local c = B.Conf[name] + + if not c.position then + local anchor, _, point, x, y = self:GetPoint(1) + print('seeding default position', anchor, point, x, y) + c.position = {anchor, point, x, y} + else + + print('restoring frame position', unpack(c.position)) + self:ClearAllPoints() + local anchorTo, relativePoint, x, y = unpack(c.position) + self:SetPoint(anchorTo, UIParent, relativePoint, x, y) + end + self:Enable(c.enabled) + + +end