Mercurial > wow > buffalo2
diff ObjectiveFrame.lua @ 19:605e8f0e46db
ObjectiveCore / Style / Events / Frame
- polishing the execution path for better performance
- make use of the Blizzard_ObjectiveTracker bitfield values to ensure compatibility in possible secure hooks
- avoid full updates when possible (using said bitfield values to indicate targeted sections)
- extreme streamlining of event handling layout: specific reason updates are invoked from API hooks; broader updates are invoked by when the event listener catches something vague like 'QUEST_LOG_UPDATE'
author | Nenue |
---|---|
date | Wed, 06 Apr 2016 07:38:35 -0400 |
parents | d1812fb10ae6 |
children | d5ee940de273 |
line wrap: on
line diff
--- a/ObjectiveFrame.lua Tue Apr 05 02:38:01 2016 -0400 +++ b/ObjectiveFrame.lua Wed Apr 06 07:38:35 2016 -0400 @@ -8,10 +8,11 @@ local ipairs, max, min, unpack, floor, pairs, tostring, type, band = ipairs, max, min, unpack, floor, pairs, tostring, type, bit.band local IsResting, UnitXP, UnitXPMax, GetXPExhaustion = IsResting, UnitXP, UnitXPMax, GetXPExhaustion local UnitLevel, IsQuestWatched, UIParent = UnitLevel, IsQuestWatched, UIParent -local Quest, Bonus, Cheevs = mod.Quest, mod.Bonus, mod.Cheevs +local DefaultTracker, Quest, Bonus, Cheevs = mod.DefaultTracker, mod.Quest, mod.Bonus, mod.Cheevs local CreateFrame = CreateFrame -local print = B.print('Objectives') +local print = B.print('ObjWrapper') local unitLevel = 1 +local OBJECTIVE_TRACKER_UPDATE_REASON = OBJECTIVE_TRACKER_UPDATE_REASON -------------------------------------------------------------------- --- Global frame layout -------------------------------------------------------------------- @@ -41,138 +42,119 @@ local headerOutline, headerColor, headerSpacing = 'OUTLINE', {1,1,1,1}, 2 local wrapperPosition = {'RIGHT', UIParent, 'RIGHT', -84, 0} -mod.InitializeWrapper = function() +local band = bit.band +local currentPosition, anchorFrame, anchorPoint +function mod:Update (reason, dataID) + local updateWrapper = 0 + local hasStuff + local insertingStuff + reason = reason or OBJECTIVE_TRACKER_UPDATE_REASON + currentPosition = 0 + anchorPoint = 'TOPLEFT' + anchorFrame = Scroll - mod.SetBlockStyle(Scroller, 'Scroller', 'Normal') - mod.SetBlockStyle(Scroller, 'Scroll', 'Normal') - mod.SetBlockStyle(Wrapper, 'Wrapper', 'Normal') + local wrapperHeight = 0 + for id, handler in pairs(mod.orderedHandlers) do + local frame = handler.frame - for i, name in ipairs(orderedNames) do - if not mod.orderedHandlers[i] then - if mod.Tracker(name, i) then - local handler = mod[name] - local tracker = CreateFrame('Frame', 'Veneer'..name..'Tracker', Scroll, 'VeneerTrackerTemplate') - tracker.title:SetText(handler.displayName) - mod.SetBlockStyle(tracker, 'Tracker', 'Normal') - handler.Tracker = tracker - mod.orderedTrackers[i] = tracker - mod.namedTrackers[name] = tracker - mod.indexedTrackers[handler] = tracker - print('created new tracker frames for new handler') - end + print(format('|cFF00FFFFbitcheck (%04X vs %04x+%04x):|r', reason, handler.updateReasonModule, handler.updateReasonEvents), band(reason, handler.updateReasonModule + handler.updateReasonEvents)) + if band(reason, handler.updateReasonModule + handler.updateReasonEvents) > 0 then + handler:Update(reason, dataID) + print('|cFF00FF00'..id..'|r', handler.displayName, 'count:', handler.numWatched) + insertingStuff = true + else + print('|cFFFF0088'..id..'|r', 'no reason') + end + + if handler.numWatched >= 1 then + hasStuff = true + currentPosition = currentPosition + 1 + frame:SetParent(Scroll) + frame:SetPoint('TOPLEFT', anchorFrame, anchorPoint, 0, 0) + print(' |cFF00BBFFpinning to', anchorFrame:GetName(), anchorPoint) + anchorFrame = handler.frame + anchorPoint = 'BOTTOMLEFT' + + print('current frame height:', frame.height) + wrapperHeight = wrapperHeight + frame.height + print('|cFFFF0088total height:', wrapperHeight) + else + handler.frame:Hide() end end - Scroller:SetScrollChild(Scroll) - mod.InitializeWrapperWidgets() - if B.Conf.ObjectiveTrackerMinimized then - Scroller_OnShow(Scroller) + if hasStuff or insertingStuff then + + print('updating height to', wrapperHeight) + Wrapper:SetHeight(wrapperHeight) + Scroller:SetHeight(wrapperHeight) + Scroll:SetHeight(wrapperHeight) + print('|cFFFF8800Wrapper:', Wrapper:GetSize()) + for i = 1, Wrapper:GetNumPoints() do + print(' ', Wrapper:GetPoint(i)) + end + print(' |cFF00FFFFScroller:', Scroller:GetSize()) + for i = 1, Scroller:GetNumPoints() do + print(' ', Scroller:GetPoint(i)) + end + print(' |cFF00FFFFScroll:', Scroll:GetSize()) + for i = 1, Scroll:GetNumPoints() do + print(' ', Scroll:GetPoint(i)) + end + + Wrapper:Show() + Scroller:Show() + Scroll:Show() end - mod.UpdateWrapperStyle() + end -mod.InitializeXPTracker = function() - local XPBar = Wrapper.XPBar - if UnitLevel('player') == 100 then - XPBar:Hide() - return +DefaultTracker.GetBlock = function(handler, blockIndex) + local block = handler.usedBlocks[blockIndex] + if not handler.usedBlocks[blockIndex] then + if #handler.freeBlocks >= 1 then + block = handler.freeBlocks[#handler.freeBlocks] + handler.freeBlocks[#handler.freeBlocks] = nil + else + block = CreateFrame('Frame', 'Veneer'..tostring(handler)..'Block'..blockIndex, Scroll, 'VeneerTrackerBlock') + block.SetStyle = mod.SetBlockStyle + block.Select = handler.Select + block.Open = handler.Open + block.Remove = handler.Remove + block.Link = handler.Link + block:SetScript('OnMouseUp', handler.OnMouseUp) + block:SetScript('OnMouseDown', handler.OnMouseDown) + block.attachmentHeight = 0 + block:ClearAllPoints() + end + + handler.usedBlocks[blockIndex] = block end - - --- xp bar - XPBar:SetWidth(mod.Conf.Wrapper.WrapperWidth - Wrapper.CloseButton:GetWidth()) - XPBar.statusbg:SetAllPoints(XPBar) - XPBar:RegisterEvent('DISABLE_XP_GAIN') - XPBar:RegisterEvent('ENABLE_XP_GAIN') - XPBar:SetScript('OnEvent', mod.UpdateXP) - - if not IsXPUserDisabled() then - mod.EnableXP(XPBar) - else - mod.DisableXP(XPBar) - end - - mod.UpdateXP(XPBar) + return handler.usedBlocks[blockIndex] end -mod.EnableXP = function(self) - self:RegisterEvent('PLAYER_XP_UPDATE') - self:RegisterEvent('PLAYER_LEVEL_UP') - self:RegisterEvent('PLAYER_UPDATE_RESTING') - self.statusbg:SetTexture(0,0,0,.25) - self:Show() -end - -mod.DisableXP = function(self) - self:UnregisterEvent('PLAYER_XP_UPDATE') - self:UnregisterEvent('PLAYER_LEVEL_UP') - self:UnregisterEvent('PLAYER_UPDATE_RESTING') - self.statusbg:SetTexture(0.5,0.5,0.5,0.5) - self:Hide() -end - -mod.UpdateXP = function(self, event) - if event == 'DISABLE_XP_GAIN' then - mod.DisableXP(self) - elseif event == 'ENABLE_XP_GAIN' then - mod.EnableXP(self) - end - - if not IsXPUserDisabled() then - - local xp = UnitXP('player') - local xpmax = UnitXPMax('player') - local rest = GetXPExhaustion() - self.foreground:SetWidth((xp/xpmax) * self:GetWidth()) - if rest then - self.rested:ClearAllPoints() - if xp == 0 then - self.rested:SetPoint('TOPLEFT', self, 'TOPLEFT', 0, 0) - else - self.rested:SetPoint('TOPLEFT', self.fg, 'TOPRIGHT', 0, 0) - end - - if (xp + rest) > xpmax then - self.rested:SetPoint('BOTTOMRIGHT', self, 'BOTTOMRIGHT', 0, 0) - else - self.rested:SetWidth((rest/xpmax) * self:GetWidth()) - end - self.rested:SetPoint('BOTTOM', self, 'BOTTOM') - self.rested:Show() - else - self.rested:Hide() - end - - if IsResting() then - self.statusbg:SetTexture(.2,.8,.2,.5) - else - self.statusbg:SetTexture(0,0,0,.25) - end - self.xpText:SetText(xp .. '/'.. xpmax .. (rest and (' ('..tostring(rest)..')') or '')) - end -end - - - -mod.UpdateTracker = function(handler) - local tracker = handler.Tracker +DefaultTracker.Update = function (self, reason, dataID) + local tracker = self.frame print('|cFFFF4400'..tracker:GetName().. '|r:Update()') local blockIndex = 0 - local trackerHeight = tracker.titleHeight + local trackerHeight = 0 - previousBlock = tracker.title - local numWatched = handler.GetNumWatched() - local numBlocks = handler.numBlocks + self.currentAnchor = tracker.titlebg + local numWatched = self:GetNumWatched() + local numBlocks = self.numBlocks local actualBlocks = 0 for watchIndex = 1, 25 do blockIndex = blockIndex + 1 if watchIndex <= numWatched then - local info = handler:GetInfo(watchIndex) + local info = self:GetInfo(watchIndex) if info then - local currentBlock = mod.UpdateTrackerBlock(handler, blockIndex, info) - previousBlock = currentBlock + local currentBlock = self:UpdateBlock(blockIndex, info) + self.currentAnchor = currentBlock print(' |cFFFFFF00'..watchIndex..'|r', '|cFF00FF00'..currentBlock:GetName()..'|r', currentBlock.height) + print(currentBlock:IsVisible()) + print(currentBlock:GetPoint(1)) trackerHeight = trackerHeight + currentBlock.height numBlocks = max(numBlocks, watchIndex) actualBlocks = actualBlocks + 1 @@ -181,8 +163,8 @@ end elseif watchIndex <= numBlocks then - local used = handler.usedBlocks - local free = handler.freeBlocks + local used = self.usedBlocks + local free = self.freeBlocks print('clean up dead quest block') if used[blockIndex] then used[blockIndex]:Hide() @@ -195,16 +177,24 @@ break -- done with quest stuff end end - handler.numWatched = numWatched - handler.numBlocks = numBlocks - handler.actualBlocks = actualBlocks - handler:Report() + self.numWatched = numWatched + self.numBlocks = numBlocks + self.actualBlocks = actualBlocks + self:Report() + tracker.previousHeight = tracker.height if numBlocks >= 1 then previousBlock = nil - tracker.height = trackerHeight + + tracker.height = trackerHeight + tracker.titlebg:GetHeight() + tracker:SetHeight(tracker.height) + tracker:Show() + + print(tracker.height) + else tracker.height = 0 + tracker:Hide() end return tracker.numWatched, tracker.numAll @@ -215,54 +205,53 @@ -- @param blockNum the ordered block to be updated, not a watchIndex value -- @param info the reference returned by the GetXInfo functions -- REMEMBER: t.info and questData[questID] are the same table -mod.UpdateTrackerBlock = function (handler, blockIndex, info) +DefaultTracker.UpdateBlock = function (self, blockIndex, info) local print = B.print('BlockParse') print(' Read list item |cFF00FFFF'..blockIndex..'|r') if not blockIndex or not info then return end - local tracker = handler.Tracker - local t = handler:GetBlock(blockIndex) - t.handler = handler + local frame = self.frame + local t = self:GetBlock(blockIndex) + t.handler = self t.info = info t.mainStyle = info.mainStyle or 'Normal' t.subStyle = info.subStyle info.blockIndex = blockIndex - if info.questID then handler.QuestBlock[info.questID] = t end - if info.questLogIndex then handler.LogBlock[info.questLogIndex] = t end - if info.watchIndex then handler.WatchBlock[info.watchIndex] = t end - handler.BlockInfo[blockIndex] = info - + if info.questID then self.QuestBlock[info.questID] = t end + if info.questLogIndex then self.LogBlock[info.questLogIndex] = t end + if info.watchIndex then self.WatchBlock[info.watchIndex] = t end + self.BlockInfo[blockIndex] = info t.attachmentHeight = 0 - - - - - - if info.isComplete == 1 then - if info.popupInfo then + if info.isComplete then + if mod.AutoQuest.Info[info.questID] then t.status:SetText('(Click to Complete)') + t.status:Show() else t.status:SetText('Ready to turn in') + t.status:Show() end elseif info.completed then t.status:SetText(nil) + t.status:Hide() elseif info.numObjectives >= 1 then t.attachmentHeight = 0 t.status:Show() - print(' lines to build:', info.numObjectives) + print(' lines to parse:', info.numObjectives) local text = '' mod.UpdateObjectives(t, info, text) + print(' |cFF00FF00attachment', t.attachmentHeight) elseif info.description then t.status:SetText(info.description) + t.status:Show() else t.status:SetText(nil) + t.status:Show() end t.title:SetText(info.title) - print(' ', t.status:CanWordWrap(), t.status:GetStringHeight()) if info.specialItem and not info.itemButton then @@ -272,15 +261,16 @@ --info.itemButton = nil end - if previousBlock then - t:SetPoint('TOPLEFT', previousBlock, 'BOTTOMLEFT', 0, 0) - t:SetPoint('RIGHT', tracker,'RIGHT', 0, 0) - print(' anchor to|cFF0088FF', previousBlock:GetName()) + if self.currentAnchor then + t:SetPoint('TOPLEFT', self.currentAnchor, 'BOTTOMLEFT', 0, 0) + t:SetPoint('RIGHT', frame,'RIGHT', 0, 0) + print(' anchor to|cFF0088FF', self.currentAnchor:GetName()) end --- metrics are calculated in SetStyle - t:SetStyle('TrackerBlock', handler.name, t.mainStyle, t.subStyle) + t:SetStyle('TrackerBlock', self.name, t.mainStyle, t.subStyle) + print(' |cFFFFFF00height|r', t.height) t:Show() print(' |cFF00FFFF)|r -> ', t, t:GetHeight()) @@ -338,11 +328,14 @@ return t end + + mod.UpdateObjectives = function(block, info, text) local print = B.print('BlockLine') print(' |cFF00FF00objective updates for', block:GetName()) local attachmentHeight = block.attachmentHeight + print(attachmentHeight) if info.description and not(info.earnedBy or info.isComplete) then print(' -- has description text:', select('#', info.description), info.description) text = info.description @@ -350,6 +343,7 @@ local completionScore, completionMax = 0, 0 for i, line in ipairs(info.objectives) do + print(attachmentHeight) print(' |cFF88FF00objective', i) block.handler.ParseObjective(line, info) @@ -360,7 +354,8 @@ if line.widget then if attachmentHeight == 0 then - attachmentHeight = block.status.spacing + attachmentHeight = (block.status.spacing or block.status:GetSpacing()) * 2 + --print(attachmentHeight) end line.widget:Show() line.widget:SetParent(block) @@ -377,6 +372,8 @@ end end + + block.completionScore = completionScore / completionMax block.attachmentHeight = attachmentHeight @@ -396,7 +393,7 @@ -- * lines - number of non-wrapped text lines to account for line space; may be discarded depending on things -- * money - boolean that determines listening for money events or not -- * progress - number ranging 0 to 2 indicating none/partial/full completion respectively -mod.Tracker.ParseObjective = function(line, info) +DefaultTracker.ParseObjective = function(line, info) if line.finished then line.progress = 2 @@ -482,6 +479,7 @@ mod.Quest.numButtons = 0 local usedButtons = mod.Quest.itemButtons local freeButtons = mod.Quest.freeButtons +--[=[ mod.UpdateWrapper = function(reason) print('|cFF00FFFFUpdateWrapper:|r', reason) unitLevel = UnitLevel('player') @@ -492,16 +490,16 @@ scrollHeight = 0 for i, handler in ipairs(orderedHandlers) do mod.UpdateTracker(handler) - local tracker = handler.Tracker + local frame = handler.frame if handler.actualBlocks >= 1 then - tracker:SetParent(Scroll) - tracker:SetPoint('TOPLEFT', Scroll, 'TOPLEFT', 0, - scrollHeight) - tracker:SetSize(wrapperWidth, tracker.height) - print('|cFF00FFFF'..tracker:GetName()..'|r h:|cFF00FF00', tracker.height, '|r y:|cFF00FF00', -scrollHeight) - scrollHeight = scrollHeight + tracker.height - tracker:Show() + frame:SetParent(Scroll) + frame:SetPoint('TOPLEFT', Scroll, 'TOPLEFT', 0, - scrollHeight) + frame:SetSize(wrapperWidth, frame.height) + print('|cFF00FFFF'..frame:GetName()..'|r h:|cFF00FF00', frame.height, '|r y:|cFF00FF00', -scrollHeight) + scrollHeight = scrollHeight + frame.height + frame:Show() else - tracker:Hide() + frame:Hide() end wrapperBlocks = wrapperBlocks + handler.actualBlocks end @@ -561,6 +559,7 @@ mod.UpdateActionButtons() end +--]=] --- Queue any active item buttons for update for that frame mod.UpdateActionButtons = function(updateReason)