Mercurial > wow > dependencyloader
view DependencyLoader_Core/Core.lua @ 0:9852fcd5e59e
initial import
author | mckenziemc |
---|---|
date | Tue, 30 Nov 2010 16:13:04 -0800 |
parents | |
children | 930871e163bc |
line wrap: on
line source
local addonName, addonTable = ... print("running Core.lua") -- TODO: prevent infinite loops in the recursive functions local Core, core = addonTable:NewClass("Core") local Addon = addonTable.classes.Addon function Core:New() local instance = {} setmetatable(instance, self.instanceMetatable) instance.addons = {} instance.nameToIndex = {} for i=1,GetNumAddOns() do local newAddon = Addon:New(i) instance.addons[i] = newAddon instance.nameToIndex[newAddon:GetName()] = i end -- TODO: enable dependencies for any addons that have already loaded return instance end -- @param addon Name or index of the addon to retrieve. -- @return The addon object, or nil if not found function core:GetAddon(addon) if not Addon:Exists(addon) then return nil end local index if type(addon) == "string" then index = self.nameToIndex[addon] elseif type(addon) == "number" then index = addon end return self.addons[index] 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) -- convert root to an Addon object root = self:GetAddon(root) assert(root) if root:IsLoaded() then return true end -- check if the root itself can be force-loaded if not root:CanForceLoad() then return false end -- now check dependencies recursively -- FIXME: prevent infinite recursion local dependencies = {root:GetDependencies()} for i, depName in pairs(dependencies) do local dep = self:GetAddon(depName) if dep == nil then return false -- missing dependency end -- if it's already loaded then skip to next one if not dep:IsLoaded() then if not self:CanForceLoadTree(depName) then return false end end end return true 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) root = self:GetAddon(root) assert(root) -- since this will be used recursively, return true if -- this is already loaded. if root:IsLoaded() then return true end -- true if all dependencies are loaded or LoD if not 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) if not dep then return false -- missing end if not dep:IsLoaded() then if not self:CanLoDTree(depName) then return false end end end return true end -- Checks if the tree rooted at the specified addon -- 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 return true -- FIXME: deps may have been disabled end -- TODO: make sure the root isn't incompatible -- now check dependencies recursively -- FIXME: prevent infinite recursion local dependencies = {root:GetDependencies()} for i, depName in pairs(dependencies) do local dep = self:GetAddon(depName) if dep == nil then return false -- missing dependency end -- TODO: make sure it's compatible end 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) -- 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. if self:ForceLoadAvailable() then -- LoD trees can also be force-loaded self:ForceLoadTree(addon) else 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) -- load dependencies local dependencies = {root:GetDependencies(addon)} for i, depName in pairs(dependencies) do self:ForceLoadTree(depName) end -- load embeds, if they are available separately local embeds = {root:GetEmbeds(addon)} for i, embedName in pairs(embeds) do if Addon:Exists(embedName) then self:ForceLoadTree(embedName) end end root:ForceLoad() end function core:LoadLoDTree(root) root = self:GetAddon(root) assert(root) -- load dependencies local dependencies = {root:GetDependencies(addon)} for i, depName in pairs(dependencies) do self:LoadLoDTree(depName) end -- load embeds, if they are available separately local embeds = {root:GetEmbeds(addon)} for i, embedName in pairs(embeds) do if Addon:Exists(embedName) then self:LoadLoDTree(embedName) end end 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) -- assume root is LoD -- check dependencies local dependencies = {root:GetDependencies(addon)} for i, depName in pairs(dependencies) do local dep = self:GetAddon(depName) -- 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) else -- FIXME: if it's already loaded -- 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) if embed then if embed:CanLoD() then -- don't load it now but make sure its dependencies are prepared self:PrepareLoDTree(embedName) else -- FIXME: if it's already loaded -- force-load it now so we can load the parent on demand self:ForceLoadTree(depName) end end end end function Core:PrepareReloadTree(addon) root = self:GetAddon(root) assert(root) root:Enable() -- check dependencies local dependencies = {root:GetDependencies()} for i, depName in pairs(dependencies) do self:PrepareReloadTree(depName) end -- prepare embeds, if they are available separately local embeds = {root:GetEmbeds(addon)} for i, embedName in pairs(embeds) do local embed = self:GetAddon(embedName) if embed then self:PrepareReloadTree(embedName) end end end function Core:ForceLoadAvailable() return true -- FIXME: use field and a frame registered for PLAYER_LOGIN end