annotate DependencyLoader/Tree.lua @ 16:1d8898cd1c82

removed the unused code from Core.lua
author mckenziemc
date Sat, 11 Dec 2010 01:54:15 -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