|
09-14-12, 04:48 PM | #1 |
oUF_AuraBars
So I tried modifying/adding some code to this plug in. Essentially I'd like 4 aura blocks, player buffs, player debuffs, target buffs, target debuffs.
It seemed to me there was no easy way to separate buff from debuff other than to write a separate function that only chose buffs, and alter the current function to only choose debuffs. The following is the code that I came up with: http://pastebin.com/V0uFmRGD Code:
Message: Interface\AddOns\oUF_AuraBars\oUF_AuraBars.lua:271: Usage: UnitDebuff("unit", [index] or ["name", "rank"][, "filter"]) Time: 09/14/12 18:46:54 Count: 1 Stack: [C]: ? [C]: ? Interface\FrameXML\RestrictedFrames.lua:604: in function <Interface\FrameXML\RestrictedFrames.lua:603> Interface\FrameXML\RestrictedFrames.lua:742: in function `CallMethod' [string " local header = self:GetParent()..."]:44: in function <[string " local header = self:GetParent()..."]:1> (tail call): ? [C]: ? Interface\FrameXML\RestrictedExecution.lua:441: in function <Interface\FrameXML\RestrictedExecution.lua:412> Interface\FrameXML\SecureGroupHeaders.lua:108: in function <Interface\FrameXML\SecureGroupHeaders.lua:102> Interface\FrameXML\SecureGroupHeaders.lua:158: in function <Interface\FrameXML\SecureGroupHeaders.lua:115> Interface\FrameXML\SecureGroupHeaders.lua:393: in function <Interface\FrameXML\SecureGroupHeaders.lua:382> [C]: in function `Show' Interface\FrameXML\SecureStateDriver.lua:100: in function <Interface\FrameXML\SecureStateDriver.lua:95> Interface\FrameXML\SecureStateDriver.lua:164: in function <Interface\FrameXML\SecureStateDriver.lua:146> [C]: in function `SetAttribute' Interface\FrameXML\SecureStateDriver.lua:11: in function `RegisterAttributeDriver' Interface\AddOns\oUF\ouf.lua:411: in function `SpawnHeader' Interface\AddOns\oUF_Skaarj\layout.lua:442: in function `func' Interface\AddOns\oUF\factory.lua:13: in function <Interface\AddOns\oUF\factory.lua:10> (tail call): ? Locals: <none> |
|
09-14-12, 06:05 PM | #2 |
This is the problem:
Code:
oUF:AddElement('AuraBars', UpdateBuff, UpdateDebuff, EnableBuff, EnableDebuff, DisableBuff, DisableDeuff) (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, 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
__________________
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. |
|
09-15-12, 10:33 AM | #3 |
First off, thank you for taking the time to fix and optimize my code that you'll never use. That's pretty awesome.
Secondly, I put your suggested code in, but I'm getting this pretty frustrating error. I can't seem to put my finger on what causes it. Sometimes I don't get it for a few minutes, sometimes it's as I start attacking something. Code:
Message: Interface\AddOns\oUF_AuraBars\oUF_AuraBars.lua:331: attempt to index local 'aura' (a nil value) Time: 09/15/12 19:54:32 Count: 31 Stack: Interface\AddOns\oUF_AuraBars\oUF_AuraBars.lua:331: in function `func' Interface\AddOns\oUF\events.lua:14: in function <Interface\AddOns\oUF\events.lua:12> (tail call): ? Code:
Message: Interface\AddOns\oUF_AuraBars\oUF_AuraBars.lua:331: attempt to index local 'aura' (a nil value) Time: 09/15/12 19:54:29 Count: 2 Stack: Interface\AddOns\oUF_AuraBars\oUF_AuraBars.lua:331: in function `func' Interface\AddOns\oUF\ouf.lua:117: in function <Interface\AddOns\oUF\ouf.lua:110> (tail call): ? [C]: in function `Show' Interface\FrameXML\SecureStateDriver.lua:83: in function <Interface\FrameXML\SecureStateDriver.lua:73> Interface\FrameXML\SecureStateDriver.lua:137: in function <Interface\FrameXML\SecureStateDriver.lua:119> Code:
Message: Interface\AddOns\oUF_AuraBars\oUF_AuraBars.lua:331: attempt to index local 'aura' (a nil value) Time: 09/15/12 19:55:42 Count: 1 Stack: Interface\AddOns\oUF_AuraBars\oUF_AuraBars.lua:331: in function `func' Interface\AddOns\oUF\ouf.lua:117: in function <Interface\AddOns\oUF\ouf.lua:110> (tail call): ? [C]: in function `CameraOrSelectOrMoveStop' [string "CAMERAORSELECTORMOVE"]:4: in function <[string "CAMERAORSELECTORMOVE"]:1> Code:
Message: Interface\AddOns\oUF_AuraBars\oUF_AuraBars.lua:163: attempt to index field 'aura' (a nil value) Time: 09/15/12 19:55:48 Count: 306 Stack: Interface\AddOns\oUF_AuraBars\oUF_AuraBars.lua:163: in function <Interface\AddOns\oUF_AuraBars\oUF_AuraBars.lua:150> http://pastebin.com/SK47CrRG Last edited by sirann : 09-15-12 at 05:58 PM. |
|
09-16-12, 01:27 AM | #4 |
Oh, I think I see what the problem is. Try this:
Code:
local debuffs = {} local function UpdateDebuff(self, event, unit) if self.unit ~= unit then return end local DebuffBars = self.DebuffBars local numDebuffs = 0 for i = 1, 40 do local name, rank, icon, count, debuffType, duration, expirationTime, unitCaster, isStealable, shouldConsolidate, spellID = UnitDebuff(unit, i) if not name then break end if DebuffBars.filter(self, unit, name, rank, icon, count, debuffType, duration, expirationTime, unitCaster, isStealable, shouldConsolidate, spellID) then numDebuffs = numDebuffs + 1 local t = debuffs[numDebuffs] if not t then t = table_create() debuffs[numDebuffs] = t end 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 = DebuffBars.enemyAuraType t.shouldConsolidate = shouldConsolidate t.spellID = spellID end end for i = #debuffs, numDebuffs + 1, -1 do debuffs[i] = table_delete(debuffs[i]) end table.sort(debuffs, DebuffBars.sort or default_sort) local bars = DebuffBars.bars for i = 1, numDebuffs do if DebuffBars:GetWidth() == 0 then break end local bar = bars[i] if not bar then bar = CreateAuraBar(self, i == 1 and DebuffBars or bars[i - 1]) bars[i] = bar end bar:Show() local statusbar = bar.statusBar local debuff = debuffs[i] bar.aura = debuff if debuff.noTime then -- something weird here statusbar:SetMinMaxValues(0, 1) statusbar:SetValue(1) else if DebuffBars.scaleTime then local maxvalue = math.min(DebuffBars.scaleTime, debuff.duration) statusbar:SetMinMaxValues(0, maxvalue) statusbar:SetWidth((maxvalue/DebuffBars.scaleTime)*((DebuffBars.auraBarWidth or DebuffBars:GetWidth())-(statusbar:GetHeight()+(DebuffBars.gap or 0))))-- icon size + gap else statusbar:SetMinMaxValues(0, debuff.duration) end statusbar:SetValue(debuff.expirationTime - GetTime()) end statusbar.icon:SetTexture(debuff.icon) statusbar.spellname:SetText(debuff.count > 1 and format("%s [%d]", debuff.name, debuff.count) or debuff.name) statusbar.spelltime:SetText(not debuff.noTime and FormatTime(debuff.expirationTime - GetTime())) local r, g, b local color = DebuffBars.debuffColor if color then r, g, b = color[1], color[2], color[3] -- don't use unpack; 3 table lookups is faster than 1 function call else color = DebuffTypeColor[debuff.debuffType or "none"] r, g, b = color.r, color.g, color.b end statusbar:SetStatusBarColor(r, g, b) end for i = numDebuffs + 1, #bars do local bar = bars[i] bar.aura = table_delete(bar.aura) bar:Hide() end end Code:
local table_create, table_delete do local pool = { } local function table_create() local t = next(pool) if t then pool[t] = nil end return t or {} end local function table_delete(t) if type(t) == "table" then for k, v in pairs(t) do t[k] = nil end t[true] = true t[true] = nil pool[t] = true end return nil end end local default_sort = function(a, b) if a.noTime then if b.noTime then -- both timeless, sort by name REVERSE return a.name < b.name else -- a timeless, b not return true end else if b.noTime then -- b timeless, a not return false else -- neither timeless, sort by expiry time return a.expires > b.expires end end end
__________________
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-16-12 at 10:33 PM. |
|
09-16-12, 11:34 AM | #5 |
Relevant section(s) can be found here:
http://pastebin.com/53q2b56C targeting friendly or non-friendly throws this error: Message: Interface\AddOns\oUF_AuraBars\oUF_AuraBars.lua:257: attempt to call upvalue 'table_create' (a nil value) |
|
09-16-12, 10:33 PM | #6 |
Code:
local pool = { } local function table_new()
__________________
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. |
|
07-29-18, 06:08 PM | #7 |
Nope, sorry.
__________________
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. |
|
WoWInterface » Featured Projects » oUF (Otravi Unit Frames) » oUF_AuraBars |
«
Previous Thread
|
Next Thread
»
|
Display Modes |
Switch to Linear Mode |
Hybrid Mode |
Switch to Threaded Mode |
|
|