annotate DependencyLoader_Core/Core.lua @ 8:930871e163bc

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