-- ------------------------------------------------------------------------------ -- -- TradeSkillMaster -- -- https://tradeskillmaster.com -- -- All Rights Reserved - Detailed license information included with addon. -- -- ------------------------------------------------------------------------------ -- local _, TSM = ... local Cooldowns = TSM.TaskList:NewPackage("Cooldowns") local L = TSM.Include("Locale").GetTable() local Delay = TSM.Include("Util.Delay") local ObjectPool = TSM.Include("Util.ObjectPool") local Table = TSM.Include("Util.Table") local String = TSM.Include("Util.String") local private = { query = nil, taskPool = ObjectPool.New("COOLDOWN_TASK", TSM.TaskList.CooldownCraftingTask, 0), activeTasks = {}, activeTaskByProfession = {}, ignoredQuery = nil, -- luacheck: ignore 1004 - just stored for GC reasons } -- ============================================================================ -- Module Functions -- ============================================================================ function Cooldowns.OnEnable() TSM.TaskList.RegisterTaskPool(private.ActiveTaskIterator) private.query = TSM.Crafting.CreateCooldownSpellsQuery() :Select("profession", "spellId") :Custom(private.QueryPlayerFilter, UnitName("player")) :SetUpdateCallback(private.PopulateTasks) private.ignoredQuery = TSM.Crafting.CreateIgnoredCooldownQuery() :SetUpdateCallback(private.PopulateTasks) private.PopulateTasks() end -- ============================================================================ -- Private Helper Functions -- ============================================================================ function private.ActiveTaskIterator() return ipairs(private.activeTasks) end function private.QueryPlayerFilter(row, player) return String.SeparatedContains(row:GetField("players"), ",", player) end function private.PopulateTasks() -- clean DB entries with expired times for spellId, expireTime in pairs(TSM.db.char.internalData.craftingCooldowns) do if expireTime <= time() then TSM.db.char.internalData.craftingCooldowns[spellId] = nil end end -- clear out the existing tasks for _, task in pairs(private.activeTaskByProfession) do task:WipeSpellIds() end local minPendingCooldown = math.huge for _, profession, spellId in private.query:Iterator() do if TSM.Crafting.IsCooldownIgnored(spellId) then -- this is ignored elseif TSM.db.char.internalData.craftingCooldowns[spellId] then -- this is on CD minPendingCooldown = min(minPendingCooldown, TSM.db.char.internalData.craftingCooldowns[spellId] - time()) else -- this is a new CD task local task = private.activeTaskByProfession[profession] if not task then task = private.taskPool:Get() task:Acquire(private.RemoveTask, L["Cooldowns"], profession) private.activeTaskByProfession[profession] = task end if not task:HasSpellId(spellId) then task:AddSpellId(spellId, 1) end end end -- update our tasks wipe(private.activeTasks) for profession, task in pairs(private.activeTaskByProfession) do if task:HasSpellIds() then tinsert(private.activeTasks, task) task:Update() else private.activeTaskByProfession[profession] = nil task:Release() private.taskPool:Recycle(task) end end TSM.TaskList.OnTaskUpdated() if minPendingCooldown ~= math.huge then Delay.AfterTime("COOLDOWN_UPDATE", minPendingCooldown, private.PopulateTasks) else Delay.Cancel("COOLDOWN_UPDATE") end end function private.RemoveTask(task) local profession = task:GetProfession() assert(Table.RemoveByValue(private.activeTasks, task) == 1) assert(private.activeTaskByProfession[profession] == task) private.activeTaskByProfession[profession] = nil task:Release() private.taskPool:Recycle(task) TSM.TaskList.OnTaskUpdated() end