annotate DependencyLoader/Core.lua @ 10:e0a4a8b5b389

lots more modifications...
author mckenziemc
date Sun, 05 Dec 2010 03:10:07 -0800
parents 5362e308c3eb
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