annotate DependencyLoader/Core.lua @ 15:a46bf694050c

cleaned up Tree's methods a bit and improved documentation Addon:Exists will now return false for Blizzard addons (needs to be handled better) Addon.lua will now use the raw hooks from the interface module fixed the inverted returns from IsForceLoadAvailable EnableAddOn and LoadAddOn hooks will now skip the extra processing if the addon does not exist or is a Blizzard addon moved the EnableAddOn queing to the interface
author mckenziemc
date Sat, 11 Dec 2010 01:48:39 -0800
parents 78b28ebdc169
children 1d8898cd1c82
rev   line source
mckenziemc@8 1
mckenziemc@0 2
mckenziemc@0 3
mckenziemc@0 4 local addonName, addonTable = ...
mckenziemc@0 5
mckenziemc@0 6
mckenziemc@14 7 -- NOTE: current contents of this file are no longer used
mckenziemc@10 8 if true then
mckenziemc@10 9 return
mckenziemc@10 10 end
mckenziemc@10 11
mckenziemc@0 12 local Core, core = addonTable:NewClass("Core")
mckenziemc@0 13
mckenziemc@0 14
mckenziemc@0 15 function Core:New()
mckenziemc@0 16 local instance = {}
mckenziemc@0 17 setmetatable(instance, self.instanceMetatable)
mckenziemc@0 18
mckenziemc@0 19 instance.addons = {}
mckenziemc@0 20 instance.nameToIndex = {}
mckenziemc@0 21
mckenziemc@0 22 for i=1,GetNumAddOns() do
mckenziemc@0 23 local newAddon = Addon:New(i)
mckenziemc@0 24
mckenziemc@0 25 instance.addons[i] = newAddon
mckenziemc@0 26 instance.nameToIndex[newAddon:GetName()] = i
mckenziemc@0 27 end
mckenziemc@0 28
mckenziemc@0 29 -- TODO: enable dependencies for any addons that have already loaded
mckenziemc@0 30
mckenziemc@0 31 return instance
mckenziemc@0 32 end
mckenziemc@0 33
mckenziemc@0 34
mckenziemc@0 35 -- @param addon Name or index of the addon to retrieve.
mckenziemc@0 36 -- @return The addon object, or nil if not found
mckenziemc@0 37 function core:GetAddon(addon)
mckenziemc@0 38 if not Addon:Exists(addon) then
mckenziemc@0 39 return nil
mckenziemc@0 40 end
mckenziemc@0 41
mckenziemc@0 42 local index
mckenziemc@0 43
mckenziemc@0 44 if type(addon) == "string" then
mckenziemc@0 45 index = self.nameToIndex[addon]
mckenziemc@0 46 elseif type(addon) == "number" then
mckenziemc@0 47 index = addon
mckenziemc@0 48 end
mckenziemc@0 49
mckenziemc@0 50 return self.addons[index]
mckenziemc@0 51 end
mckenziemc@0 52
mckenziemc@0 53
mckenziemc@0 54 -- Checks if the tree rooted at the specified addon can be force-loaded.
mckenziemc@0 55 -- @param root The name or index of the root addon.
mckenziemc@0 56 function core:CanForceLoadTree(root)
mckenziemc@0 57 -- convert root to an Addon object
mckenziemc@0 58 root = self:GetAddon(root)
mckenziemc@0 59 assert(root)
mckenziemc@0 60
mckenziemc@0 61 if root:IsLoaded() then
mckenziemc@0 62 return true
mckenziemc@0 63 end
mckenziemc@0 64
mckenziemc@0 65 -- check if the root itself can be force-loaded
mckenziemc@0 66 if not root:CanForceLoad() then
mckenziemc@0 67 return false
mckenziemc@0 68 end
mckenziemc@0 69
mckenziemc@0 70 -- now check dependencies recursively
mckenziemc@0 71 -- FIXME: prevent infinite recursion
mckenziemc@0 72
mckenziemc@0 73 local dependencies = {root:GetDependencies()}
mckenziemc@0 74 for i, depName in pairs(dependencies) do
mckenziemc@0 75 local dep = self:GetAddon(depName)
mckenziemc@0 76
mckenziemc@0 77 if dep == nil then
mckenziemc@0 78 return false -- missing dependency
mckenziemc@0 79 end
mckenziemc@0 80
mckenziemc@0 81 -- if it's already loaded then skip to next one
mckenziemc@0 82 if not dep:IsLoaded() then
mckenziemc@0 83 if not self:CanForceLoadTree(depName) then
mckenziemc@0 84 return false
mckenziemc@0 85 end
mckenziemc@0 86 end
mckenziemc@0 87 end
mckenziemc@0 88
mckenziemc@0 89 return true
mckenziemc@0 90 end
mckenziemc@0 91
mckenziemc@0 92 -- NOTE: any tree that can be loaded on demand is also eligible for force-loading
mckenziemc@0 93 -- Checks if the tree rooted at the specified addon can be loaded on demand.
mckenziemc@0 94 -- @param root The name or index of the root addon.
mckenziemc@0 95 function core:CanLoDTree(root)
mckenziemc@0 96 root = self:GetAddon(root)
mckenziemc@0 97 assert(root)
mckenziemc@0 98
mckenziemc@0 99 -- since this will be used recursively, return true if
mckenziemc@0 100 -- this is already loaded.
mckenziemc@0 101 if root:IsLoaded() then
mckenziemc@0 102 return true
mckenziemc@0 103 end
mckenziemc@0 104
mckenziemc@0 105 -- true if all dependencies are loaded or LoD
mckenziemc@0 106
mckenziemc@0 107 if not root:CanLoD() then
mckenziemc@0 108 return false
mckenziemc@0 109 end
mckenziemc@0 110
mckenziemc@0 111 -- now check dependencies recursively
mckenziemc@0 112 local dependencies = {root:GetDependencies()}
mckenziemc@0 113 for i, depName in pairs(dependencies) do
mckenziemc@0 114 local dep = self:GetAddon(depName)
mckenziemc@0 115
mckenziemc@0 116 if not dep then
mckenziemc@0 117 return false -- missing
mckenziemc@0 118 end
mckenziemc@0 119
mckenziemc@0 120 if not dep:IsLoaded() then
mckenziemc@0 121 if not self:CanLoDTree(depName) then
mckenziemc@0 122 return false
mckenziemc@0 123 end
mckenziemc@0 124 end
mckenziemc@0 125 end
mckenziemc@0 126
mckenziemc@0 127 return true
mckenziemc@0 128 end
mckenziemc@0 129
mckenziemc@0 130
mckenziemc@0 131 -- Checks if the tree rooted at the specified addon
mckenziemc@0 132 -- can be loaded if all dependencies are enabled
mckenziemc@0 133 -- the UI is reloaded.
mckenziemc@0 134 -- Basically makes sure all dependencies are installed.
mckenziemc@0 135 function core:CanReloadTree(root)
mckenziemc@0 136 -- convert root to an Addon object
mckenziemc@0 137 root = self:GetAddon(root)
mckenziemc@0 138 assert(root)
mckenziemc@0 139
mckenziemc@0 140 if root:IsLoaded() then
mckenziemc@0 141 return true
mckenziemc@0 142 -- FIXME: deps may have been disabled
mckenziemc@0 143 end
mckenziemc@0 144
mckenziemc@0 145 -- TODO: make sure the root isn't incompatible
mckenziemc@0 146
mckenziemc@0 147 -- now check dependencies recursively
mckenziemc@0 148 -- FIXME: prevent infinite recursion
mckenziemc@0 149
mckenziemc@0 150 local dependencies = {root:GetDependencies()}
mckenziemc@0 151 for i, depName in pairs(dependencies) do
mckenziemc@0 152 local dep = self:GetAddon(depName)
mckenziemc@0 153
mckenziemc@0 154 if dep == nil then
mckenziemc@0 155 return false -- missing dependency
mckenziemc@0 156 end
mckenziemc@0 157
mckenziemc@0 158 -- TODO: make sure it's compatible
mckenziemc@0 159 end
mckenziemc@0 160
mckenziemc@0 161 return true
mckenziemc@0 162 end
mckenziemc@0 163
mckenziemc@0 164 -- Loads the tree rooted at the specified addon.
mckenziemc@0 165 -- FIXME: load the root too or not?
mckenziemc@0 166 -- Supports both LoD addons and those that require force-loading.
mckenziemc@0 167 function core:LoadTree(addon)
mckenziemc@0 168 -- don't check if the tree can actually be loaded.
mckenziemc@0 169 -- external code should do that itself to check if it
mckenziemc@0 170 -- should even call this at all.
mckenziemc@0 171
mckenziemc@0 172 if self:ForceLoadAvailable() then
mckenziemc@0 173 -- LoD trees can also be force-loaded
mckenziemc@0 174 self:ForceLoadTree(addon)
mckenziemc@0 175 else
mckenziemc@0 176 self:LoadLoDTree(addon)
mckenziemc@0 177 end
mckenziemc@0 178 end
mckenziemc@0 179
mckenziemc@0 180
mckenziemc@0 181 -- load the root too, since it may actually be a leaf
mckenziemc@0 182 function core:ForceLoadTree(root)
mckenziemc@0 183 root = self:GetAddon(root)
mckenziemc@0 184 assert(root)
mckenziemc@0 185
mckenziemc@0 186 -- load dependencies
mckenziemc@0 187 local dependencies = {root:GetDependencies(addon)}
mckenziemc@0 188 for i, depName in pairs(dependencies) do
mckenziemc@0 189 self:ForceLoadTree(depName)
mckenziemc@0 190 end
mckenziemc@0 191
mckenziemc@0 192 -- load embeds, if they are available separately
mckenziemc@0 193 local embeds = {root:GetEmbeds(addon)}
mckenziemc@0 194 for i, embedName in pairs(embeds) do
mckenziemc@0 195 if Addon:Exists(embedName) then
mckenziemc@0 196 self:ForceLoadTree(embedName)
mckenziemc@0 197 end
mckenziemc@0 198 end
mckenziemc@0 199
mckenziemc@0 200 root:ForceLoad()
mckenziemc@0 201 end
mckenziemc@0 202
mckenziemc@0 203
mckenziemc@0 204 function core:LoadLoDTree(root)
mckenziemc@0 205 root = self:GetAddon(root)
mckenziemc@0 206 assert(root)
mckenziemc@0 207
mckenziemc@0 208 -- load dependencies
mckenziemc@0 209 local dependencies = {root:GetDependencies(addon)}
mckenziemc@0 210 for i, depName in pairs(dependencies) do
mckenziemc@0 211 self:LoadLoDTree(depName)
mckenziemc@0 212 end
mckenziemc@0 213
mckenziemc@0 214 -- load embeds, if they are available separately
mckenziemc@0 215 local embeds = {root:GetEmbeds(addon)}
mckenziemc@0 216 for i, embedName in pairs(embeds) do
mckenziemc@0 217 if Addon:Exists(embedName) then
mckenziemc@0 218 self:LoadLoDTree(embedName)
mckenziemc@0 219 end
mckenziemc@0 220 end
mckenziemc@0 221
mckenziemc@0 222 root:LoD()
mckenziemc@0 223 end
mckenziemc@0 224
mckenziemc@0 225
mckenziemc@0 226 -- I think the problem this solves is a major issue with
mckenziemc@0 227 -- migrating to separate libs. think about it more and document
mckenziemc@0 228 -- here and in project description
mckenziemc@0 229 function core:PrepareLoDTree(root)
mckenziemc@0 230 root = self:GetAddon(root)
mckenziemc@0 231 assert(root)
mckenziemc@0 232
mckenziemc@0 233 -- assume root is LoD
mckenziemc@0 234
mckenziemc@0 235 -- check dependencies
mckenziemc@0 236 local dependencies = {root:GetDependencies(addon)}
mckenziemc@0 237 for i, depName in pairs(dependencies) do
mckenziemc@0 238 local dep = self:GetAddon(depName)
mckenziemc@0 239
mckenziemc@0 240 -- assume external code made sure it exists
mckenziemc@0 241
mckenziemc@0 242 if dep:CanLoD() then
mckenziemc@0 243 -- don't load it now but make sure its dependencies are prepared
mckenziemc@0 244 self:PrepareLoDTree(depName)
mckenziemc@0 245 else
mckenziemc@0 246 -- FIXME: if it's already loaded
mckenziemc@0 247 -- force-load it now so we can load the parent on demand
mckenziemc@0 248 self:ForceLoadTree(depName)
mckenziemc@0 249 end
mckenziemc@0 250 end
mckenziemc@0 251
mckenziemc@0 252 -- prepare embeds, if they are available separately
mckenziemc@0 253 local embeds = {root:GetEmbeds(addon)} -- FIXME: addon?
mckenziemc@0 254 for i, embedName in pairs(embeds) do
mckenziemc@0 255 local embed = self:GetAddon(embedName)
mckenziemc@0 256
mckenziemc@0 257 if embed then
mckenziemc@0 258 if embed:CanLoD() then
mckenziemc@0 259 -- don't load it now but make sure its dependencies are prepared
mckenziemc@0 260 self:PrepareLoDTree(embedName)
mckenziemc@0 261 else
mckenziemc@0 262 -- FIXME: if it's already loaded
mckenziemc@0 263 -- force-load it now so we can load the parent on demand
mckenziemc@0 264 self:ForceLoadTree(depName)
mckenziemc@0 265 end
mckenziemc@0 266 end
mckenziemc@0 267 end
mckenziemc@0 268 end
mckenziemc@0 269
mckenziemc@0 270
mckenziemc@0 271 function Core:PrepareReloadTree(addon)
mckenziemc@0 272 root = self:GetAddon(root)
mckenziemc@0 273 assert(root)
mckenziemc@0 274
mckenziemc@0 275 root:Enable()
mckenziemc@0 276
mckenziemc@0 277 -- check dependencies
mckenziemc@0 278 local dependencies = {root:GetDependencies()}
mckenziemc@0 279 for i, depName in pairs(dependencies) do
mckenziemc@0 280 self:PrepareReloadTree(depName)
mckenziemc@0 281 end
mckenziemc@0 282
mckenziemc@0 283 -- prepare embeds, if they are available separately
mckenziemc@0 284 local embeds = {root:GetEmbeds(addon)}
mckenziemc@0 285 for i, embedName in pairs(embeds) do
mckenziemc@0 286 local embed = self:GetAddon(embedName)
mckenziemc@0 287
mckenziemc@0 288 if embed then
mckenziemc@0 289 self:PrepareReloadTree(embedName)
mckenziemc@0 290 end
mckenziemc@0 291 end
mckenziemc@0 292 end
mckenziemc@0 293
mckenziemc@0 294
mckenziemc@0 295 function Core:ForceLoadAvailable()
mckenziemc@0 296 return true
mckenziemc@0 297 -- FIXME: use field and a frame registered for PLAYER_LOGIN
mckenziemc@0 298 end