annotate DependencyLoader/Tree.lua @ 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 a46bf694050c
children e7995d599184
rev   line source
mckenziemc@8 1 -- Tree
mckenziemc@8 2 -- Represents a recursive "tree" of addon
mckenziemc@8 3 -- dependencies rooted at a specific addon.
mckenziemc@8 4
mckenziemc@8 5
mckenziemc@8 6 local addonName, addonTable = ...
mckenziemc@8 7
mckenziemc@8 8
mckenziemc@10 9 -- FIXME: prevent infinite loops in the recursive functions
mckenziemc@8 10
mckenziemc@8 11
mckenziemc@8 12 local Tree, tree = addonTable:NewClass("Tree")
mckenziemc@8 13
mckenziemc@8 14
mckenziemc@15 15 local classes = addonTable.classes
mckenziemc@15 16
mckenziemc@15 17
mckenziemc@8 18 Tree.trees = {}
mckenziemc@8 19
mckenziemc@10 20
mckenziemc@15 21 --- (private) Creates a new tree object.
mckenziemc@15 22 -- Assumptions: root addon exists and is not a Blizzard addon.
mckenziemc@8 23 -- @param root Name, index, or Addon object of the root addon.
mckenziemc@8 24 function Tree:New(root)
mckenziemc@8 25 if type(root) ~= "table" then
mckenziemc@15 26 root = classes.Addon:Get(root)
mckenziemc@8 27 end
mckenziemc@8 28
mckenziemc@8 29 local instance = {}
mckenziemc@8 30 setmetatable(instance, self.instanceMetatable)
mckenziemc@8 31
mckenziemc@8 32 instance.root = root
mckenziemc@8 33
mckenziemc@8 34 return instance
mckenziemc@8 35 end
mckenziemc@8 36
mckenziemc@8 37
mckenziemc@8 38 --- Retrieves the tree rooted at the specified addon
mckenziemc@15 39 -- Assumptions: root addon exists and is not a Blizzard addon
mckenziemc@8 40 -- @param root Name, index, or Addon object of the root.
mckenziemc@8 41 function Tree:Get(root)
mckenziemc@8 42 if type(root) ~= "table" then
mckenziemc@15 43 root = classes.Addon:Get(root)
mckenziemc@8 44 end
mckenziemc@8 45
mckenziemc@8 46 local tree = self.trees[root]
mckenziemc@8 47
mckenziemc@8 48 if tree then
mckenziemc@8 49 return tree
mckenziemc@8 50 else
mckenziemc@8 51 tree = self:New(root)
mckenziemc@8 52 self.trees[root] = tree
mckenziemc@8 53 return tree
mckenziemc@8 54 end
mckenziemc@8 55 end
mckenziemc@8 56
mckenziemc@8 57
mckenziemc@15 58 -- NOTE: All tree:Can functions should check the root too.
mckenziemc@15 59 -- That way, the hooks don't have to do "if addon:Can_ and tree:Can_",
mckenziemc@15 60 -- plus the tree can cache info that includes the capabilities of the
mckenziemc@15 61 -- root addon.
mckenziemc@15 62
mckenziemc@15 63
mckenziemc@15 64 --- Checks if the tree rooted at the specified addon
mckenziemc@12 65 -- can be loaded if all dependencies are enabled
mckenziemc@12 66 -- and the UI is reloaded.
mckenziemc@12 67 -- Basically makes sure all dependencies are installed.
mckenziemc@12 68 function tree:CanLoad()
mckenziemc@15 69 local root = self.root
mckenziemc@15 70
mckenziemc@15 71 if root:IsLoaded() then
mckenziemc@15 72 return true
mckenziemc@15 73 end
mckenziemc@15 74
mckenziemc@15 75 if not root:CanLoad() then
mckenziemc@12 76 return false
mckenziemc@12 77 end
mckenziemc@12 78
mckenziemc@12 79 -- check all the dependencies
mckenziemc@15 80 local dependencies = {root:GetDependencies()}
mckenziemc@15 81
mckenziemc@8 82 for i, depName in pairs(dependencies) do
mckenziemc@15 83 if not classes.Addon:Exists(depName) then
mckenziemc@12 84 return false
mckenziemc@12 85 end
mckenziemc@12 86
mckenziemc@15 87 local dep = classes.Addon:Get(depName)
mckenziemc@15 88 local depTree = Tree:Get(dep)
mckenziemc@8 89
mckenziemc@12 90 if not depTree:CanLoad() then
mckenziemc@15 91 return false
mckenziemc@10 92 end
mckenziemc@10 93 end
mckenziemc@10 94
mckenziemc@12 95 return true
mckenziemc@8 96 end
mckenziemc@8 97
mckenziemc@8 98
mckenziemc@12 99 --- Checks if the tree can be loaded on demand.
mckenziemc@15 100 -- Does not allow for force-loading; dependencies must
mckenziemc@15 101 -- already be loaded, or enabled and LoD.
mckenziemc@10 102 function tree:CanLoD()
mckenziemc@15 103 local root = self.root
mckenziemc@15 104
mckenziemc@15 105 if root:IsLoaded() then
mckenziemc@8 106 return true
mckenziemc@8 107 end
mckenziemc@8 108
mckenziemc@15 109 if not root:CanLoD() then
mckenziemc@8 110 return false
mckenziemc@8 111 end
mckenziemc@8 112
mckenziemc@8 113 -- now check dependencies recursively
mckenziemc@15 114 local dependencies = {root:GetDependencies()}
mckenziemc@15 115
mckenziemc@8 116 for i, depName in pairs(dependencies) do
mckenziemc@15 117 if not classes.Addon:Exists(depName) then
mckenziemc@15 118 return false
mckenziemc@15 119 end
mckenziemc@15 120
mckenziemc@15 121 local dep = classes.Addon:Get(depName)
mckenziemc@15 122 local depTree = Tree:Get(dep)
mckenziemc@8 123
mckenziemc@10 124 if not depTree:CanLoD() then
mckenziemc@10 125 return false
mckenziemc@8 126 end
mckenziemc@8 127 end
mckenziemc@8 128
mckenziemc@8 129 return true
mckenziemc@8 130 end
mckenziemc@8 131
mckenziemc@8 132
mckenziemc@15 133 --- Checks if this tree can be force-loaded.
mckenziemc@15 134 -- Does not check user settings nor if force-loading is actually available.
mckenziemc@15 135 -- @return canForceLoad True if this tree can be force loaded, false otherwise
mckenziemc@15 136 function tree:CanForceLoad()
mckenziemc@15 137 local root = self.root
mckenziemc@15 138 -- TODO: remove redundencies (for now they're here for design flexibility)
mckenziemc@15 139
mckenziemc@15 140 -- this addon must be loaded, able to load-on-demand, or able to force-load
mckenziemc@15 141 if root:IsLoaded() then
mckenziemc@15 142 return true
mckenziemc@15 143 end
mckenziemc@15 144
mckenziemc@15 145 if not root:CanForceLoad() then
mckenziemc@12 146 return false
mckenziemc@8 147 end
mckenziemc@8 148
mckenziemc@8 149 -- now check dependencies recursively
mckenziemc@15 150 local dependencies = {root:GetDependencies()}
mckenziemc@15 151
mckenziemc@8 152 for i, depName in pairs(dependencies) do
mckenziemc@15 153 if not classes.Addon:Exists(depName) then
mckenziemc@12 154 return false
mckenziemc@8 155 end
mckenziemc@12 156
mckenziemc@15 157 local dep = classes.Addon:Get(depName)
mckenziemc@15 158 local depTree = Tree:Get(dep)
mckenziemc@15 159
mckenziemc@15 160 if not depTree:CanForceLoad() then
mckenziemc@15 161 return false
mckenziemc@12 162 end
mckenziemc@8 163 end
mckenziemc@8 164
mckenziemc@8 165 return true
mckenziemc@8 166 end
mckenziemc@8 167
mckenziemc@12 168
mckenziemc@15 169 --- Prepares this tree to be loaded, whether through
mckenziemc@15 170 -- a ui reload or by loading on demand.
mckenziemc@15 171 -- Assumptions: CanLoad is true for this tree
mckenziemc@15 172 function tree:PrepareForLoad()
mckenziemc@15 173 local root = self.root
mckenziemc@15 174
mckenziemc@15 175 -- The Addon class will take care of delaying enables
mckenziemc@15 176 -- till after PLAYER_LOGIN if necessary.
mckenziemc@15 177
mckenziemc@15 178 root:Enable()
mckenziemc@15 179
mckenziemc@15 180 -- enable dependencies
mckenziemc@15 181 local dependencies = {root:GetDependencies()}
mckenziemc@15 182
mckenziemc@15 183 for i, depName in pairs(dependencies) do
mckenziemc@15 184 Tree:Get(depName):PrepareForLoad()
mckenziemc@15 185 end
mckenziemc@12 186
mckenziemc@15 187 -- prepare embeds, if they are available separately
mckenziemc@15 188 local embeds = {root:GetEmbeds(addon)}
mckenziemc@12 189
mckenziemc@15 190 for i, embedName in pairs(embeds) do
mckenziemc@15 191 if classes.Addon:Exists(embedName) then
mckenziemc@15 192 Tree:Get(embedName):PrepareForLoad()
mckenziemc@12 193 end
mckenziemc@12 194 end
mckenziemc@12 195 end
mckenziemc@12 196
mckenziemc@12 197
mckenziemc@12 198 -- I think the problem this solves is a major issue with
mckenziemc@12 199 -- migrating to separate libs. think about it more and document
mckenziemc@12 200 -- here and in project description
mckenziemc@15 201
mckenziemc@15 202 --- Force-loads this addon tree. If a subtree can be loaded on
mckenziemc@15 203 -- demand, this function will enable but not load the subtree.
mckenziemc@15 204 -- Assumptions: the root addon should be force-loaded, not just enabled.
mckenziemc@15 205 --function tree:ForceLoad()
mckenziemc@15 206
mckenziemc@15 207 -- Assumptions: the root is loadable-on demand, and force-load is available.
mckenziemc@15 208 -- and tree can be force-loaded
mckenziemc@12 209 function tree:PrepareForLoD()
mckenziemc@15 210 local root = self.root
mckenziemc@12 211
mckenziemc@15 212 -- prepare dependencies first (for consistency)
mckenziemc@15 213 local dependencies = {root:GetDependencies()}
mckenziemc@15 214
mckenziemc@12 215 for i, depName in pairs(dependencies) do
mckenziemc@15 216 local dep = classes.Addon:Get(depName)
mckenziemc@12 217
mckenziemc@15 218 if not dep:IsLoaded() then
mckenziemc@15 219 if dep:CanLoD() then
mckenziemc@15 220 -- don't load it now but make sure its dependencies are prepared
mckenziemc@15 221 Tree:Get(dep):PrepareForLoD()
mckenziemc@15 222 else
mckenziemc@15 223 -- Based on our assumption about the tree, this addon
mckenziemc@15 224 -- should be able to force-load.
mckenziemc@15 225 -- force-load it now so we can load the parent on demand
mckenziemc@15 226 Tree:Get(dep):ForceLoad()
mckenziemc@15 227 end
mckenziemc@12 228 end
mckenziemc@12 229 end
mckenziemc@12 230
mckenziemc@12 231 -- prepare embeds, if they are available separately
mckenziemc@15 232 local embeds = {root:GetEmbeds()}
mckenziemc@15 233
mckenziemc@12 234 for i, embedName in pairs(embeds) do
mckenziemc@15 235 if classes.Addon:Exists(embedName) then
mckenziemc@15 236 local embed = classes.Addon:Get(embedName)
mckenziemc@15 237
mckenziemc@15 238 if not embed:IsLoaded() then
mckenziemc@15 239 if embed:CanLoD() then
mckenziemc@15 240 Tree:Get(embed):PrepareForLoD()
mckenziemc@15 241 else
mckenziemc@15 242 Tree:Get(embed):ForceLoad()
mckenziemc@15 243 end
mckenziemc@12 244 end
mckenziemc@12 245 end
mckenziemc@12 246 end
mckenziemc@15 247
mckenziemc@15 248 root:Enable()
mckenziemc@12 249 end
mckenziemc@12 250
mckenziemc@12 251
mckenziemc@15 252 --- Force-loads this tree.
mckenziemc@15 253 -- This will also load any LoD addons in the tree
mckenziemc@10 254 function tree:ForceLoad()
mckenziemc@15 255 local root = self.root
mckenziemc@15 256
mckenziemc@15 257 -- FIXME: if already loaded
mckenziemc@15 258
mckenziemc@8 259 -- load dependencies
mckenziemc@15 260 local dependencies = {root:GetDependencies()}
mckenziemc@15 261
mckenziemc@8 262 for i, depName in pairs(dependencies) do
mckenziemc@15 263 Tree:Get(depName):ForceLoad()
mckenziemc@8 264 end
mckenziemc@8 265
mckenziemc@8 266 -- load embeds, if they are available separately
mckenziemc@15 267 local embeds = {root:GetEmbeds()}
mckenziemc@15 268
mckenziemc@8 269 for i, embedName in pairs(embeds) do
mckenziemc@15 270 if classes.Addon:Exists(embedName) then
mckenziemc@15 271 Tree:Get(embedName):ForceLoad()
mckenziemc@15 272 end
mckenziemc@8 273 end
mckenziemc@8 274
mckenziemc@8 275 root:ForceLoad()
mckenziemc@8 276 end