View Single Post
09-21-13, 11:03 PM   #2
Dridzt
A Pyroguard Emberseer
 
Dridzt's Avatar
AddOn Author - Click to view addons
Join Date: Nov 2005
Posts: 1,360
This is an issue that stems from an assumption several addons make that the ADDON_LOADED event for the specific addon in question, generally fires before the PLAYER_LOGIN event.

This was indeed the case for all statically loaded addons (not load on demand) prior to 5.4.

The significance of those 2 events is that ADDON_LOADED with 'myaddon' as arg1 tells the author that saved variables are loaded and it's safe to do settings initialization, while PLAYER_LOGIN tells the author that they now have available most game systems (things like player talents, etc) so it's safe to query those.

This is mirrored in the Ace3 initialization scheme as well with :OnInitialize() corresponding to ADDON_LOADED for our addon, and :OnEnable() corresponding to PLAYER_LOGIN.

Many authors got into the habit of doing initialization on PLAYER_LOGIN since it was assumed (and for a very long period of time actually worked like that) that it always fires later than ADDON_LOADED.

This is no longer the case and PLAYER_LOGIN can fire earlier in the loading process than ADDON_LOADED for 'our addon' on some systems or for the same player from login to login.

So trying to reference for example fonts in PLAYER_LOGIN assuming the addon has already processed its saved variables in ADDON_LOADED and knows what font to apply won't always work.

The way to fix this is to put checks in place that ensure you do your initialization explicitly in the order you intended and not implicitly assuming a specific ADDON_LOADED -> PLAYER_LOGIN sequence.

Since you cannot get around the fact that your saved variables load at ADDON_LOADED my preferred method for ensuring I do initialization properly is something like this

Code:
events.ADDON_LOADED = function(addonName)
  if addonName == "myAddon" then
    -- InitSVStuff()
    if IsLoggedIn() then
      events.PLAYER_LOGIN()
    else
      events:RegisterEvent("PLAYER_LOGIN")
    end
  end
end
events.PLAYER_LOGIN = function()
  -- InitGameStuff()
end
This ensures that PLAYER_LOGIN and any extended initialization I need to do there always runs after ADDON_LOADED and any saved variables related setup I need to do first.

I put similar safeguards in AceAddon-3.0 based addons with the :OnInitialize() and :OnEnable() functions after 5.4.
  Reply With Quote