Mercurial > wow > dependencyloader
changeset 17:f825ccf94a89
fixed an indexing issue in Addon.lua
moved most of the code in DependencyLoader.lua to Core.lua, and renamed the former to frontend.lua
updated load.xml
rearranged stuff in start.lua
author | mckenziemc |
---|---|
date | Sat, 11 Dec 2010 03:32:04 -0800 |
parents | 1d8898cd1c82 |
children | e7995d599184 |
files | DependencyLoader/Addon.lua DependencyLoader/Core.lua DependencyLoader/DependencyLoader.lua DependencyLoader/frontend.lua DependencyLoader/load.xml DependencyLoader/start.lua |
diffstat | 6 files changed, 276 insertions(+), 276 deletions(-) [+] |
line wrap: on
line diff
--- a/DependencyLoader/Addon.lua Sat Dec 11 01:54:15 2010 -0800 +++ b/DependencyLoader/Addon.lua Sat Dec 11 03:32:04 2010 -0800 @@ -184,9 +184,9 @@ function addon:Enable() if IsLoggedIn() then - addonTable.interface:QueueEnable(self.name) + addonTable.classes.Core:QueueEnable(self.name) else - addonTable.interface:RawEnableAddOn(self.name) + addonTable.classes.Core:RawEnableAddOn(self.name) end end @@ -195,8 +195,8 @@ function addon:Load() assert(self:CanLoD()) - addonTable.interface:RawEnableAddOn(self.name) - addonTable.interface:RawLoadAddOn(self.name) + addonTable.classes.Core:RawEnableAddOn(self.name) + addonTable.classes.Core:RawLoadAddOn(self.name) end @@ -204,7 +204,7 @@ assert(self:CanForceLoad()) -- TODO: make sure force-loading is available at this time - addonTable.interface:RawEnableAddOn(self.name) -- This should cause the game to also load this addon + addonTable.Core:RawEnableAddOn(self.name) -- This should cause the game to also load this addon end
--- a/DependencyLoader/Core.lua Sat Dec 11 01:54:15 2010 -0800 +++ b/DependencyLoader/Core.lua Sat Dec 11 03:32:04 2010 -0800 @@ -1,8 +1,218 @@ -- Core --- Provides core functionality of DependencyLoader +-- Provides core functionality of Core + + +-- TODO: disable bootstrap if we load successfully? +-- TODO: implement a feature to disable unneeded libraries when a parent +-- is disabled? local addonName, addonTable = ... -local Core, core = addonTable:NewClass("Core") +-- locals +local print = addonTable.print +local debug = addonTable.debug +local classes = addonTable.classes + +local AceHook = LibStub("AceHook-3.0") +local LibScriptLink = LibStub("LibScriptLink-1.0") + + +local Core = addonTable:NewClass("Core") + + +AceHook:Embed(Core) + +Core.queuedEnables = {} -- addons queued to be enabled after PLAYER_LOGIN + + +-- Does not consider user settings or addon errata. +function Core:IsForceLoadAvailable() + if IsLoggedIn() then + return false + else + return true + end +end + + +function Core:IsForceLoadAllowed() + -- TODO: check user settings + return true +end + + +function Core:CanForceLoad() + return self:IsForceLoadAvailable() and self:IsForceLoadAllowed() +end + + +-- Enables any dependencies needed by the addons +-- that have already been enabled +function Core:PrepareAllAddons() + 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(i) + end + end +end + + +function Core:SetHooks() + self:RawHook("EnableAddOn", true) + self:RawHook("LoadAddOn", true) +end + + +-- FIXME: use pcall in EnableAddOn and LoadAddOn, so that if my part errors, +-- it can still use the unhooked version + +function Core:EnableAddOn(...) + local id = ... + + 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:RawEnableAddOn(...) +end + + + +--- Prepares the addon tree rooted at the specified addon +function Core:LoadAddOn(...) + local id = ... + + 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:PrepareForLoad() + -- TODO: request reload + end + end + + -- call even if it can't be loaded so regular returns appear + return self:RawLoadAddOn(...) +end + + +function Core:RequestReload() + -- TODO: this should be throtled so that it can + -- occur more than once but not within a short time + + debug("reload requested (NYI)") +end + + +-- name or index +function Core:QueueEnable(addon) + self.queuedEnables[addon] = true +end + + +function Core:RawEnableAddOn(...) + return self.hooks.EnableAddOn(...) +end + + +function Core:RawLoadAddOn(...) + return self.hooks.LoadAddOn(...) +end + + +function Core:ProcessEnableQueue() + for addon in pairs(self.queuedEnables) do + self:RawEnableAddOn(addon) + self.queuedEnables[addon] = nil + end +end
--- a/DependencyLoader/DependencyLoader.lua Sat Dec 11 01:54:15 2010 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,258 +0,0 @@ --- 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
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/DependencyLoader/frontend.lua Sat Dec 11 03:32:04 2010 -0800 @@ -0,0 +1,51 @@ +-- frontend.lua +-- Implements the frontend of DependenyLoader + + +local addonName, addonTable = ... + + +local print = addonTable.print +local debug = addonTable.debug + +local Core = addonTable.classes.Core + + +local frontend = LibStub("AceAddon-3.0"):NewAddon(addonName, "AceEvent-3.0") +addonTable.frontend = frontend +_G[addonName] = frontend + +frontend.addonTable = addonTable + + +function frontend:OnInitialize() + debug("Initializing", addonName) + self:Enable() +end + + +function frontend:OnEnable() + -- this may get called early so don't rely on + -- it as an indicator for PLAYER_LOGIN + + if not IsLoggedIn() then + self:RegisterEvent("PLAYER_LOGIN") + end + + Core:SetHooks() + Core:PrepareAllAddons() + + print("Enabled", addonName) +end + + +function frontend:OnDisable() + Core:UnhookAll() + + print("Disabled", addonName) +end + +function frontend:PLAYER_LOGIN(...) + Core:ProcessEnableQueue() +end +
--- a/DependencyLoader/load.xml Sat Dec 11 01:54:15 2010 -0800 +++ b/DependencyLoader/load.xml Sat Dec 11 03:32:04 2010 -0800 @@ -1,1 +1,1 @@ -<ui xsi:schemaLocation="http://www.blizzard.com/wow/ui/ ..\FrameXML\UI.xsd"> <!--@no-lib-strip@--> <include file="embeds.xml"/> <!--@end-no-lib-strip@--> <script file="start.lua"/> <script file="class.lua"/> <script file="Addon.lua"/> <script file="Tree.lua"/> <script file="Core.lua"/> <script file="DependencyLoader.lua"/> </ui> \ No newline at end of file +<ui xsi:schemaLocation="http://www.blizzard.com/wow/ui/ ..\FrameXML\UI.xsd"> <!--@no-lib-strip@--> <include file="embeds.xml"/> <!--@end-no-lib-strip@--> <script file="start.lua"/> <script file="class.lua"/> <script file="Addon.lua"/> <script file="Tree.lua"/> <script file="Core.lua"/> <script file="frontend.lua"/> </ui> \ No newline at end of file
--- a/DependencyLoader/start.lua Sat Dec 11 01:54:15 2010 -0800 +++ b/DependencyLoader/start.lua Sat Dec 11 03:32:04 2010 -0800 @@ -5,17 +5,14 @@ local addonName, addonTable = ... -print( string.format([[running %s\start.lua]], addonName) ) +-- prepare output functions +local LibPrint = LibStub("LibPrint-1.0") --- NOTE: We don't have to check if this module's dependencies --- are available: it lists them normally in its .toc file and --- the bootstrap module will take care of enabling them first. +addonTable.printStream = LibPrint:NewStream("DependencyLoader", "DpLdr", print) +addonTable.debugStream = LibPrint:NewStream("DependencyLoader", "DpLdr", "mcm") --- prepare output functions -local lp = LibStub("LibPrint-1.0") -local printStream = lp:NewStream("DependencyLoader", "DepLoader", "DepLdr", print) -local debugStream = lp:NewStream("DependencyLoader", "DepLoader", "DepLdr", "mcm") +function addonTable.print(...) addonTable.printStream:Print(...) end +function addonTable.debug(...) addonTable.debugStream:Print(...) end -addonTable.print = function(...) printStream:Print(...) end -addonTable.debug = function(...) debugStream:Print(...) end +addonTable.debug("loading", addonName)