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 |