Mercurial > wow > dependencyloader
changeset 10:e0a4a8b5b389
lots more modifications...
author | mckenziemc |
---|---|
date | Sun, 05 Dec 2010 03:10:07 -0800 |
parents | 5362e308c3eb |
children | 47d15fc9208e |
files | DependencyLoader/Addon.lua DependencyLoader/Core.lua DependencyLoader/DependencyLoader.lua DependencyLoader/DependencyLoader.toc DependencyLoader/DependencyLoader_Core.toc DependencyLoader/Tree.lua DependencyLoader/frontend.lua DependencyLoader/load.xml DependencyLoader_Bootstrap/DependencyLoader.toc DependencyLoader_Bootstrap/DependencyLoader_Bootstrap.toc DependencyLoader_Bootstrap/bootstrap.lua DependencyLoader_Errata/DependencyLoader_Errata.toc |
diffstat | 12 files changed, 216 insertions(+), 228 deletions(-) [+] |
line wrap: on
line diff
--- a/DependencyLoader/Addon.lua Sun Dec 05 00:12:57 2010 -0800 +++ b/DependencyLoader/Addon.lua Sun Dec 05 03:10:07 2010 -0800 @@ -1,27 +1,16 @@ -- Addon --- Represents individual addon modules +-- Represents individual addon modules. local addonName, addonTable = ... --- NOTE: I assume that the API addon functions are --- slightly quicker with an index than with a number. - --- TODO: modify the dependency stuff to use the Errata module if available +-- TODO: test if the API functions are quicker with indexes than names. +-- TODO: modify the dependency stuff to check the Errata module. local Addon, addon = addonTable:NewClass("Addon") --- load ability masks -Addon.loadMasks = { - reload = bit.lshift(1, 0), -- can load after reloadui - ondemand = bit.lshift(1, 1), -- can load on demand - forceafter = bit.lshift(1, 2), -- force load after it would normally be loaded - forcebefore = bit.lshift(1, 3), -- force load before it would normally be loaded -} - - Addon.addons = {} Addon.nameToIndex = {} @@ -91,6 +80,7 @@ end end + -- Checks if an addon exists with the specified name. -- @param addon Name of the addon. -- @return True if the addon is present, false otherwise. @@ -115,11 +105,6 @@ end -function Addon:GetLoadMasks() - return self.masks -end - - function addon:GetName() return self.name end @@ -142,29 +127,6 @@ end -function addon:GetLoadBitfield() - local bitfield = 0 - - if self:CanLoad() then - bitfield = bitfield + self.masks.reload - end - - if self:CanLoD() then - bitfield = bitfield + self.masks.ondemand - end - - if self:CanForceLoadAfter() then - bitfield = bitfield + self.masks.forceafter - end - - if self:CanForceLoadBefore() then - bitfield = bitfield + self.masks.forcebefore - end - - return bitfield -end - - --- Checks if the addon is loadable. -- Considers interface issues, missing, etc. (NYI) -- Does not check dependencies. @@ -196,6 +158,12 @@ end +function addon:CanForceLoad() + -- FIXME: check if this would've already been loaded + return self:CanForceLoadAfter() +end + + function addon:Enable() -- FIXME: delay this till after PLAYER_LOGIN or it'll get force-loaded EnableAddOn(self.name)
--- a/DependencyLoader/Core.lua Sun Dec 05 00:12:57 2010 -0800 +++ b/DependencyLoader/Core.lua Sun Dec 05 03:10:07 2010 -0800 @@ -4,6 +4,10 @@ local addonName, addonTable = ... +if true then + return +end + local Core, core = addonTable:NewClass("Core")
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/DependencyLoader/DependencyLoader.lua Sun Dec 05 03:10:07 2010 -0800 @@ -0,0 +1,99 @@ +-- DependencyLoader +-- + +local addonName, addonTable = ... + + +local DependencyLoader = LibStub("AceAddon-3.0"):NewAddon(addonName, "AceHook-3.0") +_G[addonName] = DependencyLoader + +addonTable.interface = DependencyLoader + + +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") + + +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() + self:Print("Enabled", addonName) + + self:Hook("EnableAddOn", true) + + self:FixCurrentAddons() +end + + +function DependencyLoader:OnDisable() + self:Print("Disabled", addonName) +end + + +-- Does not consider user settings or addon errata. +function DependencyLoader:IsForceLoadAvailable() + return IsLoggedIn() and true or false +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:FixCurrentAddons() + local requestReload = false + + for i=1, GetNumAddOns() do + local addon = addonTable.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 + local tree = addonTable.classes.Tree:Get(addon) + + if self:CanForceLoad() and tree:CanForceLoad() then + tree:ForceLoad() + elseif tree:CanLoD() then + tree:PrepareForLoD() + elseif tree:CanLoad() then + tree:PrepareForReload() + requestReload = true + end + end + end + + if requestReload then + local message = LibScriptLink:NewLink(ReloadUI) .. " to reload your UI." + self:Print(message) + end +end + + +function DependencyLoader:EnableAddOn(...) + print("DependencyLoader:EnableAddOn", ...) +end
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/DependencyLoader/DependencyLoader.toc Sun Dec 05 03:10:07 2010 -0800 @@ -0,0 +1,12 @@ +## Interface: 40000 + +## Notes: Automatically loads dependencies of addons you've manually enabled. + +## Author: mckenziemc + +## Dependencies: LibStub, Ace3, LibPrint-1.0, LibScriptLink-1.0 + +## LoadOnDemand: 1 + + +load.xml
--- a/DependencyLoader/DependencyLoader_Core.toc Sun Dec 05 00:12:57 2010 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,14 +0,0 @@ -## Interface: 40000 - -# TODO: actually explain what DependencyLoader does. -## Notes: Core module of DependencyLoader -## Author: mckenziemc - -# TODO: figure out some way to allow AddonLoader -# to work with DependencyLoader -## Dependencies: DependencyLoader, LibStub, LibPrint-1.0, Ace3 - -## LoadOnDemand: 1 - - -load.xml
--- a/DependencyLoader/Tree.lua Sun Dec 05 00:12:57 2010 -0800 +++ b/DependencyLoader/Tree.lua Sun Dec 05 03:10:07 2010 -0800 @@ -6,7 +6,7 @@ local addonName, addonTable = ... --- TODO: prevent infinite loops in the recursive functions +-- FIXME: prevent infinite loops in the recursive functions local Tree, tree = addonTable:NewClass("Tree") @@ -14,6 +14,7 @@ Tree.trees = {} + -- internal -- Creates a new tree object -- @param root Name, index, or Addon object of the root addon. @@ -68,48 +69,54 @@ end --- Checks if the tree rooted at the specified addon can be force-loaded. --- @param root The name or index of the root addon. -function core:CanForceLoadTree(root) - -- TODO: if some addons have already loaded, we have to check - -- forceafter for those and forcebefore for the others - return false +--- Checks if this tree can be force-loaded. +-- Does not check user settings nor if force-loading is actually available. +-- @return canForceLoad True if this tree can be force loaded, false otherwise +function tree:CanForceLoad() + if self.root:IsLoaded() then + return true + end + + if not self.root:CanForceLoad() then + return false + end + + -- now check dependencies recursively + local dependencies = {self.root:GetDependencies()} + for i, depName in pairs(dependencies) do + local depTree = Tree:Get(depName) + + if not depTree:CanForceLoad() then + return false + end + end + + return end -- NOTE: any tree that can be loaded on demand is also eligible for force-loading --- Checks if the tree rooted at the specified addon can be loaded on demand. --- @param root The name or index of the root addon. -function core:CanLoDTree(root) - local bitfield = self:GetLoadBitfield() - root = self:GetAddon(root) - assert(root) - +-- Checks if the tree can be loaded on demand. +function tree:CanLoD() -- since this will be used recursively, return true if -- this is already loaded. - if root:IsLoaded() then + if self.root:IsLoaded() then return true end -- true if all dependencies are loaded or LoD - if not root:CanLoD() then + if not self.root:CanLoD() then return false end -- now check dependencies recursively local dependencies = {root:GetDependencies()} for i, depName in pairs(dependencies) do - local dep = self:GetAddon(depName) + local depTree = Tree:Get(depName) - if not dep then - return false -- missing - end - - if not dep:IsLoaded() then - if not self:CanLoDTree(depName) then - return false - end + if not depTree:CanLoD() then + return false end end @@ -121,12 +128,8 @@ -- can be loaded if all dependencies are enabled -- the UI is reloaded. -- Basically makes sure all dependencies are installed. -function core:CanReloadTree(root) - -- convert root to an Addon object - root = self:GetAddon(root) - assert(root) - - if root:IsLoaded() then +function tree:CanLoad() + if self.root:IsLoaded() then return true -- FIXME: deps may have been disabled end @@ -136,11 +139,11 @@ -- now check dependencies recursively -- FIXME: prevent infinite recursion - local dependencies = {root:GetDependencies()} + local dependencies = {self.root:GetDependencies()} for i, depName in pairs(dependencies) do - local dep = self:GetAddon(depName) + local depTree = Tree:Get(depName) - if dep == nil then + if not depTree:CanLoad() then return false -- missing dependency end @@ -150,10 +153,11 @@ return true end +--[[ -- Loads the tree rooted at the specified addon. -- FIXME: load the root too or not? -- Supports both LoD addons and those that require force-loading. -function core:LoadTree(addon) +function tree:Load(addon) -- don't check if the tree can actually be loaded. -- external code should do that itself to check if it -- should even call this at all. @@ -165,31 +169,30 @@ self:LoadLoDTree(addon) end end +]] -- load the root too, since it may actually be a leaf -function core:ForceLoadTree(root) - root = self:GetAddon(root) - assert(root) - +function tree:ForceLoad() -- load dependencies - local dependencies = {root:GetDependencies(addon)} + local dependencies = {self.root:GetDependencies()} for i, depName in pairs(dependencies) do - self:ForceLoadTree(depName) + local depTree = Tree:Get(depName) + depTree:ForceLoad() end -- load embeds, if they are available separately - local embeds = {root:GetEmbeds(addon)} + local embeds = {self.root:GetEmbeds()} for i, embedName in pairs(embeds) do - if Addon:Exists(embedName) then - self:ForceLoadTree(embedName) - end + local embedTree = Tree:Get(embedName) + embedTree:ForceLoad() end root:ForceLoad() end +--[[ don't think i need this function core:LoadLoDTree(root) root = self:GetAddon(root) assert(root) @@ -210,24 +213,22 @@ root:LoD() end +]] -- I think the problem this solves is a major issue with -- migrating to separate libs. think about it more and document -- here and in project description -function core:PrepareLoDTree(root) - root = self:GetAddon(root) - assert(root) - +function tree:PrepareForLoD() -- assume root is LoD -- check dependencies local dependencies = {root:GetDependencies(addon)} for i, depName in pairs(dependencies) do - local dep = self:GetAddon(depName) + local depTree = Tree:Get(depName) + depTree:PrepareForLoD() - -- assume external code made sure it exists - + --[[ if dep:CanLoD() then -- don't load it now but make sure its dependencies are prepared self:PrepareLoDTree(depName) @@ -236,13 +237,16 @@ -- force-load it now so we can load the parent on demand self:ForceLoadTree(depName) end + ]] end -- prepare embeds, if they are available separately local embeds = {root:GetEmbeds(addon)} -- FIXME: addon? for i, embedName in pairs(embeds) do - local embed = self:GetAddon(embedName) + local embedTree = Tree:Get(embedName) + embedTree:PrepareForLoD() + --[[ if embed then if embed:CanLoD() then -- don't load it now but make sure its dependencies are prepared @@ -253,35 +257,23 @@ self:ForceLoadTree(depName) end end + ]] end end -function Core:PrepareReloadTree(addon) - root = self:GetAddon(root) - assert(root) - - root:Enable() +function tree:PrepareForReload() + self.root:Enable() -- check dependencies - local dependencies = {root:GetDependencies()} + local dependencies = {self.root:GetDependencies()} for i, depName in pairs(dependencies) do - self:PrepareReloadTree(depName) + Tree:Get(depName):PrepareForReload() end -- prepare embeds, if they are available separately - local embeds = {root:GetEmbeds(addon)} + local embeds = {self.root:GetEmbeds(addon)} for i, embedName in pairs(embeds) do - local embed = self:GetAddon(embedName) - - if embed then - self:PrepareReloadTree(embedName) - end + Tree:Get(embedName):PrepareForReload() end end - - -function Core:ForceLoadAvailable() - return true - -- FIXME: use field and a frame registered for PLAYER_LOGIN -end
--- a/DependencyLoader/frontend.lua Sun Dec 05 00:12:57 2010 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,83 +0,0 @@ --- main.lua --- - -local addonName, addonTable = ... - - -local DependencyLoader = LibStub("AceAddon-3.0"):NewAddon(addonName) -_G[addonName] = DependencyLoader - -local libPrint = LibStub("LibPrint-1.0") -DependencyLoader.printStream = libPrint:NewStream("DependencyLoader", "DpLdr", print) -DependencyLoader.debugStream = libPrint:NewStream("DependencyLoader", "DpLdr", "mcm") - --- temp -DependencyLoader.classes = addonTable.classes - -function DependencyLoader:Print(...) - self.printStream:Print(...) -end - - -function DependencyLoader:Debug(...) - self.debugStream:Print(...) -end - - -function DependencyLoader:OnInitialize() - self:Debug("Initializing and enabling", addonName) - self:Enable() -end - - -function DependencyLoader:OnEnable() - self.core = addonTable.classes.Core:New() - - self:Print("Enabled", addonName) - - self:FixCurrentAddons() -end - -function DependencyLoader:OnDisable() - self:Print("Disabled", addonName) -end - - --- TODO: move this into core? - --- Enables any dependencies needed by the addons --- that have already been enabled -function DependencyLoader:FixCurrentAddons() - local core = self.core - - for i=1, GetNumAddOns() do - local addon = self.core:GetAddon(i) - - if addon:IsEnabled() then - if addon:IsLoaded() then - -- TODO: it might still help to enable its embeds - else - self:Debug("Checking", addon:GetName()) - - if addonTable.classes.Core:ForceLoadAvailable() then - if core:CanForceLoadTree(addon:GetName()) then - core:ForceLoadTree(addon:GetName()) - else - print("Can't force load", addon:GetName()) - end - else - if core:CanLoDTree(addon:GetName()) then - core:PrepareLoDTree(addon:GetName()) - else - print("Couldn't load", addon:GetName(), "on demand.") - end - end - end - end - end -end - - - - - \ No newline at end of file
--- a/DependencyLoader/load.xml Sun Dec 05 00:12:57 2010 -0800 +++ b/DependencyLoader/load.xml Sun Dec 05 03:10:07 2010 -0800 @@ -1,1 +1,1 @@ -<ui xsi:schemaLocation="http://www.blizzard.com/wow/ui/ ..\FrameXML\UI.xsd"> <script file="start.lua"/> <script file="class.lua"/> <script file="Addon.lua"/> <script file="Core.lua"/> <script file="frontend.lua"/> </ui> \ No newline at end of file +<ui xsi:schemaLocation="http://www.blizzard.com/wow/ui/ ..\FrameXML\UI.xsd"> <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
--- a/DependencyLoader_Bootstrap/DependencyLoader.toc Sun Dec 05 00:12:57 2010 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,11 +0,0 @@ -## Interface: 40000 - -## Notes: Bootstrap for DependencyLoader_Core -## Author: mckenziemc - -## LoadManagers: !!!LoadFirst, AddonLoader -## X-LoadFirst: true -## X-LoadOn-Always: true - - -load.xml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/DependencyLoader_Bootstrap/DependencyLoader_Bootstrap.toc Sun Dec 05 03:10:07 2010 -0800 @@ -0,0 +1,13 @@ +## Interface: 40000 + +## Title: DependencyLoader Bootstrap +## Notes: Bootstrap for DependencyLoader + +## Author: mckenziemc + +## LoadManagers: !!!LoadFirst, AddonLoader +## X-LoadFirst: true +## X-LoadOn-Always: true + + +load.xml
--- a/DependencyLoader_Bootstrap/bootstrap.lua Sun Dec 05 00:12:57 2010 -0800 +++ b/DependencyLoader_Bootstrap/bootstrap.lua Sun Dec 05 03:10:07 2010 -0800 @@ -6,14 +6,18 @@ local addonName, addonTable = ... + +print("loading DependencyLoader_Bootstrap") + -- TODO: move and use dependency parsing function here? -local dependencies = {"LibStub", "LibPrint-1.0", "Ace3"} +local dependencies = {"LibStub", "Ace3", "LibBuilder-1.0", "LibPrint-1.0", "LibScriptLink-1.0"} local canLoad = true for _, addon in pairs(dependencies) do local reason = select(6, GetAddOnInfo(addon)) - if reason ~= nil and reason ~= "DISABLED" then + if reason ~= nil and reason ~= "DISABLED" and reason ~= "DEP_DISABLED" then + print("Can't load", addon) canLoad = false break end @@ -25,12 +29,13 @@ end -print("Loading DependencyLoader") +print("bootstrap: Loading DependencyLoader") for _, addon in pairs(dependencies) do EnableAddOn(addon) + LoadAddOn(addon) end -EnableAddOn("DependencyLoader_Core") -LoadAddOn("DependencyLoader_Core") +EnableAddOn("DependencyLoader") +LoadAddOn("DependencyLoader")
--- a/DependencyLoader_Errata/DependencyLoader_Errata.toc Sun Dec 05 00:12:57 2010 -0800 +++ b/DependencyLoader_Errata/DependencyLoader_Errata.toc Sun Dec 05 03:10:07 2010 -0800 @@ -1,5 +1,8 @@ ## Interface: 40000 +## Title: DependencyLoader Errata +## Notes: Errata for other addons' dependency info. + ## Author: mckenziemc ## Dependencies: DependencyLoader