Thread: oUF_AuraBars
View Single Post
09-14-12, 06:05 PM   #2
Phanx
Cat.
 
Phanx's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2006
Posts: 5,617
This is the problem:
Code:
oUF:AddElement('AuraBars', UpdateBuff, UpdateDebuff, EnableBuff, EnableDebuff, DisableBuff, DisableDeuff)
AddElement only accepts four arguments: (1) the element name, (2) the update function, (3) the enable function, and (4) the disable function. You can't register multiple elements in one AddElement call, or change the order of the arguments.

(Also, "DisableDeuff" is misspelled.)

If you want separate elements for buffs and debuffs, you need to add them separately:
Code:
oUF:AddElement('AuraBarsBuff', UpdateBuff, EnableBuff, DisableBuff)
oUF:AddElement('AuraBarsDebuff', UpdateDebuff, EnableDebuff, DisableDebuff)
Also, I'd suggest using the names "BuffBars" and "DebuffBars" instead of "AuraBarsBuff" and "AuraBarsDebuff"; they're shorter, and more descriptive.

Also, a lot of that code is really inefficient; I'm not sure whether that was in the original module, or part of your changes. Creating 2-82 tables every time the unit's auras change (1-41 in each UpdateBuff and UpdateDebuff) is basically a memory leak, and your module will consume memory like a horde of kids in a candy store. Reuse tables as much as possible, instead of simply discarding them and creating new ones.

Consistent indentation, and separating blocks with empty lines, will also help the code be more readable.

Compare your UpdateDebuff function with:
Code:
local debuffs = {} -- Only create one table, and reuse it.

local function UpdateDebuff(self, event, unit)
	if self.unit ~= unit then return end

	local auraBarsDebuff = self.AuraBarsDebuff

	local numDebuffs = 0
	for index = 1, 40 do
		local name, rank, icon, count, debuffType, duration, expirationTime, unitCaster, isStealable, shouldConsolidate, spellID = UnitDebuff(unit, index)
		if not name then break end
		if auraBarsDebuff.filter(self, unit, name, rank, icon, count, debuffType, duration, expirationTime, unitCaster, isStealable, shouldConsolidate, spellID) then
			local t = debuffs[i] or {} -- Reuse tables where possible.
			t.name = name
			t.rank = rank
			t.icon = icon
			t.count = count
			t.debuffType = debuffType
			t.duration = duration
			t.expirationTime = expirationTime
			t.unitCaster = unitCaster
			t.isStealable = isStealable
			t.noTime = duration == 0 and expirationTime == 0
			t.filter = auraBarsDebuff.enemyAuraType
			t.shouldConsolidate = shouldConsolidate
			t.spellID = spellID
			debuffs[i] = t
			numDebuffs = i
		end
	end

	-- Clear unused debuff slots.
	for i = numDebuffs + 1, #debuffs do
		debuffs[i] = nil
		-- wipe(debuffs[i]) would be better, but then you would need to either:
		-- (a) accomodate empty tables in your sort function, putting them at the end,
		-- or (b) introduce a table pool and recycling scheme.
	end

	if auraBarsDebuff.sort then
		table.sort(debuffs, type(auraBarsDebuff.sort) == 'function' and auraBarsDebuff.sort or nil) -- no need to pass the global "sort"
	end

	local bars = auraBarsDebuff.bars
	for index = 1, #debuffs do
		if auraBarsDebuff:GetWidth() == 0 then
			break
		end

		local frame = bars[index]
		if not frame then
			frame = CreateAuraBar(self, index == 1 and auraBarsDebuff or bars[index - 1])
			bars[index] = frame
		end

		local bar = frame.statusBar
		frame.index = index

		local aura = debuffs[index]
		bar.aura = aura

		if aura.noTime then -- you already have a local aura, no need to spend an extra table lookup getting it out of bar.aura
			bar:SetMinMaxValues(0, 1)
			bar:SetValue(1)
		else
			if auraBarsDebuff.scaleTime then
				local maxvalue = math.min(auraBarsDebuff.scaleTime, bar.aura.duration)
				bar:SetMinMaxValues(0, maxvalue)
				bar:SetWidth((maxvalue/auraBarsDebuff.scaleTime)*((auraBarsDebuff.auraBarWidth or auraBarsDebuff:GetWidth())-(bar:GetHeight()+(auraBarsDebuff.gap or 0))))-- icon size + gap
			else
				bar:SetMinMaxValues(0, aura.duration)
			end
			bar:SetValue(aura.expirationTime - GetTime())
		end

		bar.icon:SetTexture(aura.icon)

		bar.spellname:SetText(aura.count > 1 and string.format("%s [%d]", bar.aura.name, aura.count) or aura.name)
		bar.spelltime:SetText(not bar.noTime and FormatTime(aura.expirationTime-GetTime()))

		local debuffType = aura.debuffType or 'none'
		r, g, b = DebuffTypeColor[debuffType].r, DebuffTypeColor[debuffType].g, DebuffTypeColor[debuffType].b
		if auraBarsDebuff.debuffColor then
			r, g, b = unpack(auraBarsDebuff.debuffColor)
		end
		bar:SetStatusBarColor(r, g, b)

		frame:Show()
	end

	for index = #auras + 1, #bars do
		bars[index]:Hide()
	end

	if auraBarsDebuff.PostUpdate then
		auraBarsDebuff:PostUpdate(event, unit)
	end
end
(Might be some drycoded errors in there; I didn't load it in-game.)
__________________
Retired author of too many addons.
Message me if you're interested in taking over one of my addons.
Don’t message me about addon bugs or programming questions.

Last edited by Phanx : 09-14-12 at 06:29 PM.
  Reply With Quote