comparison DependencyLoader/Addon.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/Addon.lua@930871e163bc
children e0a4a8b5b389
comparison
equal deleted inserted replaced
8:930871e163bc 9:5362e308c3eb
1 -- Addon
2 -- Represents individual addon modules
3
4
5 local addonName, addonTable = ...
6
7
8 -- NOTE: I assume that the API addon functions are
9 -- slightly quicker with an index than with a number.
10
11 -- TODO: modify the dependency stuff to use the Errata module if available
12
13 local Addon, addon = addonTable:NewClass("Addon")
14
15
16 -- load ability masks
17 Addon.loadMasks = {
18 reload = bit.lshift(1, 0), -- can load after reloadui
19 ondemand = bit.lshift(1, 1), -- can load on demand
20 forceafter = bit.lshift(1, 2), -- force load after it would normally be loaded
21 forcebefore = bit.lshift(1, 3), -- force load before it would normally be loaded
22 }
23
24
25 Addon.addons = {}
26 Addon.nameToIndex = {}
27
28
29 -- Internal function
30 -- Creates a new Addon object
31 -- @param id Name or index of the addon.
32 function Addon:New(id)
33 local instance = {}
34 setmetatable(instance, self.instanceMetatable)
35
36 if type(id) == "number" then
37 -- TODO: make sure it's in range
38 instance.index = id
39 instance.name = GetAddOnInfo(id)
40 else
41 -- FIXME: allow blizzard addons?
42 local index
43
44 for i=1,GetNumAddOns() do
45 if GetAddOnInfo(i) == id then
46 index = i
47 break
48 end
49 end
50
51 if index then
52 instance.name = GetAddOnInfo(id)
53 instance.index = index
54 else
55 error("Addon not found")
56 end
57 end
58
59 return instance
60 end
61
62
63 --- Retrieves an Addon object.
64 -- @param id Name or index of the addon to retrieve.
65 -- @return The Addon object, or nil if not found.
66 function Addon:Get(id)
67 if not self:Exists(id) then
68 return nil
69 end
70
71 if type(id) == "number" then
72 if self.addons[id] ~= nil then
73 return self.addons[id]
74 end
75
76 local new = self:New(id)
77 self.addons[new:GetIndex()] = new
78 self.nameToIndex[new:GetName()] = id
79
80 return new
81 elseif type(id) == "string" then
82 if self.nameToIndex[id] then
83 return self.addons[self.nameToIndex[id] ]
84 end
85
86 local new = self:New(id)
87 self.addons[new:GetIndex()] = new
88 self.nameToIndex[id] = new:GetIndex()
89
90 return new
91 end
92 end
93
94 -- Checks if an addon exists with the specified name.
95 -- @param addon Name of the addon.
96 -- @return True if the addon is present, false otherwise.
97 function Addon:Exists(addon)
98 if type(addon) == "number" then
99 if addon >= 1 and addon <= GetNumAddOns() then
100 return true
101 else
102 return false
103 end
104 elseif type(addon) == "string" then
105 local status = select(6, GetAddOnInfo(addon))
106
107 if status == "MISSING" then
108 return false
109 else
110 return true
111 end
112 else
113 error()
114 end
115 end
116
117
118 function Addon:GetLoadMasks()
119 return self.masks
120 end
121
122
123 function addon:GetName()
124 return self.name
125 end
126
127
128 function addon:GetIndex()
129 return self.index
130 end
131
132
133 function addon:IsEnabled()
134 -- FIXME: written while tired; review later
135 local status = select(6, GetAddOnInfo(self.index))
136
137 if status == "DISABLED" then
138 return false
139 else
140 return true
141 end
142 end
143
144
145 function addon:GetLoadBitfield()
146 local bitfield = 0
147
148 if self:CanLoad() then
149 bitfield = bitfield + self.masks.reload
150 end
151
152 if self:CanLoD() then
153 bitfield = bitfield + self.masks.ondemand
154 end
155
156 if self:CanForceLoadAfter() then
157 bitfield = bitfield + self.masks.forceafter
158 end
159
160 if self:CanForceLoadBefore() then
161 bitfield = bitfield + self.masks.forcebefore
162 end
163
164 return bitfield
165 end
166
167
168 --- Checks if the addon is loadable.
169 -- Considers interface issues, missing, etc. (NYI)
170 -- Does not check dependencies.
171 function addon:CanLoad()
172 -- FIXME: an addon may be present but unloadable if loading out of date addons is disabled.
173 return true
174 end
175
176
177 function addon:CanLoD()
178 -- FIXME: what will the client say about addons using LoadManagers if the LM was force-loaded?
179 if IsAddOnLoadOnDemand(self.name) then
180 return true
181 else
182 return false
183 end
184 end
185
186
187 function addon:CanForceLoadAfter()
188 -- TODO: check Errata module
189 return false
190 end
191
192
193 function addon:CanForceLoadBefore()
194 -- TODO: check Errata module
195 return false -- TODO: check if there's any reason addons can't be forceloaded
196 end
197
198
199 function addon:Enable()
200 -- FIXME: delay this till after PLAYER_LOGIN or it'll get force-loaded
201 EnableAddOn(self.name)
202 end
203
204
205 -- NOTE: only call for LoD, not force-loading
206 function addon:Load()
207 assert(self:CanLoD())
208
209 EnableAddOn(self.name)
210 LoadAddOn(self.name)
211 end
212
213
214 function addon:ForceLoad()
215 assert(self:CanForceLoad())
216 -- TODO: make sure force-loading is available at this time
217
218 EnableAddOn(self.name) -- This should cause the game to also load this addon
219 end
220
221
222 function addon:GetDependencies()
223 -- TODO: consider no-lib embeds as deps?
224 return GetAddOnDependencies(self.index)
225 end
226
227
228 function addon:GetEmbeds()
229 local embeds = {}
230
231 local embedString = GetAddOnMetadata(self.name, "X-Embeds")
232
233 if embedString then
234 for match in string.gmatch(embedString, "[^,%s]+") do
235 table.insert(embeds, match)
236 end
237 end
238
239 return unpack(embeds)
240 end
241
242 function addon:IsLoaded()
243 if IsAddOnLoaded(self.index) then
244 return true
245 else
246 return false
247 end
248 end