view ObjectiveTracker/DefaultTracker.lua @ 37:e84d645c8ab8

- revised the tracker update function to build its complete data list up front and use the values as points of comparison for determining possible out of place blocks, which will be iterated over afterward to remove what wasn't re-used - also entailed revising the exact role of global event handlers and function hooks, limiting their directions of communication so one doesn't end up calling the other multiple or inifinity times - schema handling polish
author Nenue
date Mon, 18 Apr 2016 07:56:23 -0400
parents a487841050be
children 1f8f9cc3d956
line wrap: on
line source
--- ${PACKAGE_NAME}
-- @file-author@
-- @project-revision@ @project-hash@
-- @file-revision@ @file-hash@
-- Created: 4/17/2016 7:33 AM
local B = select(2,...).frame
local T = B:RegisterModule("ObjectiveTracker", _G.VeneerObjectiveWrapper, 'BuffFrame')
local _G, ipairs, max, min, unpack, floor, pairs, tostring, type, band = _G, ipairs, max, min, unpack, floor, pairs, tostring, type, bit.band
local IsResting, UnitXP, UnitXPMax, GetXPExhaustion, tinsert, tremove = IsResting, UnitXP, UnitXPMax, GetXPExhaustion, table.insert, table.remove
local UnitLevel, IsQuestWatched, UIParent = UnitLevel, IsQuestWatched, UIParent
local GetAutoQuestPopUp, GetQuestLogCompletionText = GetAutoQuestPopUp, GetQuestLogCompletionText
local PERCENTAGE_STRING, GetQuestProgressBarPercent = PERCENTAGE_STRING, GetQuestProgressBarPercent
local Default, AutoQuest, Quest, Bonus, Cheevs = T.DefaultHandler, T.AutoQuest, T.Quest, T.Bonus, T.Cheevs
local InCombatLockdown, format, lshift, CreateFrame = InCombatLockdown, format, bit.lshift, CreateFrame
local IsModifiedClick, ChatEdit_GetActiveWindow = IsModifiedClick, ChatEdit_GetActiveWindow
local print = B.print('Tracker')
local oprint = B.print('Objectives')
local bprint = B.print('Block')
local tprint = B.print('Tracker')
local lprint = B.print('Line')
local unitLevel = 1
local OBJECTIVE_TRACKER_UPDATE_REASON = OBJECTIVE_TRACKER_UPDATE_REASON
local debug = false

--- FRAMES
local Wrapper = _G.VeneerObjectiveWrapper
local Scroller = Wrapper.scrollArea
local Scroll = _G.VeneerObjectiveScroll
local orderedHandlers = T.orderedHandlers
local orderedNames = T.orderedNames


--- Placing the Update functions here since they shouldn't be messing with schema stuff
local currentPosition, anchorFrame, anchorPoint
--- Positioning and stuff
local tick = 0
local firstUpdate = true
function T:Update (reason, ...)
  if not B.Conf.VeneerObjectiveWrapper.enabled then
    return
  end

  tick = tick + 1
  if firstUpdate or not reason then
    reason = _G.OBJECTIVE_TRACKER_UPDATE_ALL
  end

  local print = tprint
  local hasStuff = false
  local insertingStuff = false

  print(format('|cFFBB0066Update:|r |cFFFF%04X%d|r  ', tick, lshift(reason, 4)), reason, ...)
  currentPosition = 0

  for id, handler in pairs(T.orderedHandlers) do
    local frame = handler.frame


    if band(reason, handler.updateReasonModule + handler.updateReasonEvents) > 0 then
      insertingStuff = handler:UpdateTracker(reason, ...)
    else
      print('  |cFFFF4400Update:|r skipping',handler.name)
    end

    if handler.numWatched >= 1 then
      hasStuff = true
      currentPosition = currentPosition + 1
      Default.AddTracker(handler, frame, currentPosition)

    else
      frame:ClearAllPoints()
      frame:SetPoint('BOTTOM', Scroll, 'BOTTOM', 0, 0)
      frame.destinationOffset = 0
      frame:Hide()
      frame.wasEmpty = true
    end
  end

  -- do these whenever there is content or content is being added
  if  hasStuff or insertingStuff then
    T:FinishWrapper()
  end
  Quest.GetClosest()
  --T.UpdateActionButtons(reason)
  if firstUpdate then
    firstUpdate = nil
  end
