comparison DependencyLoader/Tree.lua @ 12:b230b94d4487

fixed Addon.lua to use the unhooked EnableAddOn (still needs to be changed to grab from the interface) improved the error message when creating an Addon object on a Blizzard addon (will add direct support later) implemented the hooks on EnableAddOn and LoadAddOn rearranged functions inside Tree.lua, with some edits copied OptDeps from main module to the bootstrap module, to delegate loading to the client when possible
author mckenziemc
date Fri, 10 Dec 2010 00:21:17 -0800
parents e0a4a8b5b389
children a46bf694050c
comparison
equal deleted inserted replaced
11:47d15fc9208e 12:b230b94d4487
49 return tree 49 return tree
50 end 50 end
51 end 51 end
52 52
53 53
54 function tree:GetLoadBitfield() 54 -- Checks if the tree rooted at the specified addon
55 local bitfield = self.root:GetLoadBitfield() 55 -- can be loaded if all dependencies are enabled
56 56 -- and the UI is reloaded.
57 local dependencies = {self.root:GetDependencies()} 57 -- Basically makes sure all dependencies are installed.
58 for i, depName in pairs(dependencies) do 58 function tree:CanLoad()
59 local depTree = Tree:Get(depName) 59 if not self.root:CanLoad() then
60 60 return false
61 if depTree == nil then 61 end
62 return 0 62
63 end 63 -- check all the dependencies
64 64 local dependencies = {self.root:GetDependencies()}
65 bitfield = bit.band(bitfield, depTree:GetLoadBitfield()) 65 for i, depName in pairs(dependencies) do
66 end 66 local dep = addonTable.classes.Addon:Get(depName)
67 67
68 return bitfield 68 if not dep:CanLoad() then
69 end 69 return false
70 70 end
71 71
72 --- Checks if this tree can be force-loaded. 72 local depTree = Tree:Get(depName)
73 -- Does not check user settings nor if force-loading is actually available. 73
74 -- @return canForceLoad True if this tree can be force loaded, false otherwise 74 if not depTree:CanLoad() then
75 function tree:CanForceLoad() 75 return false -- missing dependency
76 if self.root:IsLoaded() then 76 end
77 return true 77 end
78 end 78
79 79 return true
80 if not self.root:CanForceLoad() then 80 end
81 return false 81
82 end 82
83 83 --- Checks if the tree can be loaded on demand.
84 -- now check dependencies recursively 84 -- Does not consider force-loading; dependencies must
85 local dependencies = {self.root:GetDependencies()} 85 -- be enabled and LoD, or loaded
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
95 end
96
97
98 -- NOTE: any tree that can be loaded on demand is also eligible for force-loading
99 -- Checks if the tree can be loaded on demand.
100 function tree:CanLoD() 86 function tree:CanLoD()
101 -- since this will be used recursively, return true if 87 -- since this will be used recursively, return true if
102 -- this is already loaded. 88 -- this is already loaded.
103 if self.root:IsLoaded() then 89 if self.root:IsLoaded() then
104 return true 90 return true
109 if not self.root:CanLoD() then 95 if not self.root:CanLoD() then
110 return false 96 return false
111 end 97 end
112 98
113 -- now check dependencies recursively 99 -- now check dependencies recursively
114 local dependencies = {root:GetDependencies()} 100 local dependencies = {self.root:GetDependencies()}
115 for i, depName in pairs(dependencies) do 101 for i, depName in pairs(dependencies) do
116 local depTree = Tree:Get(depName) 102 local depTree = Tree:Get(depName)
117 103
118 if not depTree:CanLoD() then 104 if not depTree:CanLoD() then
119 return false 105 return false
122 108
123 return true 109 return true
124 end 110 end
125 111
126 112
127 -- Checks if the tree rooted at the specified addon 113 --- Checks if this tree can be loaded on demand as long as
128 -- can be loaded if all dependencies are enabled 114 -- force-loading is allowed for preparing dependencies.
129 -- the UI is reloaded. 115 function tree:CanLoDWithForce()
130 -- Basically makes sure all dependencies are installed. 116 if not self.root:CanLoD() then
131 function tree:CanLoad() 117 return false
118 end
119
120 -- now check dependencies recursively
121 local dependencies = {self.root:GetDependencies()}
122 for i, depName in pairs(dependencies) do
123 local dep = addonTable.classes.Addon:Get(depName)
124 local depTree = Tree:Get(depName)
125
126 if not dep:CanLoad() then
127 return false
128 end
129
130 if dep:CanLoD() then
131 if not depTree:CanLoDWithForce() then
132 return false
133 end
134 elseif dep:CanForceLoad() then
135 if not depTree:CanForceLoad() then
136 return
137 end
138 end
139 end
140
141 return true
142 end
143
144
145
146 --- Checks if this tree can be force-loaded.
147 -- Does not check user settings nor if force-loading is actually available.
148 -- @return canForceLoad True if this tree can be force loaded, false otherwise
149 function tree:CanForceLoad()
150 -- TODO: remove redundencies (for now they're here for design flexibility)
151
152 -- this addon must be loaded, able to load-on-demand, or able to force-load
132 if self.root:IsLoaded() then 153 if self.root:IsLoaded() then
133 return true 154 return true
134 -- FIXME: deps may have been disabled 155 end
135 end 156
136 157 if not self.root:CanLoad() then
137 -- TODO: make sure the root isn't incompatible 158 return false
159 end
160
161 if not self.root:CanForceLoad() then
162 return false
163 end
138 164
139 -- now check dependencies recursively 165 -- now check dependencies recursively
140 -- FIXME: prevent infinite recursion 166 local dependencies = {self.root:GetDependencies()}
141 167 for i, depName in pairs(dependencies) do
142 local dependencies = {self.root:GetDependencies()} 168 local dep = addonTable.classes.Addon:Get(depName)
143 for i, depName in pairs(dependencies) do 169 local depTree = Tree:Get(depName)
144 local depTree = Tree:Get(depName) 170
145 171 if not dep:CanLoad() then
146 if not depTree:CanLoad() then 172 return false
147 return false -- missing dependency 173 end
148 end 174
149 175 if not dep:CanLoD() and not dep:CanForceLoad() then
150 -- TODO: make sure it's compatible 176 return false
151 end 177 end
152 178
153 return true 179 if not depTree:CanForceLoad() then
154 end 180 return false
181 end
182 end
183
184 return
185 end
186
187
155 188
156 --[[ 189 --[[
157 -- Loads the tree rooted at the specified addon. 190 -- Loads the tree rooted at the specified addon.
158 -- FIXME: load the root too or not? 191 -- FIXME: load the root too or not?
159 -- Supports both LoD addons and those that require force-loading. 192 -- Supports both LoD addons and those that require force-loading.
170 end 203 end
171 end 204 end
172 ]] 205 ]]
173 206
174 207
175 -- load the root too, since it may actually be a leaf 208 function tree:PrepareForReload()
176 function tree:ForceLoad() 209 -- if force-loading is enabled then we have to queue this if the addon isn't lod
177 -- load dependencies 210 local function callback()
178 local dependencies = {self.root:GetDependencies()} 211 self.root:Enable()
179 for i, depName in pairs(dependencies) do 212
180 local depTree = Tree:Get(depName) 213 -- check dependencies
181 depTree:ForceLoad() 214 local dependencies = {self.root:GetDependencies()}
182 end 215 for i, depName in pairs(dependencies) do
183 216 Tree:Get(depName):PrepareForReload()
184 -- load embeds, if they are available separately 217 end
185 local embeds = {self.root:GetEmbeds()} 218
186 for i, embedName in pairs(embeds) do 219 -- prepare embeds, if they are available separately
187 local embedTree = Tree:Get(embedName) 220 local embeds = {self.root:GetEmbeds(addon)}
188 embedTree:ForceLoad() 221 for i, embedName in pairs(embeds) do
189 end 222 Tree:Get(embedName):PrepareForReload()
190 223 end
191 root:ForceLoad() 224 end
192 end 225
193 226 if IsLoggedIn() then
194 227 callback()
195 --[[ don't think i need this 228 else
196 function core:LoadLoDTree(root) 229 -- TODO: replace with cleaner alternative?
197 root = self:GetAddon(root) 230 local frame = CreateFrame("Frame")
198 assert(root) 231 frame:SetScript("OnEvent", callback)
199 232 frame:RegisterEvent("PLAYER_LOGIN")
200 -- load dependencies 233 end
201 local dependencies = {root:GetDependencies(addon)} 234 end
202 for i, depName in pairs(dependencies) do
203 self:LoadLoDTree(depName)
204 end
205
206 -- load embeds, if they are available separately
207 local embeds = {root:GetEmbeds(addon)}
208 for i, embedName in pairs(embeds) do
209 if Addon:Exists(embedName) then
210 self:LoadLoDTree(embedName)
211 end
212 end
213
214 root:LoD()
215 end
216 ]]
217 235
218 236
219 -- I think the problem this solves is a major issue with 237 -- I think the problem this solves is a major issue with
220 -- migrating to separate libs. think about it more and document 238 -- migrating to separate libs. think about it more and document
221 -- here and in project description 239 -- here and in project description
222 function tree:PrepareForLoD() 240 function tree:PrepareForLoD()
223 -- assume root is LoD 241 -- assume root is LoD
224 242
225 -- check dependencies 243 -- check dependencies
226 local dependencies = {root:GetDependencies(addon)} 244 local dependencies = {self.root:GetDependencies(addon)}
227 for i, depName in pairs(dependencies) do 245 for i, depName in pairs(dependencies) do
228 local depTree = Tree:Get(depName) 246 local depTree = Tree:Get(depName)
229 depTree:PrepareForLoD() 247 depTree:PrepareForLoD()
230 248
231 --[[ 249 --[[
239 end 257 end
240 ]] 258 ]]
241 end 259 end
242 260
243 -- prepare embeds, if they are available separately 261 -- prepare embeds, if they are available separately
244 local embeds = {root:GetEmbeds(addon)} -- FIXME: addon? 262 local embeds = {self.root:GetEmbeds(addon)} -- FIXME: addon?
245 for i, embedName in pairs(embeds) do 263 for i, embedName in pairs(embeds) do
246 local embedTree = Tree:Get(embedName) 264 local embedTree = Tree:Get(embedName)
247 embedTree:PrepareForLoD() 265 embedTree:PrepareForLoD()
248 266
249 --[[ 267 --[[
260 ]] 278 ]]
261 end 279 end
262 end 280 end
263 281
264 282
265 function tree:PrepareForReload() 283 -- load the root too, since it may actually be a leaf
266 self.root:Enable() 284 function tree:ForceLoad()
267 285 -- load dependencies
268 -- check dependencies 286 local dependencies = {self.root:GetDependencies()}
269 local dependencies = {self.root:GetDependencies()} 287 for i, depName in pairs(dependencies) do
270 for i, depName in pairs(dependencies) do 288 local depTree = Tree:Get(depName)
271 Tree:Get(depName):PrepareForReload() 289 depTree:ForceLoad()
272 end 290 end
273 291
274 -- prepare embeds, if they are available separately 292 -- load embeds, if they are available separately
275 local embeds = {self.root:GetEmbeds(addon)} 293 local embeds = {self.root:GetEmbeds()}
276 for i, embedName in pairs(embeds) do 294 for i, embedName in pairs(embeds) do
277 Tree:Get(embedName):PrepareForReload() 295 local embedTree = Tree:Get(embedName)
278 end 296 embedTree:ForceLoad()
279 end 297 end
298
299 root:ForceLoad()
300 end
301
302
303 --[[ don't think i need this
304 function core:LoadLoDTree(root)
305 root = self:GetAddon(root)
306 assert(root)
307
308 -- load dependencies
309 local dependencies = {root:GetDependencies(addon)}
310 for i, depName in pairs(dependencies) do
311 self:LoadLoDTree(depName)
312 end
313
314 -- load embeds, if they are available separately
315 local embeds = {root:GetEmbeds(addon)}
316 for i, embedName in pairs(embeds) do
317 if Addon:Exists(embedName) then
318 self:LoadLoDTree(embedName)
319 end
320 end
321
322 root:LoD()
323 end
324 ]]
325