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