Mercurial > wow > dependencyloader
view DependencyLoader/DependencyLoader.lua @ 15:a46bf694050c
cleaned up Tree's methods a bit and improved documentation
Addon:Exists will now return false for Blizzard addons (needs to be handled better)
Addon.lua will now use the raw hooks from the interface module
fixed the inverted returns from IsForceLoadAvailable
EnableAddOn and LoadAddOn hooks will now skip the extra processing if the addon does not exist or is a Blizzard addon
moved the EnableAddOn queing to the interface
author | mckenziemc |
---|---|
date | Sat, 11 Dec 2010 01:48:39 -0800 |
parents | 78b28ebdc169 |
children |
line wrap: on
line source
-- DependencyLoader -- -- TODO: disable bootstrap if we load successfully? -- TODO: implement a feature to disable unneeded libraries when a parent -- is disabled? local addonName, addonTable = ... local DependencyLoader = LibStub("AceAddon-3.0"):NewAddon(addonName, "AceHook-3.0", "AceEvent-3.0") _G[addonName] = DependencyLoader addonTable.interface = DependencyLoader local classes = addonTable.classes local LibPrint = LibStub("LibPrint-1.0") local LibScriptLink = LibStub("LibScriptLink-1.0") DependencyLoader.printStream = LibPrint:NewStream("DependencyLoader", "DpLdr", print) DependencyLoader.debugStream = LibPrint:NewStream("DependencyLoader", "DpLdr", "mcm") DependencyLoader.queuedEnables = {} -- addons queued to be enabled after PLAYER_LOGIN function DependencyLoader:Print(...) self.printStream:Print(...) end function DependencyLoader:Debug(...) self.debugStream:Print(...) end function DependencyLoader:OnInitialize() self:Debug("Initializing", addonName) self:Enable() end function DependencyLoader:OnEnable() -- this may get called early so don't rely on -- it as an indicator for PLAYER_LOGIN self:RegisterEvent("PLAYER_LOGIN") self:RawHook("LoadAddOn", true) self:RawHook("EnableAddOn", true) self:PrepareAllAddons() self:Print("Enabled", addonName) end function DependencyLoader:PLAYER_LOGIN(...) self:Debug(...) self:ProcessEnableQueue() end function DependencyLoader:OnDisable() self:Print("Disabled", addonName) end -- Does not consider user settings or addon errata. function DependencyLoader:IsForceLoadAvailable() if IsLoggedIn() then return false else return true end end function DependencyLoader:IsForceLoadAllowed() -- TODO: check user settings return true end function DependencyLoader:CanForceLoad() return self:IsForceLoadAvailable() and self:IsForceLoadAllowed() end -- Enables any dependencies needed by the addons -- that have already been enabled function DependencyLoader:PrepareAllAddons() local requestReload = false for i=1, GetNumAddOns() do local addon = classes.Addon:Get(i) -- TODO: what if an addon was loaded but its deps were then disabled? if addon:IsEnabled() and not addon:IsLoaded() then self:EnableAddOn(addon:GetName()) end end --[[ if requestReload then local message = LibScriptLink:NewLink(ReloadUI) .. " to reload your UI." self:Print(message) end ]] end -- FIXME: use pcall in EnableAddOn and LoadAddOn, so that if my part errors, -- it can still use the unhooked version function DependencyLoader:EnableAddOn(...) local id = ... self:Debug("EnableAddOn", ...) -- even though we know EnableAddOn can cause force-loading before PLAYER_LOGIN, -- DO NOT attempt to "fix" it: another addon that -does- know about -- the different behavior might call our hook. if classes.Addon:Exists(id) then local addon = classes.Addon:Get(id) local tree = classes.Tree:Get(addon) local requestReload = false if self:CanForceLoad() then -- NOTE: if we can force-load, then will enabling LoD addons cause them to load too? -- A: no, they will still wait for LoadAddOn -- Can the addon be loaded on demand if force-loading is -- allowed for its dependencies -- if so, enable all deps and force-load if nec. -- deps will get enabled if all parents are lod, force-loaded -- if any parent can't be loaded on demand -- else -- if the addon is not loadable on demand but the tree can be -- force-loaded, then force-load it all -- deps will all get loaded since req. for root to load -- else -- if it can be loaded with a reloadui then prepare after login -- else -- it can't be loaded, maybe tell the user if tree:CanForceLoad() then if addon:CanLoD() then tree:PrepareForLoD() else tree:ForceLoad() end elseif tree:CanLoad() then tree:PrepareForLoad() requestReload = true else -- TODO: tell user end --[[ if tree:CanLoDWithForce() then tree:PrepareForLoD() elseif tree:CanForceLoad() then tree:ForceLoad() elseif tree:CanLoad() then tree:PrepareForLoad() requestReload = true else -- TODO: tell user end ]] else -- if it can be loaded on demand (deps are loaded or LoD) then -- prepare it (enable all deps) -- else -- if it can be loaded (and isn't already) then -- if force loading is available, we have to wait, then enable everything -- else -- prepare for reload (TODO: move this check and similar to PLAYER_LOGOUT) -- else -- can't be loaded, maybe tell the user if tree:CanLoD() then tree:PrepareForLoad() -- don't actually intend to reload, just enable everything elseif tree:CanLoad() then tree:PrepareForLoad() requestReload = true else -- TODO: tell user end end if requestReload then self:RequestReload() end end -- propogate the call even if it doesn't exist or deps are unavailable return self.hooks.EnableAddOn(...) end --- Prepares the addon tree rooted at the specified addon function DependencyLoader:LoadAddOn(...) local id = ... self:Debug("LoadAddOn", ...) if classes.Addon:Exists(id) then local addon = classes.Addon:Get(id) local tree = classes.Tree:Get(addon) if tree:CanLoD() then tree:PrepareForLoD() elseif tree:CanLoad() then tree:PrepareForReload() end end -- call even if it can't be loaded so regular returns appear return self.hooks.LoadAddOn(...) end function DependencyLoader:RequestReload() -- TODO: this should only run once end function DependencyLoader:QueueEnable(name) self.queuedEnables[name] = true end function DependencyLoader:RawEnableAddOn(...) return self.hooks.EnableAddOn(...) end function DependencyLoader:RawLoadAddOn(...) return self.hooks.LoadAddOn(...) end function DependencyLoader:ProcessEnableQueue() for addon in pairs(self.queuedEnables) do self:RawEnableAddOn(addon) self.queuedEnables[addon] = nil end end