end

Default.UpdateTracker = function (handler, reason, id, isNew)
  local print = tprint
  local frame = handler.frame
  local blockIndex = 0

  print(format('  |cFFFF8800UpdateTracker|r(%s): %s', handler.name, reason))
  handler.updateReason = reason
  local numWatched, numAll, watchTable = handler:GetNumWatched(id, isNew)

  if numWatched >= 1 then
    if watchTable then
      print('|cFF00FF00      n     ID    Obj wID Log Blk')
      for i, w in ipairs(watchTable) do
        print(format('     %2d => %6d %3d %3d %3s %s', i, w.id, w.numObjectives, w.watchIndex, (w.logIndex or ''), (handler.InfoBlock[w.id] and handler.InfoBlock[w.id]:GetName() or '')))
      end
    end
  end

  handler.numWatched = numWatched
  handler.numAll = numAll
  handler.numBlocks = 0
  handler.currentBlock = 0
  handler.currentAnchor = frame.titlebg
  for blockIndex = 1, numWatched do
    local currentBlock = handler:UpdateBlock(blockIndex, id, isNew)
    if currentBlock then
      handler:AddBlock(currentBlock)
    else
      print('    |cFFFF9900finished|r @', blockIndex)
      break -- done with quest stuff
    end
  end


  local numBlocks = handler.numBlocks
  local used = handler.usedBlocks
  local free = handler.freeBlocks
  print(format('    (%s): |cFFFF8800%04X|r --- blocks |cFFFF8800%d|r, (used/free: |cFFFF8800%d|r/|cFFFF8800%d|r)', handler.name, band(reason, handler.updateReasonModule + handler.updateReasonEvents, reason), numBlocks, #used, #free))
  return numWatched, numAll
end

Default.UpdateBlock = function (handler, index)
  local print = bprint
  if not index then
    return
  end
  local info = handler.WatchList[index] -- should match up with whatever the internal watch list has
  if not info then
    return
  end
  print('  Updating |cFF00FF00'..handler.displayName..'|r|cFF00FFFF'..index..'|r|cFF0099FF', info.id ,'|r')
  local frame = handler.frame
  local block = handler:GetBlock(info.id)

  block.handler = handler
  block.info = info

  info.blockIndex = index
  if info.id then
    print('  storing id', info.id, 'for', block:GetName())
    handler.InfoBlock[info.id] = block
  end
  if info.logIndex then
    print('  storing logIndex', info.logIndex, 'for', block:GetName())
    handler.LogBlock[info.logIndex] = block
  end
  if info.watchIndex then
    print('  storing watchIndex', info.watchIndex, 'for', block:GetName())
    handler.WatchBlock[info.watchIndex] = block
  end
  handler.BlockInfo[index] = info
  handler:UpdateObjectives(block)

  block.title:SetText(info.title)

  print('           |cFFFFFF00height|r:', block.height)
  print('  |cFF00FFFF)|r -> ', block, block:GetHeight())

  block:Show()

  if info.specialItem and not info.itemButton then
    print('    - |cFF00FFFFgenerating item button for info set')
    info.itemButton = T.SetItemButton(block, info)
  else
    --info.itemButton = nil
  end

  local tagPoint, tagAnchor, tagRelative, x, y = 'TOPRIGHT', block, 'TOPRIGHT', -2, -2

  local numCurrency = 0
  for i, rewardTile in ipairs(block.rewardTile) do
    if info.rewardInfo and info.rewardInfo[i] then
      local reward = info.rewardInfo[i]
      --rewardTile:SetPoint(tagPoint, tagAnchor, tagRelative, -2, -2)
      rewardTile:SetTexture(reward.texture)
      rewardTile:Show()

      print('updating reward tile #'.. i, reward.type, reward.count, reward.text, reward.texture)
      if reward.count and reward.count > 1 then
        block.rewardLabel[i]:SetText(reward.count)
        block.rewardLabel[i]:Show()
      end

      rewardTile:ClearAllPoints()
      rewardTile:SetPoint(tagPoint, tagAnchor, tagRelative, x, y)
      tagPoint, tagAnchor, tagRelative, x, y = 'TOPRIGHT', rewardTile, 'TOPLEFT', -2, 0
    else
      rewardTile:Hide()
      block.rewardLabel[i]:Hide()
    end
  end

  if info.selected then
    block.SelectionOverlay:Show()
  else
    block.SelectionOverlay:Hide()
  end

  if info.tagInfo then
    tagPoint, tagAnchor, tagRelative = handler:AddTag(block, 'frequencyTag', tagPoint, tagAnchor, tagRelative)
    tagPoint, tagAnchor, tagRelative = handler:AddTag(block, 'typeTag', tagPoint, tagAnchor, tagRelative)
    tagPoint, tagAnchor, tagRelative = handler:AddTag(block, 'completionTag', tagPoint, tagAnchor, tagRelative)
  end

  if info.schema then
    block.schema = info.schema
  end

  if info.statusKey and (Devian and Devian.InWorkspace()) then
    block.debugText:SetText(tostring(info.statusKey) .. ' ' .. tostring(block.posIndex) .. ' '.. tostring(info.logIndex))
    block.debugText:Show()
  end
  return block
end

Default.UpdateObjectives = function(handler, block)
  local print = lprint
  local block_schema = block.schema
  local info = block.info
  print('  |cFF00FF00default.objectives', block:GetName())
  -- reset the starting positions
  block.endPoint = block.titlebg
  block.attachmentHeight = 0
  block.currentLine = 0

  local displayObjectiveHeader = false

  block.attachmentHeight = 0
  local text, attachment, template


  if info.description and #info.description >= 1 then
    print('   |cFF00FFFF  header line:|r', info.description)
    text = info.description
    handler:AddLine(block, text, nil)
  end

  if (info.isComplete or info.numObjectives == 0) and info.completionText then
    print('     overriding line #1 for completion text:', info.completionText)
    text = info.completionText
    handler:AddLine(block, text, nil, 'completed')
  else
    if info.objectives then
      for i, data in ipairs(info.objectives) do
        local line = handler:GetLine(block)
        displayObjectiveHeader = true
        line.height = 0
        text, attachment, template = handler:UpdateLine(block, line, data)
        print('  |cFF88FF00#', i, data.type, text, attachment)
        handler:AddLine(block, text, attachment, template)

      end
    end
  end

  if block.currentLine < block.numLines then
    print('  - cull', block.currentLine, block.numLines)
    for i = block.currentLine + 1, block.numLines do
      print('  - hide |cFFFF0088'..i..'|r', block.lines[i])
      block.lines[i]:ClearAllPoints()
      block.lines[i]:Hide()
    end
  end

  if block.currentLine > 0 then
    block.attachmentHeight = block.attachmentHeight
    print('   |cFF00FF00attachment:', block.attachmentHeight)
  end
  return block_schema
end

Default.UpdateLine = function(handler, block, line, data)
  return data.text, line.widget, 'normal'
end

Default.Select = function(handler, block)
  T:Update()
end
Default.Open = function(handler, block)
  T:Update(handler.updateReasonModule)
end
Default.Remove = function(handler, block)
  T:Update(handler.updateReasonModule)
end
Default.Report = function(handler, block)
  print('Stats:', handler.numWatched,'items tracked,', handler.numBlocks,'blocks assigned.')
end

Default.OnMouseUp = function(self, button)
  print(self.handler.name, self.mainStyle, self.subStyle)
  if button == 'LeftButton' then
    if IsModifiedClick("CHATLINK") and ChatEdit_GetActiveWindow() then
      self.Link(self.handler, self)
    elseif IsModifiedClick("QUESTWATCHTOGGLE") then
      self.Remove(self.handler, self)
    else
      self.Select(self.handler, self)
    end
  elseif button == 'RightButton' then
    self.Open(self.handler, self)
  end
  self.initialButton = nil
  self.modChatLink = nil
  self.modQuestWatch = nil
  --T:Update(self.handler.updateReasonModule)
  print('|cFFFF8800'..tostring(self:GetName())..':MouseUp()|r')
end
Default.OnMouseDown = function(self, button)
  print(self.info.title)
end