Mercurial > wow > dependencyloader
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 |