Thread: GetTime()
View Single Post
10-01-20, 12:56 AM   #9
SDPhantom
A Pyroguard Emberseer
 
SDPhantom's Avatar
AddOn Author - Click to view addons
Join Date: Jul 2006
Posts: 2,323
This is what I've come up with.
Lua Code:
  1. local AsyncPairs; do
  2. --  Local pointers make lookups faster
  3.     local CallErrorHandler=CallErrorHandler;
  4.     local debugprofilestop=debugprofilestop;
  5.     local next=next;
  6.     local table_remove=table.remove;
  7.     local unpack=unpack;
  8.     local xpcall=xpcall;
  9.  
  10.     local TableStack={};
  11.     local TimerFrame=CreateFrame("Frame");
  12.  
  13.     local function TimerFrame_OnUpdate(self,elpased)
  14.         local tbldat=TableStack[1];--   Pull from bottom of stack
  15.         if tbldat then
  16.             local tbl,key,limit,oniterate,onfinish=unpack(tbldat,1,5);--    Extract vars; range is specified since there can be embedded nils
  17.             local start=debugprofilestop()-elapsed*1000;--  Offset with frame render time
  18.             repeat--    Used instead of While to guarantee at least one iteration
  19.                 local val; key,val=next(tbl,key);-- Get next key/val pair
  20.                 if key~=nil then--  We have a key/val pair
  21.                     local ok=xpcall(oniterate,CallErrorHandler,key,val);--  Dispatch OnIterate callback
  22.                     if not ok then table_remove(TableStack,1); break; end-- OnError: Remove table from stack and exit
  23.                 else--  No more key/val pairs
  24.                     table_remove(TableStack,1);--   Remove from stack
  25.                     if onfinish then xpcall(onfinish,CallErrorHandler); end--   Dispatch OnFinish callback
  26.                     break;--    Exit loop
  27.                 end
  28.             until debugprofilestop()-start>=limit-- Checked at end of iteration; compare elapsed time to limit
  29.             tbldat[2]=key;--    Store new key for next frame; if table was removed from stack, this is just garbage anyway
  30.         else self:SetScript("OnUpdate",nil); end--  Disable if we have nothing on the stack
  31.     end
  32.  
  33.     function AsyncPairs(tbl,limit,oniterate,onfinish)
  34.         table.insert(TableStack,{tbl,nil,limit,oniterate,onfinish});--  Push to stack
  35.         TimerFrame:SetScript("OnUpdate",TimerFrame_OnUpdate);-- Activate timer function
  36.     end
  37. end

Usage: AsyncPairs(Table, Limit, OnIterate[, OnFinish])
Limit is in milliseconds. OnIterate and OnFinish are callbacks with the later being optional.
__________________
WoWInterface AddOns
"All I want is a pretty girl, a decent meal, and the right to shoot lightning at fools."
-Anders (Dragon Age: Origins - Awakening)

Last edited by SDPhantom : 10-01-20 at 12:59 AM.
  Reply With Quote