View Single Post
09-04-21, 02:04 PM   #6
maqjav
A Theradrim Guardian
AddOn Author - Click to view addons
Join Date: Feb 2012
Posts: 60
This is the code I wrote with your ideas:

Lua Code:
  1. local Routine = {} do  
  2.     function Routine:Init(getterItems, chunkSize)
  3.         self.context, self.deadline = {}
  4.         self.context.currentIndex = 1
  5.         self.context.getterItems = getterItems
  6.         self.context.chunkSize = chunkSize
  7.     end
  8.  
  9.     function Routine:Run(callback)
  10.         if (not self.context) then
  11.             return true
  12.         end
  13.         self.deadline = debugprofilestop() + 500/(tonumber(C_CVar.GetCVar("targetFPS")) or GetFrameRate() or 35)
  14.  
  15.         repeat
  16.             local totalIndex = 1
  17.             local chunkIndex = 1
  18.             for key, value in pairs(self.context.getterItems()) do
  19.                 if (totalIndex >= self.context.currentIndex) then
  20.                     if (chunkIndex == self.context.chunkSize) then
  21.                         return false
  22.                     end
  23.                    
  24.                     callback(self.context, key, value)
  25.                     self.context.currentIndex = self.context.currentIndex + 1
  26.                     chunkIndex = chunkIndex + 1
  27.                 end
  28.                
  29.                 totalIndex = totalIndex + 1
  30.             end
  31.            
  32.             self.context.finished = true
  33.             return true
  34.         until debugprofilestop() > self.deadline
  35.     end
  36.    
  37.     function Routine:IsRunning()
  38.         if self.context and not self.context.finished then
  39.             return true
  40.         end
  41.         return false
  42.     end
  43.    
  44.     function Routine:Reset()
  45.         self.context = {}
  46.     end
  47.    
  48.     function Routine:New(routine)
  49.         routine = routine or {}
  50.         setmetatable(routine, self)
  51.         self.__index = self
  52.         return routine
  53.     end
  54. end

And this is how I use it:
Lua Code:
  1. local routine = Routine:New()
  2. routine:Init(GetStuff, 100)
  3.  
  4. -- Using OnUpdate script
  5. myFrame:SetScript("OnUpdate", function(self)
  6.     local finished = routine:Run(function(state, key, value)
  7.         doHeavyStuff(key, value)
  8.     end)
  9.    
  10.     if (finished) then
  11.         routine:Reset()
  12.         self:SetScript("OnUpdate", nil)
  13.     end
  14. end);
  15.  
  16. -- Using a ticker if the frame is hidden
  17. C_Timer.NewTicker(0.5, function(self)
  18.     local finished = routine:Run(function(context, key, value)
  19.         doHeavyStuff(key, value)
  20.     end)
  21.    
  22.     if (finished) then
  23.         routine:Reset()
  24.         self:Cancel()
  25.     end
  26. end

So far this improves the performance a lot. It takes longer to finish, but I'm sure I can improve it changing the value of "state.chunkSize".

The issue I find with this code is that it loops through the table returned by GetStuff() several times and I don't see how to avoid it.

Thank you both!

Last edited by maqjav : 09-12-21 at 06:38 AM.
  Reply With Quote