View Single Post
10-17-20, 08:45 AM   #3
DahkCeles
A Cliff Giant
 
DahkCeles's Avatar
AddOn Author - Click to view addons
Join Date: Jun 2020
Posts: 73
I've found there's two sources of delay, especially in Classic: (a) asynchronously querying the localized spell name; and (b) waiting for the spell book to be available at PLAYER_LOGIN.

I quickly wrote the snippet below to convert spellIDs into localized names, but not to check the spell book until at least PLAYER_LOGIN and possibly later if asynchronous queries return info even later. This snippet also deletes non-existing spellIDs, which could happen for classic vs. retail differences.

If you are creating click-cast frames for use during combat, then you should change this to do as much as possible at PLAYER_LOGIN even if some spells are still slow loading -- its possible the player is logging in during a raid fight after the game crashed, and they will need to rejoin the fight on a best-effort basis before combat lockdown kicks in.


Lua Code:
  1. local spells = {1459, 23028, 1008,  604}  -- mage buffs
  2. local spellsLoaded = 0
  3.  
  4. local function updateSpells()
  5.   if (spellsLoaded == #spells) then
  6.     for __, spellName in ipairs(spells) do
  7.       if (GetSpellInfo(spellName)) then
  8.         -- doSomething()
  9.       else
  10.         -- doSomethingElse()
  11.       end
  12.     end
  13.   end
  14. end
  15.  
  16. local playerIsLoggedIn = false
  17. local f = CreateFrame("Frame")
  18. f:RegisterEvent("PLAYER_LOGIN")
  19. f:SetScript("OnEvent", function()
  20.   updateSpells()
  21.   playerIsLoggedIn = true
  22.   f:RegisterEvent("LEARNED_SELL_IN_TAB")
  23.   pcall(f.RegisterEvent, f, "ACTIVE_TALENT_GROUP_CHANGED") -- retail only
  24.   f:SetScript("OnEvent", updateSpells)
  25. end
  26.  
  27. local i = 1
  28. while spells[i] do
  29.   local entry = i  -- This local reference avoids race conditions between the loop and async queries.
  30.   if (C_Spell.DoesSpellExist(entry)) then
  31.     local spell = Spell:CreateFromSpellID(entry)
  32.     spell:ContinueOnSpellLoad(function()
  33.       spells[entry] = GetSpellInfo(spells[entry])
  34.       spellsLoaded = spellsLoaded + 1
  35.       if (playerLoginHappened) then
  36.         updateSpells()
  37.       end
  38.     end)
  39.     i = i + 1  -- moves to the next spell
  40.   else
  41.     -- The spell doesn't exist; maybe because of classic vs retail?
  42.     tremove(spells, i)  -- shifts the next spell forward
  43.   end
  44. end
  Reply With Quote