comparison DependencyLoader_Core/Core.lua @ 0:9852fcd5e59e

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