changeset 8:7923243ae972

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
author Nenue
date Fri, 01 Apr 2016 14:40:14 -0400
parents 5301c68f28d8
children 2698173edd40
files ObjectiveCore.lua ObjectiveEvents.lua ObjectiveFrame.lua ObjectiveInfo.lua ObjectiveUI.lua ObjectiveWidgets.xml
diffstat 6 files changed, 101 insertions(+), 45 deletions(-) [+]
line wrap: on
line diff
--- 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 = {}
 
 
 
--- 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
--- 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
--- 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,
--- 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
--- 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 @@
     <Layers>
       <Layer level="BACKGROUND">
         <Texture SetAllPoints="true" name="$parentBackground" parentKey="bg">
-          <Color r="0" g="0" b="0" a="0.25" />
+          <Color r="0" g="0" b="0" a="0.70" />
           <Anchors>
             <Anchor point="BOTTOMLEFT" />
             <Anchor point="TOPRIGHT" />
@@ -32,9 +32,6 @@
 
         <Texture SetAllPoints="true" name="$parentForeground" parentKey="fg">
           <Color r="1" g="1" b="1" a="1" />
-          <Anchors>
-            <Anchor point="TOPLEFT" x="1" y="-1" />
-          </Anchors>
         </Texture>
       </Layer>
       <Layer level="OVERLAY">