Originally Posted by zork
Are there any arguments that allow throttling like elapsed?
|
Cross posting this from something I posted somewhere else I can't talk about
Events in this game can trigger really, really... really fast. If you want to know how fast you can easily dump a counter to your chat window when that event triggers and watch as it fliiieeeeesssss by. This can cause issues when your update script has to parse something or do any heavy lifting. In fact, it can cause a problem at times when your update script isn't really doing much.
The safe way to handle this is to buffer your event handling so that you're only processing updates at set intervals, instead of nearly instantaneously. And yes, some things are fine at lightening speed but I've found that most work just fine between 0.33 and 3 seconds.
In the case of my War Tools addon (found within my [MH] Addon Suite) I parse Cyrodiil rather extensively. When I first drafted the addon I walked into Cyrodiil, the events registered and I instantly entered stutter-frame, stop-motion TESO. It... was... bad...
The simple fact was that events were triggering too quickly for the Cyrodiil parser to constantly run the way it was. In fact, it was running in layers on top of itself because the events fired so fast.
I also use this trick in Gear Tools (also in the Addon Suite) to build a queuing system to handle gear moves because items can't all be unequipped all at once. You have to trigger those moves one at a time. So, I pile the "these things need to happen" gear moves into a table and I execute anything pending in the table, 1 item per iteration, as the OnUpdate event triggers in the addon... at a 0.33 buffer. Because anything faster than 1/3rd of a second doesn't allow time for gear to move properly and register with your UI.
This is the basic buffer I use, modified for "generic and global" application:
Code:
local BufferTable = {}
function BufferReached(key, buffer)
if key == nil then return end
if BufferTable[key] == nil then BufferTable[key] = {} end
BufferTable[key].buffer = buffer or 3
BufferTable[key].now = GetFrameTimeSeconds()
if BufferTable[key].last == nil then BufferTable[key].last = BufferTable[key].now end
BufferTable[key].diff = BufferTable[key].now - BufferTable[key].last
BufferTable[key].eval = BufferTable[key].diff >= BufferTable[key].buffer
if BufferTable[key].eval then BufferTable[key].last = BufferTable[key].now end
return BufferTable[key].eval
end
This is how you would consume that buffer in an event/update handler:
Code:
function OnUpdateHandler()
if not BufferReached("myaddonupdatebuffer", 1) then return; end
--[[ process your update here ]]--
end
Hopefully this little tidbit helps someone.
|
Cairenn it might be good to have tips like this in your wiki, since OnUpdate fires so quickly it's likely to crash a LOT of people if addons are written that don't know how to buffer properly.