У меня есть аддон, по аналогии с interruptbar, и у него есть небольшой косяк, работает все корректно проблема чисто визуальная, после того как аддон отработал на арене при выходе с неё иконка кулдауна не пропадает с экрана и держится на следующих аренах даже если на них нету класса с этим кулдауном, можно что то дописать в коде что бы аддон самоочищался после выхода с арены?
PHP код:
local options = {
    
name "InterruptIcons Options",
    
type "group",
    
args = {
        
locked = {
            
name "Lock Frame",
            
desc "Toggle locking the frame.",
            
type "toggle",
            
get = function() return InterruptIconsDB.locked end,
            
set = function() 
                
InterruptIconsDB.locked not InterruptIconsDB.locked or false
                InterruptIcons
:UpdateIcons()
            
end,
        },
        
hidden = {
            
name "Hide Icons until active",
            --
desc "Hide icons until active.",
            
type "toggle",
            
get = function() return InterruptIconsDB.hidden end,
            
set = function()
                
wipe(InterruptIcons.activeIcons)
                
InterruptIconsDB.hidden not InterruptIconsDB.hidden or false
                InterruptIcons
:UpdateIcons()
            
end,
        },
        
size = {
            
name "Icon Size",
            
desc "Set the size of the icons.",
            
type "range",
            
min 16,
            
max 64,
            
step 1,
            
get = function() return InterruptIconsDB.size end,
            
set = function(_value)
                
InterruptIconsDB.size value
                InterruptIcons
:UpdateIcons()
            
end,
        },
        
spacing = {
            
name "Icon Spacing",
            
desc "Set the spacing between the icons.",
            
type "range",
            
min 0,
            
max 20,
            
step 1,
            
get = function() return InterruptIconsDB.spacing end,
            
set = function(_value)
                
InterruptIconsDB.spacing value
                InterruptIcons
:UpdateIcons()
            
end,
        },
        
iconsPerRow = {
            
name "Icons Per Row",
            
desc "Set the number of icons per row.",
            
type "range",
            
min 1,
            
max 20,
            
step 1,
            
get = function() return InterruptIconsDB.iconsPerRow end,
            
set = function(_value)
                
InterruptIconsDB.iconsPerRow value
                InterruptIcons
:UpdateIcons()
            
end,
        },
        
fixedIcons = {
            
name "Fixed Icons",
            
desc "Toggle static icon positions",
            
type "toggle",
            
get = function() return InterruptIconsDB.fixedIcons end,
            
set = function()
                
wipe(InterruptIcons.activeIcons)
                
InterruptIconsDB.fixedIcons not InterruptIconsDB.fixedIcons or false
                InterruptIcons
:UpdateIcons()
            
end,
        }
    },
}

