WoWInterface

WoWInterface (https://www.wowinterface.com/forums/index.php)
-   oUF (Otravi Unit Frames) (https://www.wowinterface.com/forums/forumdisplay.php?f=87)
-   -   Script ran too long (https://www.wowinterface.com/forums/showthread.php?t=52066)

sticklord 03-09-15 01:09 PM

Script ran too long
 
Hello!

I'm looking for some help regarding a script ran too long error. It's a module based off PortraitTimers (basically show an aura icon if the unit has a whitelisted aura on them). I'm pretty sure it's the function SetPortraitToTexture() that triggers this error, and it's been bugging me for a while. Anyone got any idea to how i can fix this?

Here's a link to the code I use: link

Appreciate any input.

Phanx 03-10-15 12:56 AM

Well, assuming that's what's causing the problem, it's likely only doing so because you're calling it potentially hundreds of times per second in combat, in response to UNIT_AURA (multiply that by the number of units you use this element on). You should keep track of whether the timer is already running, and if so, just return out if the buff is still active.

There are also some questionable bits in your code; for example:
Code:

                local UnitDebuff, index = UnitDebuff, 0
                while (true) do
                        index = index + 1
                        local name, _, icon, _, _, duration, expirationTime, _, _, _, spellId = (UnitDebuff or UnitBuff)(unit, index)

For one, I'd either upvalue UnitDebuff outside of your event handler, or don't bother upvaluing at all. For two, this code can never fall back to using UnitBuff, so you should probably get rid of that, or fix the rest of the code if it's supposed to use UnitBuff under some circumstances.
Code:

                                UnitDebuff = nil
                                index = 0

You don't need to manually un-set your (local) variables in Lua; they're automatically garbage-collected once they go out of scope.

I'd rewrite that update function like so:
Code:

local UnitDebuff = UnitDebuff

local Update = function(self, event, unit)
        if (self.unit ~= unit) then
                return
        end
        local pt = self.PortraitTimer
        local showing = pt:IsShown()
        for index = 1, 40 do
                local name, _, icon, _, _, duration, expirationTime, _, _, _, spellId = UnitDebuff(unit, index)
                if not name then
                        break
                end
                if PortraitTimerDB[spellId] then
                        if not showing then
                                UpdateIcon(pt, icon, duration, expirationTime)
                                pt:Show()
                                if self.CombatFeedbackText then
                                        self.CombatFeedbackText.maxAlpha = 0
                                end
                        end
                        return
                end
        end
        if showing then
                pt:Hide()
        end
        if self.CombatFeedbackText then
                self.CombatFeedbackText.maxAlpha = 1
        end
end


sticklord 03-11-15 04:32 PM

Quote:

Originally Posted by Phanx (Post 307440)
Well, assuming that's what's causing the problem, it's likely only doing so because you're calling it potentially hundreds of times per second in combat, in response to UNIT_AURA (multiply that by the number of units you use this element on). You should keep track of whether the timer is already running, and if so, just return out if the buff is still active.

Thanks for the tip, I'll try to add a check for the texture and duration so it hopefully will happen alot less frequently.

For the other bits it works with UnitBuff aswell, this:
Lua Code:
  1. UnitDebuff = nil
  2. index = 0
resets the counter and sets the local UnitDebuff to nil. So it then checks for Buffs after Debuffs. It's abit hard to read though, one day i might make it nicer:)

jeruku 03-11-15 07:47 PM

Quote:

Originally Posted by Phanx (Post 307440)
...
There are also some questionable bits in your code; for example:
Code:

                local UnitDebuff, index = UnitDebuff, 0
                while (true) do
                        index = index + 1
                        local name, _, icon, _, _, duration, expirationTime, _, _, _, spellId = (UnitDebuff or UnitBuff)(unit, index)

For one, I'd either upvalue UnitDebuff outside of your event handler, or don't bother upvaluing at all. For two, this code can never fall back to using UnitBuff, so you should probably get rid of that, or fix the rest of the code if it's supposed to use UnitBuff under some circumstances.
Code:

                                UnitDebuff = nil
                                index = 0

You don't need to manually un-set your (local) variables in Lua; they're automatically garbage-collected once they go out of scope.
...

I was thinking the same thing until I realized it scans debuffs before buffs.
It will loop through all debuffs then UnitDebuff becomes nil. Then it iterates over all buffs because it no longer uses UnitDebuff since now it is (nil or UnitBuff). Once it finishes with buffs it breaks out of the while loop. And all that explains why UnitDebuff is made local.


All times are GMT -6. The time now is 09:04 AM.

vBulletin © 2020, Jelsoft Enterprises Ltd
© 2004 - 2020 MMOUI