Mercurial > wow > dependencyloader
comparison DependencyLoader/Tree.lua @ 10:e0a4a8b5b389
lots more modifications...
| author | mckenziemc |
|---|---|
| date | Sun, 05 Dec 2010 03:10:07 -0800 |
| parents | 5362e308c3eb |
| children | b230b94d4487 |
comparison
equal
deleted
inserted
replaced
| 9:5362e308c3eb | 10:e0a4a8b5b389 |
|---|---|
| 4 | 4 |
| 5 | 5 |
| 6 local addonName, addonTable = ... | 6 local addonName, addonTable = ... |
| 7 | 7 |
| 8 | 8 |
| 9 -- TODO: prevent infinite loops in the recursive functions | 9 -- FIXME: prevent infinite loops in the recursive functions |
| 10 | 10 |
| 11 | 11 |
| 12 local Tree, tree = addonTable:NewClass("Tree") | 12 local Tree, tree = addonTable:NewClass("Tree") |
| 13 | 13 |
| 14 | 14 |
| 15 Tree.trees = {} | 15 Tree.trees = {} |
| 16 | |
| 16 | 17 |
| 17 -- internal | 18 -- internal |
| 18 -- Creates a new tree object | 19 -- Creates a new tree object |
| 19 -- @param root Name, index, or Addon object of the root addon. | 20 -- @param root Name, index, or Addon object of the root addon. |
| 20 function Tree:New(root) | 21 function Tree:New(root) |
| 66 | 67 |
| 67 return bitfield | 68 return bitfield |
| 68 end | 69 end |
| 69 | 70 |
| 70 | 71 |
| 71 -- Checks if the tree rooted at the specified addon can be force-loaded. | 72 --- Checks if this tree can be force-loaded. |
| 72 -- @param root The name or index of the root addon. | 73 -- Does not check user settings nor if force-loading is actually available. |
| 73 function core:CanForceLoadTree(root) | 74 -- @return canForceLoad True if this tree can be force loaded, false otherwise |
| 74 -- TODO: if some addons have already loaded, we have to check | 75 function tree:CanForceLoad() |
| 75 -- forceafter for those and forcebefore for the others | 76 if self.root:IsLoaded() then |
| 76 return false | 77 return true |
| 78 end | |
| 79 | |
| 80 if not self.root:CanForceLoad() then | |
| 81 return false | |
| 82 end | |
| 83 | |
| 84 -- now check dependencies recursively | |
| 85 local dependencies = {self.root:GetDependencies()} | |
| 86 for i, depName in pairs(dependencies) do | |
| 87 local depTree = Tree:Get(depName) | |
| 88 | |
| 89 if not depTree:CanForceLoad() then | |
| 90 return false | |
| 91 end | |
| 92 end | |
| 93 | |
| 94 return | |
| 77 end | 95 end |
| 78 | 96 |
| 79 | 97 |
| 80 -- NOTE: any tree that can be loaded on demand is also eligible for force-loading | 98 -- NOTE: any tree that can be loaded on demand is also eligible for force-loading |
| 81 -- Checks if the tree rooted at the specified addon can be loaded on demand. | 99 -- Checks if the tree can be loaded on demand. |
| 82 -- @param root The name or index of the root addon. | 100 function tree:CanLoD() |
| 83 function core:CanLoDTree(root) | |
| 84 local bitfield = self:GetLoadBitfield() | |
| 85 root = self:GetAddon(root) | |
| 86 assert(root) | |
| 87 | |
| 88 -- since this will be used recursively, return true if | 101 -- since this will be used recursively, return true if |
| 89 -- this is already loaded. | 102 -- this is already loaded. |
| 90 if root:IsLoaded() then | 103 if self.root:IsLoaded() then |
| 91 return true | 104 return true |
| 92 end | 105 end |
| 93 | 106 |
| 94 -- true if all dependencies are loaded or LoD | 107 -- true if all dependencies are loaded or LoD |
| 95 | 108 |
| 96 if not root:CanLoD() then | 109 if not self.root:CanLoD() then |
| 97 return false | 110 return false |
| 98 end | 111 end |
| 99 | 112 |
| 100 -- now check dependencies recursively | 113 -- now check dependencies recursively |
| 101 local dependencies = {root:GetDependencies()} | 114 local dependencies = {root:GetDependencies()} |
| 102 for i, depName in pairs(dependencies) do | 115 for i, depName in pairs(dependencies) do |
| 103 local dep = self:GetAddon(depName) | 116 local depTree = Tree:Get(depName) |
| 104 | 117 |
| 105 if not dep then | 118 if not depTree:CanLoD() then |
| 106 return false -- missing | 119 return false |
| 107 end | |
| 108 | |
| 109 if not dep:IsLoaded() then | |
| 110 if not self:CanLoDTree(depName) then | |
| 111 return false | |
| 112 end | |
| 113 end | 120 end |
| 114 end | 121 end |
| 115 | 122 |
| 116 return true | 123 return true |
| 117 end | 124 end |
| 119 | 126 |
| 120 -- Checks if the tree rooted at the specified addon | 127 -- Checks if the tree rooted at the specified addon |
| 121 -- can be loaded if all dependencies are enabled | 128 -- can be loaded if all dependencies are enabled |
| 122 -- the UI is reloaded. | 129 -- the UI is reloaded. |
| 123 -- Basically makes sure all dependencies are installed. | 130 -- Basically makes sure all dependencies are installed. |
| 124 function core:CanReloadTree(root) | 131 function tree:CanLoad() |
| 125 -- convert root to an Addon object | 132 if self.root:IsLoaded() then |
| 126 root = self:GetAddon(root) | |
| 127 assert(root) | |
| 128 | |
| 129 if root:IsLoaded() then | |
| 130 return true | 133 return true |
| 131 -- FIXME: deps may have been disabled | 134 -- FIXME: deps may have been disabled |
| 132 end | 135 end |
| 133 | 136 |
| 134 -- TODO: make sure the root isn't incompatible | 137 -- TODO: make sure the root isn't incompatible |
| 135 | 138 |
| 136 -- now check dependencies recursively | 139 -- now check dependencies recursively |
| 137 -- FIXME: prevent infinite recursion | 140 -- FIXME: prevent infinite recursion |
| 138 | 141 |
| 139 local dependencies = {root:GetDependencies()} | 142 local dependencies = {self.root:GetDependencies()} |
| 140 for i, depName in pairs(dependencies) do | 143 for i, depName in pairs(dependencies) do |
| 141 local dep = self:GetAddon(depName) | 144 local depTree = Tree:Get(depName) |
| 142 | 145 |
| 143 if dep == nil then | 146 if not depTree:CanLoad() then |
| 144 return false -- missing dependency | 147 return false -- missing dependency |
| 145 end | 148 end |
| 146 | 149 |
| 147 -- TODO: make sure it's compatible | 150 -- TODO: make sure it's compatible |
| 148 end | 151 end |
| 149 | 152 |
| 150 return true | 153 return true |
| 151 end | 154 end |
| 152 | 155 |
| 156 --[[ | |
| 153 -- Loads the tree rooted at the specified addon. | 157 -- Loads the tree rooted at the specified addon. |
| 154 -- FIXME: load the root too or not? | 158 -- FIXME: load the root too or not? |
| 155 -- Supports both LoD addons and those that require force-loading. | 159 -- Supports both LoD addons and those that require force-loading. |
| 156 function core:LoadTree(addon) | 160 function tree:Load(addon) |
| 157 -- don't check if the tree can actually be loaded. | 161 -- don't check if the tree can actually be loaded. |
| 158 -- external code should do that itself to check if it | 162 -- external code should do that itself to check if it |
| 159 -- should even call this at all. | 163 -- should even call this at all. |
| 160 | 164 |
| 161 if self:ForceLoadAvailable() then | 165 if self:ForceLoadAvailable() then |
| 163 self:ForceLoadTree(addon) | 167 self:ForceLoadTree(addon) |
| 164 else | 168 else |
| 165 self:LoadLoDTree(addon) | 169 self:LoadLoDTree(addon) |
| 166 end | 170 end |
| 167 end | 171 end |
| 172 ]] | |
| 168 | 173 |
| 169 | 174 |
| 170 -- load the root too, since it may actually be a leaf | 175 -- load the root too, since it may actually be a leaf |
| 171 function core:ForceLoadTree(root) | 176 function tree:ForceLoad() |
| 172 root = self:GetAddon(root) | |
| 173 assert(root) | |
| 174 | |
| 175 -- load dependencies | 177 -- load dependencies |
| 176 local dependencies = {root:GetDependencies(addon)} | 178 local dependencies = {self.root:GetDependencies()} |
| 177 for i, depName in pairs(dependencies) do | 179 for i, depName in pairs(dependencies) do |
| 178 self:ForceLoadTree(depName) | 180 local depTree = Tree:Get(depName) |
| 181 depTree:ForceLoad() | |
| 179 end | 182 end |
| 180 | 183 |
| 181 -- load embeds, if they are available separately | 184 -- load embeds, if they are available separately |
| 182 local embeds = {root:GetEmbeds(addon)} | 185 local embeds = {self.root:GetEmbeds()} |
| 183 for i, embedName in pairs(embeds) do | 186 for i, embedName in pairs(embeds) do |
| 184 if Addon:Exists(embedName) then | 187 local embedTree = Tree:Get(embedName) |
| 185 self:ForceLoadTree(embedName) | 188 embedTree:ForceLoad() |
| 186 end | |
| 187 end | 189 end |
| 188 | 190 |
| 189 root:ForceLoad() | 191 root:ForceLoad() |
| 190 end | 192 end |
| 191 | 193 |
| 192 | 194 |
| 195 --[[ don't think i need this | |
| 193 function core:LoadLoDTree(root) | 196 function core:LoadLoDTree(root) |
| 194 root = self:GetAddon(root) | 197 root = self:GetAddon(root) |
| 195 assert(root) | 198 assert(root) |
| 196 | 199 |
| 197 -- load dependencies | 200 -- load dependencies |
| 208 end | 211 end |
| 209 end | 212 end |
| 210 | 213 |
| 211 root:LoD() | 214 root:LoD() |
| 212 end | 215 end |
| 216 ]] | |
| 213 | 217 |
| 214 | 218 |
| 215 -- I think the problem this solves is a major issue with | 219 -- I think the problem this solves is a major issue with |
| 216 -- migrating to separate libs. think about it more and document | 220 -- migrating to separate libs. think about it more and document |
| 217 -- here and in project description | 221 -- here and in project description |
| 218 function core:PrepareLoDTree(root) | 222 function tree:PrepareForLoD() |
| 219 root = self:GetAddon(root) | |
| 220 assert(root) | |
| 221 | |
| 222 -- assume root is LoD | 223 -- assume root is LoD |
| 223 | 224 |
| 224 -- check dependencies | 225 -- check dependencies |
| 225 local dependencies = {root:GetDependencies(addon)} | 226 local dependencies = {root:GetDependencies(addon)} |
| 226 for i, depName in pairs(dependencies) do | 227 for i, depName in pairs(dependencies) do |
| 227 local dep = self:GetAddon(depName) | 228 local depTree = Tree:Get(depName) |
| 228 | 229 depTree:PrepareForLoD() |
| 229 -- assume external code made sure it exists | 230 |
| 230 | 231 --[[ |
| 231 if dep:CanLoD() then | 232 if dep:CanLoD() then |
| 232 -- don't load it now but make sure its dependencies are prepared | 233 -- don't load it now but make sure its dependencies are prepared |
| 233 self:PrepareLoDTree(depName) | 234 self:PrepareLoDTree(depName) |
| 234 else | 235 else |
| 235 -- FIXME: if it's already loaded | 236 -- FIXME: if it's already loaded |
| 236 -- force-load it now so we can load the parent on demand | 237 -- force-load it now so we can load the parent on demand |
| 237 self:ForceLoadTree(depName) | 238 self:ForceLoadTree(depName) |
| 238 end | 239 end |
| 240 ]] | |
| 239 end | 241 end |
| 240 | 242 |
| 241 -- prepare embeds, if they are available separately | 243 -- prepare embeds, if they are available separately |
| 242 local embeds = {root:GetEmbeds(addon)} -- FIXME: addon? | 244 local embeds = {root:GetEmbeds(addon)} -- FIXME: addon? |
| 243 for i, embedName in pairs(embeds) do | 245 for i, embedName in pairs(embeds) do |
| 244 local embed = self:GetAddon(embedName) | 246 local embedTree = Tree:Get(embedName) |
| 245 | 247 embedTree:PrepareForLoD() |
| 248 | |
| 249 --[[ | |
| 246 if embed then | 250 if embed then |
| 247 if embed:CanLoD() then | 251 if embed:CanLoD() then |
| 248 -- don't load it now but make sure its dependencies are prepared | 252 -- don't load it now but make sure its dependencies are prepared |
| 249 self:PrepareLoDTree(embedName) | 253 self:PrepareLoDTree(embedName) |
| 250 else | 254 else |
| 251 -- FIXME: if it's already loaded | 255 -- FIXME: if it's already loaded |
| 252 -- force-load it now so we can load the parent on demand | 256 -- force-load it now so we can load the parent on demand |
| 253 self:ForceLoadTree(depName) | 257 self:ForceLoadTree(depName) |
| 254 end | 258 end |
| 255 end | 259 end |
| 256 end | 260 ]] |
| 257 end | 261 end |
| 258 | 262 end |
| 259 | 263 |
| 260 function Core:PrepareReloadTree(addon) | 264 |
| 261 root = self:GetAddon(root) | 265 function tree:PrepareForReload() |
| 262 assert(root) | 266 self.root:Enable() |
| 263 | |
| 264 root:Enable() | |
| 265 | 267 |
| 266 -- check dependencies | 268 -- check dependencies |
| 267 local dependencies = {root:GetDependencies()} | 269 local dependencies = {self.root:GetDependencies()} |
| 268 for i, depName in pairs(dependencies) do | 270 for i, depName in pairs(dependencies) do |
| 269 self:PrepareReloadTree(depName) | 271 Tree:Get(depName):PrepareForReload() |
| 270 end | 272 end |
| 271 | 273 |
| 272 -- prepare embeds, if they are available separately | 274 -- prepare embeds, if they are available separately |
| 273 local embeds = {root:GetEmbeds(addon)} | 275 local embeds = {self.root:GetEmbeds(addon)} |
| 274 for i, embedName in pairs(embeds) do | 276 for i, embedName in pairs(embeds) do |
| 275 local embed = self:GetAddon(embedName) | 277 Tree:Get(embedName):PrepareForReload() |
| 276 | 278 end |
| 277 if embed then | 279 end |
| 278 self:PrepareReloadTree(embedName) | |
| 279 end | |
| 280 end | |
| 281 end | |
| 282 | |
| 283 | |
| 284 function Core:ForceLoadAvailable() | |
| 285 return true | |
| 286 -- FIXME: use field and a frame registered for PLAYER_LOGIN | |
| 287 end |