LibStub("AceConfig-3.0"):RegisterOptionsTable("InterruptIcons"options
PHP код:
InterruptIcons LibStub("AceAddon-3.0"):NewAddon("InterruptIcons""AceEvent-3.0")

local defaults = {
    [
"size"] = 32,
    [
"spacing"] = 0,
    [
"iconsPerRow"] = 20,
    [
"locked"] = false,
    [
"hidden"] = true,
    [
"position"] = {
        
"CENTER",
        
nil,
        
"CENTER",
        
0,
        
0,
    },
    [
"fixedIcons"] = true
}

InterruptIcons.anchor CreateFrame("Frame"nilUIParent)
InterruptIcons.anchor:SetWidth(32)
InterruptIcons.anchor:SetHeight(32)
InterruptIcons.anchor:SetMovable(true)

InterruptIcons.icons = {}
function 
InterruptIcons:OnInitialize()
    -- 
Register our SavedVariables.
    
self.db InterruptIconsDB or LibStub("AceDB-3.0"):New("InterruptIconsDB")
    -- 
Populate empty SV values.
    for 
keyoption in pairs(defaults) do
        if 
type(InterruptIconsDB[key]) == "nil" then
            InterruptIconsDB
[key] = option
        end
    end
    
    
-- Register our slash commands and interface options.
    
InterruptIcons.optionsFrame LibStub("AceConfigDialog-3.0"):AddToBlizOptions("InterruptIcons""InterruptIcons")
    
SlashCmdList["INTERRUPTICONS"] = function() InterfaceOptionsFrame_OpenToCategory("InterruptIcons"end
    SLASH_INTERRUPTICONS1 
"/interrupticons"
    
SLASH_INTERRUPTICONS2 "/ii"

    
-- Position the anchor frame
    self
.anchor:SetPoint(self.db.position[1], UIParentself.db.position[3], self.db.position[4], self.db.position[5])
    
    for 
keyspell in pairs(InterruptIconsSpellDB) do
        -- 
Insert our icon textures into the SpellDB.
        
spell.icon select(3GetSpellInfo(key))
        
        -- 
Create our iconstexture, and cooldown frames.
        
local frame CreateFrame("Frame"nilself.anchor)
        
frame:SetWidth(self.db.size)
        
frame:SetHeight(self.db.size)
        
frame:SetPoint("CENTER")
        
        
local icon frame:CreateTexture(nil"BACKGROUND")
        
icon:SetAllPoints()
        
icon:SetTexture(spell.icon)
        
icon:SetTexCoord(.07.9.07.9)
        
icon:SetDesaturated(spell.isBuff) -- Turn inactive buffs greyscale.
        
        
local cd CreateFrame("Cooldown"nilframe)
        
cd:SetAllPoints()
        
        
frame.icon icon
        frame
.cd cd
        frame
.class = spell.class
        
frame.spellid key
        frame
.isBuff spell.isBuff
        
if spell.isBuff then
            frame
.isActive false
        end
        
        tinsert
(self.iconsframe)
    
end
    self
.activeCooldowns = {}
    
self.activeIcons = {}
    
    -- 
Sort our icons alphabetically by class nameThere's no reason to do this specifically in alphabetical order...
    -- We only do it this way so that spells are grouped by class in the icon list, while using a minimal amount of code.
    table.sort(self.icons, function(a, b)
        return a.class < b.class
    end)
    -- Our AceConfig options doesn'
t update our .locked value when we log inUpdateIcons() is called here in order to force it to update.
    
self:UpdateIcons()
end

local OnUpdateFrame 
CreateFrame("Frame")
OnUpdateFrame:Hide()
function 
InterruptIcons:UpdateIcons()
    for 
keyicon in pairs(self.icons) do
        -- 
Update the icon size.
        
icon:SetWidth(self.db.size)
        
icon:SetHeight(self.db.size)
        
        -- 
Update our frame's locked status
        if self.db.locked then
            icon:EnableMouse(false)
        else
            icon:EnableMouse(true)
            icon:SetScript("OnMouseDown", function()
                self.anchor:StartMoving()
            end)
            icon:SetScript("OnMouseUp", function()
                self.anchor:StopMovingOrSizing()
                self.db.position = {self.anchor:GetPoint()}
            end)
        end
        
        -- Hide icons until active?
        if self.db.hidden then
            OnUpdateFrame:Show()
            if not self.activeCooldowns[icon.spellid] then
                icon:Hide()
            else
                icon:Show()
            end
        else
            OnUpdateFrame:Hide()
            icon:Show()
        end
        
        if icon:IsShown() then
            tinsert(self.activeIcons, icon)
        end
    end
    
    local curIcons = self.db.fixedIcons and self.icons or self.activeIcons
    for key, icon in pairs(curIcons) do
        -- Re-draw our icons.
        -- Code credit Dominos by Tuller. Thank you for saving me a lot of frustration...
        local numIcons = #curIcons
        local cols = min(self.db.iconsPerRow, numIcons)
        local rows = ceil(numIcons / cols)
        
        local spacing = self.db.spacing    
        local pad = self.db.size + self.db.spacing
        
        local col = (key-1) % cols
        local row = ceil(key / cols) - 1
        
        icon:SetPoint("LEFT", self.anchor, "LEFT", pad * col, -(pad * row))
    end
end

local last, throttle = 0, .5
OnUpdateFrame:SetScript("OnUpdate", function(self, elapsed)
    last = last + elapsed
    if last > throttle then
        for key, icon in pairs(InterruptIcons.activeCooldowns) do
            if not icon.start or not icon.cooldown then return end
            if (icon.start + icon.cooldown - GetTime()) <= 0 then
                if icon.isBuff then
                    if not icon.isActive then
                        InterruptIcons.activeCooldowns[key] = nil
                        InterruptIcons:UpdateIcons()
                    end
                else
                    InterruptIcons.activeCooldowns[key] = nil
                    InterruptIcons:UpdateIcons()
                end
                --[[
                for key2, icon2 in pairs(InterruptIcons.activeIcons) do
                    if InterruptIcons:FindIcon(key) == icon2 then
                        InterruptIcons.activeIcons[key2] = nil
                        InterruptIcons:UpdateIcons()
                    end
                end
                --]]
            end
        end
        last = 0
    end
end)

function InterruptIcons:FindIcon(spellId)
    for key, icon in pairs(self.icons) do
        if icon.spellid == spellId then
            return icon
        end
    end
    return
end

function InterruptIcons:UpdateCooldown(spellId)
    local spells = InterruptIconsSpellDB
    if spells[spellId] then 
        local icon = self:FindIcon(spellId)
        icon.cd:SetCooldown(GetTime() - .4, spells[spellId].cooldown)

        icon.start = GetTime()
        icon.cooldown = spells[spellId].cooldown
        tinsert(self.activeCooldowns, spellId, icon)

        -- Color our former-greyscale buffs when they become active.
        if icon.isBuff then
            icon.icon:SetDesaturated(false)
            icon.isActive = true
        end
        
        -- Sloppy shared cooldown code. :)
        if spellId == 49367 then -- Feral Charge - Cat
            icon = self:FindIcon(16979)
            icon.cd:SetCooldown(GetTime() - .4, 15)
        elseif spellId == 16979 then -- Feral Charge - Bear
            icon = self:FindIcon(49376)
            icon.cd:SetCooldown(GetTime() - .4, 15)
        elseif spellId == 6552 then -- Pummel
            icon = self:FindIcon(72)
            icon.cd:SetCooldown(GetTime() - .4, 10)
        elseif spellId == 72 then -- Shield Bash
            icon = self:FindIcon(6552)
            icon.cd:SetCooldown(GetTime() - .4, 10)
        --[[ Testing purposes.
        elseif spellId == 31224 then -- CloS
            icon = self:FindIcon(1766)
            icon.cd:SetCooldown(GetTime() - .4, 10)
            
            tinsert(self.activeCooldowns, icon)
        elseif spellId == 1766 then -- Kick
            icon = self:FindIcon(31224)
            icon.cd:SetCooldown(GetTime() - .4, 10)
            
            tinsert(self.activeCooldowns, icon)
        --]]
        end
        
        self:UpdateIcons()
    end
end

function InterruptIcons:COMBAT_LOG_EVENT_UNFILTERED(event, ...)
    local e, sourceFlags = select(2, ...), select(5, ...)
    
    -- If the event trigger isn'
t from an enemy unit don't proceed.
    if bit.band(sourceFlags, COMBATLOG_OBJECT_REACTION_HOSTILE) == COMBATLOG_OBJECT_REACTION_HOSTILE then
        local spells = InterruptIconsSpellDB
        if e == "SPELL_CAST_SUCCESS" then
            local spellId = select(9, ...)
            self:UpdateCooldown(spellId)
        elseif e == "SPELL_AURA_APPLIED" or e == "SPELL_AURA_REFRESH" then
            local spellId = select(9, ...)
            self:UpdateCooldown(spellId)
        elseif e == "SPELL_AURA_REMOVED" then
            local spellId = select(9, ...)
            if InterruptIconsSpellDB[spellId] then
                local icon = self:FindIcon(spellId)
                
                -- Set inactive buffs to greyscale.
                icon.icon:SetDesaturated(true)
                icon.isActive = false
            end
        end
    end
end
InterruptIcons:RegisterEvent("COMBAT_LOG_EVENT_UNFILTERED")