• 0

    posted a message on Newbie tip for OnUpdate performance
    Thanks! I raid gain tonight so I'll get a chance to compare to last raid.
    Posted in: Lua Code Discussion
  • 0

    posted a message on Newbie tip for OnUpdate performance
    I don't claim to know which method is "better" (throttle OnUpdate or use Animations). But I do know that I update my bar widths and duration text every 0.1 seconds. This would mean I'd need to replay a timer every 0.1 seconds. That's a little bit concerning, and it's not the pattern I see most addons using. It's either that or throttle the OnUpdate on an animation like Alakabaster is talking about, which would seem to defeat the purpose, no?

    As it stands now, I am able to use UNIT_AURA events to decide whether I need to set or unset an OnUpdate function.

    I understand that the Blizz animations are handled in C code but it doesn't seem like the appropriate tool in my scenario. I've not tried it though.

    Incidentally, in regard to updating the width of the bar, I did implement one improvement that was noticeable:

    function FullThrottle:RefreshActiveAnimations(bar)
        ...
        local duration = group.Expiration - GetTime()
        local width = (duration / group.FullDuration) * bar.width
        if(ceil(bar.texture:GetWidth()) ~= ceil(width)) then
            bar.texture:SetWidth(width)
        end
        ...
    end
    


    Essentially, it's always comparing whole numbers and therefore only changes if the number went from say 250 to 249. For very large values of duration, this means the texture only changes widths every 20 seconds or so.

    As opposed to...

    function FullThrottle:RefreshActiveAnimations(bar)
        ...
        local duration = group.Expiration - GetTime()
        local width = (duration / group.FullDuration) * db.Width
        bar.texture:SetWidth(width)
        ...
    end
    


    Where the numbers will be more like 250.0043123 and 249.999234

    Or even less obvious, but the same problem...

    function FullThrottle:RefreshActiveAnimations(bar)
        ...
        local duration = group.Expiration - GetTime()
        local width = (duration / group.FullDuration) * db.Width
        if(bar.texture:GetWidth() ~= width) then
            bar.texture:SetWidth(width)
        end
    
        ...
    end
    


    In the last case, width will never equal bar.texture:GetWidth() because they're both floating numbers, so it's a wasted check.

    I added similar "only if changed" checks for SetText() of the timer text but the differences weren't as apparent as the texture width checks.
    Posted in: Lua Code Discussion
  • 0

    posted a message on Newbie tip for OnUpdate performance
    I used the term "animation" loosely. Blizz's animation doesn't have an object for changing the width of something, only scale, alpha, position, and I think one more. In my case, I need to countdown a text value and change the width of a texture, neither of which can be controlled with regular events such as UNIT_AURA, etc.

    Are there other tools for this I should be looking at?
    Posted in: Lua Code Discussion
  • 0

    posted a message on Newbie tip for OnUpdate performance
    Remove your OnUpdate handler when you don't need it

    I'm extremely new to WoW addons and Lua. Coming from an OO background I've made all the mistakes someone like myself is probably expected to make. Especially in how I use tables.

    Recently I started to tackle what I felt was excessive CPU usage for a relatively simple addon (FullThrottle)

    I've read all the threads I could find during this process. Here were some useful ones to list a few:

    http://forums.wowace.com/showthread.php?t=18163
    http://old.wowace.com/wiki/Coding_Tips#Function_syntactical_sugar
    http://forums.wowace.com/showthread.php?t=17301

    It was easy for me to get caught up in the notion that my use of tables, strings, globals, etc. was where I needed to optimize. Truth be told, Lua is pretty damn well optimized on it's own. I gained very little (hardly measurable with the tools I was using) trying to optimize my code using the kinds of techniques in those threads.


    My addon has bars with textures that change width based on the time left on a spell. I also have text values that change. A bar is essentially either active (texture width and font is changing) or it's not. Besides throttling the OnUpdate handler, I also tried to be smart and check right away if I even needed to do any changes to the bar. But I was still handling OnUpdate.

    As soon as I changed my code so that when a bar is not active I unregister the OnUpdate script, I saved ~40% CPU usage.

    I'm simplifying what I had to do quite a bit, but that's essentially what was done.

    Just because you sometimes need to do some sort of animation, doesn't mean you ALWAYS need to be running OnUpdate code. Even a throttled down OnUpdate handler is consuming resources.

    That's all I got :)

    Also, thanks to everyone here for all the great historical posts and for helping people like me. This is a lot of fun!
    Posted in: Lua Code Discussion
  • 0

    posted a message on FullThrottle - Quick buff/debuff status
    Thanks! Being the first addon I've ever made (and new to Lua and everything else here) I was perhaps overly concerned. From the get go I was keeping an eye on those things.

    I'll update the page as I agree with your advice.

    Thanks again!
    Posted in: General AddOns
  • 0

    posted a message on FullThrottle - Quick buff/debuff status
    Project page here

    In a nutshell, this addon is good for quick judgement calls on whether to pop a cooldown, or maybe even stand in the fire another few seconds *GASP!*

    I think it offers a few new approaches to solving the problem of knowing the state of your buffs/debuffs. It's features are more focused towards telling you what you don't have for example (although there's no requirement to use it that way).

    For example:
    * It displays a percentage of buffs that are up. You only have to look to see what's missing if you want more info.
    * It shows the duration of the shortest buffs among all tracked (although I found out recently that NeedToKnow does this, I just didn't know)
    * In addition to the various ways for organization, it also has what I call triggers, which are a way to dynamically choose what spells to track based on in game events.

    It also tries to be as unobtrusive as possible. There are already tons of great bar mods out there (e.g. Raven) and this isn't meant to replace them. It's more of a supplement.

    Quick feature dump:
    * Complete profile support: Allows copying configurations between characters.
    * Low CPU and memory overhead: Won't bog your computer down.
    * Tracks internal cooldowns on items (when supplied).
    * Dynamic spell and category tracking.
    * Lots of configuration options: Keeps from clashing with your carefully designed UI!
    * Tracks yours, and others buffs/debuffs.
    * Optional (and highly configurable) buff/debuff Tracking Window: Filter to only missing items, only active, or show everything.
    * Handles spells providing the same effect (e.g. Sunder Armor and Expose Armor)
    * Organization features: To aid in enabling or disabling tracking of related spells.

    Triggers are pretty new and I had to rewrite a lot of the core to make them do what people expect so show mercy on me! I hope to polish it up as necessary.
    Posted in: General AddOns
  • 0

    posted a message on Raven: Auras, Cooldowns and Notifications
    Just wanted to post a comment to say that I'm impressed with the feature set of this addon. It's very impressive. I've played with it enough to know it's nice! For now I'm sticking with what's familiar but I'll likely revisit come cat.
    Posted in: General AddOns
  • 0

    posted a message on AceTimer cancellation
    There's something fishy about mixing repeating timers with one shot timers and trying to start stop the repeating ones.

    I realize this is an old thread but this quote helped me work on a solution for myself

    Its true that the timer does infact not get removed instantly, however it will be removed when its time is reached.


    My code essentially has a ResetProcessing method which looks like this. The goal is to Stop and Restart Processing. Processing just means the timer is running:

    function FullThrottle:ResetProcessing()
    	FullThrottle:StopProcessing()
    	FullThrottle:StartProcessing()
    end


    StopProcessing() looked like this:

    function FullThrottle:StopProcessing()
    	--cancel the calculation timer
    	self:CancelTimer(FullThrottle.CalculationTimer, true)
    	FullThrottle.CalculationTimer = nil
    end


    And StartProcessing() looked like this:

    function FullThrottle:StartProcessing()
    	FullThrottle.CalculationTimer = self:ScheduleRepeatingTimer("DoCalculations", FullThrottle.CalculationInterval, nil)
    end


    I should mention, as I think it's related, that I do have a second "one shot" timer which gets triggered when you mouse over the frame and fires off an animation about 1 second later. And only when both of these are "running" can I reproduce the problem I'm about to describe. To cause the problem, I simply have to mouse over my frame to trigger the mouse event that fires the one shot trigger.

    While it was VERY intermittent, sometimes the repeating timer callback wouldn't get called any more after calling ResetProcessing(). In other words, the timer wasn't getting initialized as expected.

    The one thing I know for sure is that when the problem DOES happen, the creation of my FullThrottle.CalculationTimer will NOT be nil (a table representing the string exists), no errors are thrown, but a later call to self:TimeLeft(FullThrottle.CalculationTimer) will result in the "no such timer registered" error.

    I think that's ultimately the bug. I have searched my code extensively for the issue, I'm sure the problem is in how I'm using AceTimer (not AceTimer itself) but I could not locate where I am doing things wrong. I did however find a solution that solves the problem. When canceling the repeating timer, if I convert it to a one time timer (which makes the handle valid) then things work as expected. I fear this is more of a hack for something I've done wrong than anything.

    I'm posting my "hack" in case it help shed light on any possibility that there is in fact a bug with AceTimer's processing of it's timers:

    function FullThrottle:KillRepeatingTimer(timer)
    	if(timer) then
    		self:CancelTimer(timer, true)
    		timer = self:ScheduleTimer("DoCalculations", 0.1, nil) --convert to one shot timer
    		self:CancelTimer(timer, true) --cancel again, we don't care if it ran or not
    		timer = nil
    	end
    end
    
    function FullThrottle:ResetProcessing()
    	FullThrottle:StopProcessing()
    	FullThrottle:StartProcessing()
    end
    
    function FullThrottle:StopProcessing()
    	FullThrottle:KillRepeatingTimer(FullThrottle.CalculationTimer)
    end
    
    function FullThrottle:StartProcessing()
    	FullThrottle.CalculationTimer = self:ScheduleRepeatingTimer("DoCalculations", FullThrottle.CalculationInterval, nil)
    end
    Posted in: Ace3
  • To post a comment, please or register a new account.