Thread Tools Display Modes
03-09-15, 01:09 PM   #1
sticklord
A Wyrmkin Dreamwalker
AddOn Author - Click to view addons
Join Date: Aug 2014
Posts: 57
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.
  Reply With Quote
03-10-15, 12:56 AM   #2
Phanx
Cat.
 
Phanx's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2006
Posts: 5,617
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
__________________
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.
  Reply With Quote
03-11-15, 04:32 PM   #3
sticklord
A Wyrmkin Dreamwalker
AddOn Author - Click to view addons
Join Date: Aug 2014
Posts: 57
Originally Posted by Phanx View Post
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
  Reply With Quote
03-11-15, 07:47 PM   #4
jeruku
A Cobalt Mageweaver
 
jeruku's Avatar
AddOn Author - Click to view addons
Join Date: Oct 2010
Posts: 223
Originally Posted by Phanx View Post
...
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.
__________________
"I have not failed, I simply found 10,000 ways that did not work." - Thomas Edison
  Reply With Quote

WoWInterface » Featured Projects » oUF (Otravi Unit Frames) » Script ran too long

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off