annotate DependencyLoader/Core.lua @ 11:47d15fc9208e

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