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