You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
147 lines
3.8 KiB
147 lines
3.8 KiB
local myname, ns = ...
|
|
|
|
local core = LibStub("AceAddon-3.0"):GetAddon("SilverDragon")
|
|
local module = core:GetModule("ClickTarget")
|
|
local Debug = core.Debug
|
|
|
|
module.pools = {}
|
|
function module:GetPopupLookPool(look)
|
|
look = look and (self.Looks[look] and look) or "SilverDragon"
|
|
if not module.pools[look] then
|
|
module.pools[look] = CreateObjectPool(
|
|
function(pool) return module:CreatePopup(look) end,
|
|
function(pool, popup)
|
|
popup:Reset()
|
|
tDeleteItem(module.stack, popup)
|
|
module:ProcessQueue()
|
|
end
|
|
)
|
|
end
|
|
return module.pools[look]
|
|
end
|
|
|
|
function module:Acquire(look)
|
|
return self:GetPopupLookPool(look):Acquire()
|
|
end
|
|
|
|
function module:Release(popup)
|
|
local pool = self:GetPopupLookPool(popup.look)
|
|
if pool:IsActive(popup) then
|
|
pool:Release(popup)
|
|
end
|
|
end
|
|
|
|
do
|
|
local function enumerate()
|
|
for look, pool in pairs(module.pools) do
|
|
for popup in pool:EnumerateActive() do
|
|
coroutine.yield(popup, look)
|
|
end
|
|
end
|
|
end
|
|
function module:EnumerateActive()
|
|
return coroutine.wrap(enumerate)
|
|
end
|
|
end
|
|
|
|
module.queue = {}
|
|
module.stack = {}
|
|
module.overflow = {}
|
|
function module:Enqueue(data)
|
|
for _, data2 in ipairs(self.queue) do
|
|
if data.type == data2.type and data.id == data2.id then
|
|
-- don't double up on the queue
|
|
return
|
|
end
|
|
end
|
|
for _, popup in ipairs(self.stack) do
|
|
if popup.data and popup.data.type == data.type and popup.data.id == data.id then
|
|
-- also don't double up on already-shown
|
|
return
|
|
end
|
|
end
|
|
table.insert(self.queue, data)
|
|
if InCombatLockdown() then
|
|
Debug("Queueing popup for out-of-combat")
|
|
data.unit = nil
|
|
else
|
|
self:ProcessQueue()
|
|
end
|
|
end
|
|
|
|
function module:ProcessQueue()
|
|
if module.PAUSED or InCombatLockdown() then return end
|
|
while #self.queue > 0 do
|
|
local data = table.remove(self.queue)
|
|
Debug("Showing queued popup")
|
|
table.insert(self.stack, 1, self:ShowFrame(data))
|
|
-- overflow off the end:
|
|
if #self.stack > self.db.profile.stacksize then
|
|
local stacked = table.remove(self.stack)
|
|
table.insert(module.overflow, 1, stacked.data)
|
|
stacked:Hide()
|
|
end
|
|
end
|
|
while #self.overflow > 0 and #self.stack < self.db.profile.stacksize do
|
|
-- overflow data was previously pushed off the end of the stack, and so should be put back in at the end
|
|
local data = table.remove(self.overflow)
|
|
table.insert(self.stack, self:ShowFrame(data))
|
|
end
|
|
self:Reflow()
|
|
end
|
|
|
|
do
|
|
local merge = function(t1, t2)
|
|
if not t2 then return t1 end
|
|
for k, v in pairs(t2) do
|
|
t1[k] = v
|
|
end
|
|
return t1
|
|
end
|
|
function module:UpdateWithData(data)
|
|
for _, data2 in ipairs(self.queue) do
|
|
if data.type == data2.type and data.id == data2.id then
|
|
return merge(data2, data)
|
|
end
|
|
end
|
|
for _, popup in ipairs(self.stack) do
|
|
if popup.data and popup.data.type == data.type and popup.data.id == data.id then
|
|
merge(popup.data, data)
|
|
return self:RefreshData(popup)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
function module:Reflow()
|
|
if module.PAUSED or InCombatLockdown() then return end
|
|
for i, popup in ipairs(self.stack) do
|
|
popup:ClearAllPoints()
|
|
if i == 1 then
|
|
popup:SetPoint("CENTER", self.anchor, "CENTER")
|
|
else
|
|
local _, y = self.anchor:GetCenter()
|
|
local s = self.anchor:GetScale()
|
|
if (y * s) < (UIParent:GetHeight() / 2) then
|
|
popup:SetPoint("BOTTOM", self.stack[i - 1], "TOP", 0, 10)
|
|
else
|
|
popup:SetPoint("TOP", self.stack[i - 1], "BOTTOM", 0, -10)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
function module:Redraw()
|
|
if module.PAUSED or InCombatLockdown() then return end
|
|
module.PAUSED = true
|
|
-- need to loop twice and bypass the duplicate checks
|
|
for i, popup in ipairs(self.stack) do
|
|
table.insert(self.queue, popup.data)
|
|
end
|
|
while #self.stack > 0 do
|
|
-- this will release and reset the existing frame
|
|
table.remove(self.stack):Hide()
|
|
end
|
|
module.PAUSED = false
|
|
self:ProcessQueue()
|
|
end
|
|
|