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