comparison DependencyLoader/Core.lua @ 9:5362e308c3eb

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