# HG changeset patch # User Nenue # Date 1459536014 14400 # Node ID 7923243ae9720cb7aeaf791d2a573b08cdb6e0fc # Parent 5301c68f28d8cb71d592ea5f79fb9aa980824972 ObjectiveUI & ObjectiveEvents - securehook to API calls for compatibility with addons that work with the objective tracking interface - let the API hooks invoke ObjectiveUI functions when possible - ObjectiveUI framescript handlers should use the corresponding API call if possible, so that addon space can be fully aware of our actions - Sanity check cached data when possible during 'Remove' hooks ObjectiveInfo - Add cheevID to criteria info ObjectiveCore - Index quest tracker blocks by their watch offset, and use that to verify whether the given block frame should be released into pool ObjectiveFrame - Differentiate between visible and non-visible unused buttons, and only release when their quest has been dropped diff -r 5301c68f28d8 -r 7923243ae972 ObjectiveCore.lua --- a/ObjectiveCore.lua Fri Apr 01 12:27:05 2016 -0400 +++ b/ObjectiveCore.lua Fri Apr 01 14:40:14 2016 -0400 @@ -150,9 +150,9 @@ Tracker.Info = {} -- find by data ID Tracker.BlockInfo = {} -- find by block ID Tracker.LogInfo = {} -- find by log ID (quest log mainly) -Tracker.WatchBlock = {} Tracker.WatchInfo = {} Tracker.LogBlock = {} +Tracker.WatchBlock = {} diff -r 5301c68f28d8 -r 7923243ae972 ObjectiveEvents.lua --- a/ObjectiveEvents.lua Fri Apr 01 12:27:05 2016 -0400 +++ b/ObjectiveEvents.lua Fri Apr 01 14:40:14 2016 -0400 @@ -28,7 +28,8 @@ ['RemoveQuestWatch'] = 'RemoveQuestWatch', ['AbandonQuest'] = 'AbandonQuest', ['AcknowledgeAutoAcceptQuest'] = 'AcknowledgeAutoAcceptQuest', - ['AddAutoQuestPopUp'] = 'AddAutoQuestPopUp' + ['AddAutoQuestPopUp'] = 'AddAutoQuestPopUp', + ['RemoveTrackedAchievement'] = 'RemoveTrackedAchievement' } mod.SetEvents = function() @@ -111,15 +112,38 @@ mod.UpdateWrapper() end -mod.RemoveQuestWatch = function(questIndex) +mod.RemoveQuestWatch = function(questIndex, ...) + print('|cFFFF8800RemoveQuestWatch', questIndex, ...) + local info = mod.Quest.LogInfo[questIndex] + + -- remove quest refs + mod.Quest.LogBlock[questIndex] = nil + mod.Quest.QuestBlock[info.questID] = nil + + -- remove if they still match + if mod.Quest.WatchInfo[info.watchIndex] == info then + print('cleaning dead WatchInfo entry') + mod.Quest.WatchInfo[info.watchIndex] = nil + end + mod.UpdateWrapper() + QuestPOIUpdateIcons() +end + +mod.RemoveTrackedAchievement = function(cheevID) + print('|cFFFF8800UntrackAchievement', cheevID) + mod.CleanWidgets() end mod.AcceptQuest = function() end mod.AbandonQuest = function() + + QuestPOIUpdateIcons() end mod.TurnInQuest = function() + + QuestPOIUpdateIcons() end \ No newline at end of file diff -r 5301c68f28d8 -r 7923243ae972 ObjectiveFrame.lua --- a/ObjectiveFrame.lua Fri Apr 01 12:27:05 2016 -0400 +++ b/ObjectiveFrame.lua Fri Apr 01 14:40:14 2016 -0400 @@ -668,7 +668,6 @@ ) mod.UpdateActionButtons('FULL_UPDATE') - QuestPOIUpdateIcons() end --- Queue any active item buttons for update for that frame @@ -704,10 +703,12 @@ itemButton.previousItem = nil itemButton:Hide() end - else - print(' |cFFFF0088missing block data', itemButton:GetName()) + elseif itemButton:IsVisible() then + print(' |cFFFF0088hiding unwatched quest button', itemButton:GetName()) itemButton.previousItem = nil itemButton:Hide() + else + print(' |cFFBBBBBBignoring hidden log quest button', itemButton:GetName()) end end end diff -r 5301c68f28d8 -r 7923243ae972 ObjectiveInfo.lua --- a/ObjectiveInfo.lua Fri Apr 01 12:27:05 2016 -0400 +++ b/ObjectiveInfo.lua Fri Apr 01 14:40:14 2016 -0400 @@ -57,8 +57,6 @@ q.isBreadCrumb = IsBreadcrumbQuest(questID) q.isStoryQuest = IsStoryQuest(questID) q.completionText= GetQuestLogCompletionText(questIndex) - q.trackingID = questID - q.superTracked = (questID == GetSuperTrackedQuestID()) -- call directly so artifact data doesn't become an issue q.numObjectives = GetNumQuestLeaderBoards(questIndex) q.isWatched = IsQuestWatched(questIndex) q.objectives = {} @@ -105,6 +103,8 @@ end end + q.superTracked = (questID == GetSuperTrackedQuestID()) -- call directly so artifact data doesn't become an issue + self.WatchInfo[watchIndex] = q self.LogInfo[questIndex] = q print('- logIndex =', questIndex, 'title =', title) return q @@ -147,6 +147,7 @@ for i = 1, c.numObjectives do local description, type, completed, quantity, requiredQuantity, characterName, flags, assetID, quantityString, criteriaID = GetAchievementCriteriaInfo(cheevID, i) c.objectives[i] = { + cheevID = cheevID, text = description, type = type, finished = completed, diff -r 5301c68f28d8 -r 7923243ae972 ObjectiveUI.lua --- a/ObjectiveUI.lua Fri Apr 01 12:27:05 2016 -0400 +++ b/ObjectiveUI.lua Fri Apr 01 14:40:14 2016 -0400 @@ -36,7 +36,8 @@ self.initialButton = nil self.modChatLink = nil self.modQuestWatch = nil - print('|cFFFF8800'..tostring(self:GetName())..':MouseUp()|r ->',self.info.trackingID) + print(IsModifiedClick("CHATLINK"), IsModifiedClick("QUESTWATCHTOGGLE")) + print('|cFFFF8800'..tostring(self:GetName())..':MouseUp()|r') end Tracker.OnMouseDown = function(self, button) @@ -44,6 +45,7 @@ self.modChatLink = IsModifiedClick("CHATLINK") self.modQuestWatch = IsModifiedClick("QUESTWATCHTOGGLE") self:SetStyle('Active') + print(IsModifiedClick("CHATLINK"), IsModifiedClick("QUESTWATCHTOGGLE")) print(self.info.title) end @@ -72,11 +74,6 @@ Quest.Remove = function(self) print('removing', self.info.questLogIndex, 'from watcher') RemoveQuestWatch(self.info.questLogIndex) - - mod.Quest.LogBlock[self.info.questLogIndex] = nil - mod.Quest.QuestBlock[self.info.questID] = nil - QuestPOIUpdateIcons() - mod.UpdateWrapper() end @@ -84,12 +81,18 @@ --- CHEEVS Cheevs.Select = function(self) end +Cheevs.Remove = function(self) + RemoveTrackedAchievement(self.info.cheevID) +end +Cheevs.OnMouseUp = function(self) + Tracker.OnMouseUp(self) + self:SetStyle('CheevNormal') +end Cheevs.Link = function(self) - local achievementLink = GetAchievementLink(self.info.cheevID); - if ( achievementLink ) then - ChatEdit_InsertLink(achievementLink); - end - self:SetStyle('CheevNormal') + local achievementLink = GetAchievementLink(self.info.cheevID); + if ( achievementLink ) then + ChatEdit_InsertLink(achievementLink); + end end Cheevs.Open = function(self) @@ -249,37 +252,42 @@ --- Get a usable widget for the given achievement criteria set. -- Returns a frame object with dimensioning parameters needed to size the receiving tracker block mod.SetWidget = function(obj, info) + local print = B.print('ObjectiveWidgets') local widgetType = obj.type local widget + if wr[widgetType] and wr[widgetType].used[obj.criteriaID] then + widget = wr[widgetType].used[obj.criteriaID] + print('|cFF00FF00Updating ('..obj.criteriaID..')', widget) + elseif not wr[widgetType] or #wr[widgetType].free == 0 then + widget = CreateFrame('Frame', 'VeneerObjective' .. widgetType .. (wr[widgetType] and (wr[widgetType].lastn+1) or (1)), VeneerObjectiveScroll, 'VeneerObjectiveCriteria' .. widgetType) - if not wr[widgetType] or #wr[widgetType].free == 0 then - print('VeneerObjectiveCriteria' .. widgetType) - widget = CreateFrame('Frame', nil, VeneerObjectiveScroll, 'VeneerObjectiveCriteria' .. widgetType) + print('|cFFFF0088Creating `'..widget:GetName()..'` id', wr[widgetType].lastn) + else + widget = tremove(wr[widgetType].free) + print('|cFFFFFF00Acquiring released widget', widget:GetName()) end - local free = wr[widgetType].free - local used = wr[widgetType].used - widget = tremove(free) - local index = #used+1 - used[index] = widget - wr[widgetType].usedIndex[widget] = index + wr[widgetType].used[obj.criteriaID] = widget widget.info = obj widget.parentInfo = info mod.InitializeWidget(widget) - return widget end ---- Fired by OnLoad() when a new frame is spawned +--- WidgetTemplate 'OnLoad' mod.RegisterWidget = function(frame) + local print = B.print('ObjectiveWidgets') local widgetType = frame.widgetType - local obj = frame.info if not wr[frame.widgetType] then print('|cFFFF4400[[WidgetTemplate]]|r', widgetType) - wr[widgetType] = { lastn = 0, free = {}, used = {}, usedIndex = {}, freeIndex = {} } + wr[widgetType] = { lastn = 1, free = {}, used = {}, usedIndex = {}, freeIndex = {} } + else + print('|cFF0088FF+ [[WidgetTemplate]]r', widgetType, wr[widgetType].lastn) + wr[widgetType].lastn = wr[widgetType].lastn + 1 end - tinsert(wr[frame.widgetType].free, frame) end + +--- WidgetTemplate 'OnShow' mod.InitializeWidget = setmetatable({}, { __call = function(t, frame) -- todo: config pull @@ -301,6 +309,8 @@ return t[frame.widgetType](frame) end, }) + +--- WidgetTemplate 'OnEvent' mod.UpdateWidget = setmetatable({}, { __call = function(t, frame) if not frame.widgetType then @@ -312,13 +322,35 @@ end }) +--- WidgetTemplate 'OnHide' mod.ReleaseWidget = function(frame) + local print = B.print('ObjectiveWidgets') local reg = wr[frame.widgetType] - if reg and reg.usedIndex[frame] then - tremove(reg.used, reg.usedIndex[frame]) - reg.usedIndex[frame] = nil + if reg and reg.used[frame.info.criteriaID] then + reg.used[frame.info.criteriaID] = nil + frame.info = nil + frame.parentInfo = nil frame:UnregisterAllEvents() tinsert(reg.free, frame) + print('|cFFBBBBBBreleased from service', frame:GetName()) + end +end + +--- RemoveTrackedAchievement post-hook +mod.CleanWidgets = function() + local print = B.print('ObjectiveWidgets') + local tracked = {GetTrackedAchievements() } + for type, reg in pairs(mod.WidgetRegistry) do + print('collecting', type) + for criteriaID, frame in pairs(reg.used) do + local id = frame.info.cheevID + + if id and not tContains(tracked, id) then + + print(' untracked achievement', id, 'associated with', criteriaID, frame:GetName()) + frame:Hide() + end + end end end @@ -331,26 +363,27 @@ } mod.InitializeWidget.ProgressBar = function(self) + local print = B.print('ObjectiveWidgets') local params = mod.WidgetParams[self.widgetType] self.height = params.height self:SetHeight(20) self.bg:SetHeight(20) - self.fg:SetHeight(18) + self.fg:SetHeight(16) self.fg:SetPoint('BOTTOMLEFT', self.bg, 'BOTTOMLEFT', 1, 1) self.quantityString:SetFontObject(params.quantityString.SetFontObject) self.quantityString:SetText(self.info.quantityString) end mod.UpdateWidget.ProgressBar = function (self) + local print = B.print('ObjectiveWidgets') local quantity, requiredQuantity = self.info.quantity, self.info.requiredQuantity - self.fg:SetPoint('TOPLEFT', self, 'TOPLEFT', 0, 0) + if self.info.finished then self.fg:SetWidth(self.bg:GetWidth() - 2) elseif quantity == 0 then self.fg:Hide() else self.fg:Show() - self.fg:SetWidth(self:GetWidth() * (quantity / requiredQuantity)) + self.fg:SetWidth((self:GetWidth()-2) * (quantity / requiredQuantity)) end - -end +end \ No newline at end of file diff -r 5301c68f28d8 -r 7923243ae972 ObjectiveWidgets.xml --- a/ObjectiveWidgets.xml Fri Apr 01 12:27:05 2016 -0400 +++ b/ObjectiveWidgets.xml Fri Apr 01 14:40:14 2016 -0400 @@ -21,7 +21,7 @@ - + @@ -32,9 +32,6 @@ - - -