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