ADDON_LOADED fires every time any addon (including the Blizzard ones) finishes loading. The first argument passed with the event is the name of the addon that finished loading. When it fires for an addon, that means that:
- all of the files in the addon's folder have been read,
- all objects defined in any XML files have been created,
- all code in the top-level scope of any Lua files has been executed,
- all font and textures files have been loaded into memory, and
- all previously stored saved variables for the addon have been loaded into memory.
Most addons listen for their own ADDON_LOADED event, and perform basic start-up tasks like initializing saved variables when it fires.
PLAYER_LOGIN fires at approximately the same time that the initial loading screen disappears and the game world becomes visible. Generally, this event means that all non-LoD addons have finished loading.
Most addons listen for this event, and perform additional start-up tasks like creating visible UI objects (eg. action buttons or unit frames) and registering for general events (eg. UNIT_HEALTH or PLAYER_REGEN_ENABLED). Since the user cannot see or interact with the UI prior to this event firing, there is no reason to perform these tasks earlier.
If you are writing an addon that modifies another addon's configuration, you will usually want to listen for the other addon's ADDON_LOADED event, and make your changes when it fires. However, depending on the other addon's design, and the nature of the changes you wish to make, you may need to listen for the PLAYER_LOGIN event instead (though I have never found this useful), or temporarily pre-hook one of the addon's functions when its ADDON_LOADED event fires and make your changes when that function is run:
Lua Code:
local f = CreateFrame("Frame")
f:RegisterEvent("ADDON_LOADED")
f:SetScript("OnEvent", function(self, event, addonName)
if addonName ~= "TargetAddon" then
-- Not the right addon.
-- Don't do anything else just now, but keep listening
-- for future events.
return
end
-- If we reach this point, it's the right addon.
-- Get a reference to a function the addon runs to set itself up.
local original = TargetAddon.DoSomeSetupStuff
-- Make the addon run a different function instead.
function TargetAddon:DoSomeSetupStuff(...)
-- Change some settings here, before the addon tries
-- to do anything with them.
-- Let the original function run.
original(self, ...)
-- Run any code here that needs to happen after the
-- addon sets itself up, like parenting frames to other
-- frames, etc.
-- Put the original function back. (optional)
self.DoSomeSetupStuff = original
end
-- We found the addon and modified it. We don't need to
-- listen for the addon's loading event anymore.
self:UnregisterEvent("ADDON_LOADED")
-- No events are registered anymore, so we don't need an
-- event handler anymore either. Unset it, so this function
-- gets garbage-collected and removed from memory.
self:SetScript("OnEvent", nil)
end)
For a more complex example that handles modifying multiple addons, see the attached file. It's what I use to apply custom borders to a number of addons. You'll notice that in some cases, I need to permanently hook one or more of the addon's functions, so that I can overwrite changes the addon makes during gameplay, long after the initial loading process.