vanilla-wow-addons – Blame information for rev 1
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
1 | office | 1 | --[[-------------------------------------------------------------------------------- |
2 | |||
3 | Ace |
||
4 | |||
5 | Author: Kaelten (kaelten@gmail.com) |
||
6 | Website: http://www.wowace.com |
||
7 | |||
8 | -----------------------------------------------------------------------------------]] |
||
9 | local MYADDONS_TABLE = { |
||
10 | audio = "MYADDONS_CATEGORY_AUDIO", |
||
11 | bars = "MYADDONS_CATEGORY_BARS", |
||
12 | battlegrounds = "MYADDONS_CATEGORY_BATTLEGROUNDS", |
||
13 | chat = "MYADDONS_CATEGORY_CHAT", |
||
14 | class = "MYADDONS_CATEGORY_CLASS", |
||
15 | combat = "MYADDONS_CATEGORY_COMBAT", |
||
16 | compilations = "MYADDONS_CATEGORY_COMPILATIONS", |
||
17 | development = "MYADDONS_CATEGORY_DEVELOPMENT", |
||
18 | guild = "MYADDONS_CATEGORY_GUILD", |
||
19 | interface = "MYADDONS_CATEGORY_PLUGINS", |
||
20 | inventory = "MYADDONS_CATEGORY_INVENTORY", |
||
21 | map = "MYADDONS_CATEGORY_MAP", |
||
22 | others = "MYADDONS_CATEGORY_OTHERS", |
||
23 | modules = "MYADDONS_CATEGORY_PLUGINS", |
||
24 | professions = "MYADDONS_CATEGORY_PROFESSIONS", |
||
25 | quests = "MYADDONS_CATEGORY_QUESTS", |
||
26 | raid = "MYADDONS_CATEGORY_RAID", |
||
27 | }; |
||
28 | |||
29 | local MYADDONS_ACE_CROSSCAT = {}; |
||
30 | MYADDONS_ACE_CROSSCAT["Audio"] = "MYADDONS_CATEGORY_AUDIO" |
||
31 | MYADDONS_ACE_CROSSCAT["Interface Bars"] = "MYADDONS_CATEGORY_BARS" |
||
32 | MYADDONS_ACE_CROSSCAT["Battlegrounds"] = "MYADDONS_CATEGORY_BATTLEGROUNDS" |
||
33 | MYADDONS_ACE_CROSSCAT["Chat/Communications"] = "MYADDONS_CATEGORY_CHAT" |
||
34 | MYADDONS_ACE_CROSSCAT["Class Enhancement"] = "MYADDONS_CATEGORY_CLASS" |
||
35 | MYADDONS_ACE_CROSSCAT["Combat/Casting"] = "MYADDONS_CATEGORY_COMBAT" |
||
36 | MYADDONS_ACE_CROSSCAT["Compilations"] = "MYADDONS_CATEGORY_COMPILATIONS" |
||
37 | MYADDONS_ACE_CROSSCAT["Interface Enhancements"] = "MYADDONS_CATEGORY_OTHERS" |
||
38 | MYADDONS_ACE_CROSSCAT["Development Tools"] = "MYADDONS_CATEGORY_DEVELOPMENT" |
||
39 | MYADDONS_ACE_CROSSCAT["Guild"] = "MYADDONS_CATEGORY_GUILD" |
||
40 | MYADDONS_ACE_CROSSCAT["Inventory/Item Enhancements"] = "MYADDONS_CATEGORY_INVENTORY" |
||
41 | MYADDONS_ACE_CROSSCAT["Map Enhancements"] = "MYADDONS_CATEGORY_MAP" |
||
42 | MYADDONS_ACE_CROSSCAT["Others"] = "MYADDONS_CATEGORY_OTHERS" |
||
43 | MYADDONS_ACE_CROSSCAT["Interface Enhancements"] = "MYADDONS_CATEGORY_PLUGINS" |
||
44 | MYADDONS_ACE_CROSSCAT["Professions"] = "MYADDONS_CATEGORY_PROFESSIONS" |
||
45 | MYADDONS_ACE_CROSSCAT["Quest Enhancements"] = "MYADDONS_CATEGORY_QUESTS" |
||
46 | MYADDONS_ACE_CROSSCAT["Raid Assistance"] = "MYADDONS_CATEGORY_RAID" |
||
47 | |||
48 | local ACE_VERSION = "1.3" |
||
49 | local ACE_COMP_VERSION = 103 |
||
50 | local ACE_RELEASE = "1-05-2005" |
||
51 | local ACE_WEBSITE = "http://www.wowace.com" |
||
52 | |||
53 | TRUE = 1 |
||
54 | FALSE = nil |
||
55 | |||
56 | SlashCmdList["RELOAD"] = ReloadUI |
||
57 | |||
58 | |||
59 | --[[-------------------------------------------------------------------------------- |
||
60 | Class Setup |
||
61 | -----------------------------------------------------------------------------------]] |
||
62 | |||
63 | -- AceCore just provides a debug method for all Ace classes. |
||
64 | AceCore = {} |
||
65 | -- Compatibility reference, deprecated use |
||
66 | AceCoreClass = AceCore |
||
67 | |||
68 | |||
69 | -- Object constructor |
||
70 | function AceCore:new(o) |
||
71 | self.__index = self |
||
72 | return setmetatable(o or {}, self) |
||
73 | end |
||
74 | |||
75 | function AceCore:debug(...) |
||
76 | if( ace.debugger ) then |
||
77 | ace.debugger:Message((self.app or {}).name or self.name or ACE_NAME, arg) |
||
78 | end |
||
79 | end |
||
80 | |||
81 | -- The class for the main Ace object |
||
82 | Ace = AceCore:new({ |
||
83 | name = ACE_NAME, |
||
84 | description = ACE_DESCRIPTION, |
||
85 | version = ACE_VERSION, |
||
86 | website = ACE_WEBSITE, |
||
87 | addons = {numLoaded=0,numAceAddons=0,numAceApps=0,list={}}, |
||
88 | gVersion = 0, |
||
89 | tVersion = 0, |
||
90 | fVersion = 0, |
||
91 | langs = {"deDE", "frFR", "koKR", "usEN", "zhCN"}, |
||
92 | _load = {}, |
||
93 | category = "development", |
||
94 | }) |
||
95 | -- Compatibility reference, deprecated use |
||
96 | AceClass = Ace |
||
97 | |||
98 | function Ace:new(c,t) |
||
99 | return AceCore.new(c or self,t) |
||
100 | end |
||
101 | |||
102 | |||
103 | --[[-------------------------------------------------------------------------------- |
||
104 | Core Ace Methods |
||
105 | -----------------------------------------------------------------------------------]] |
||
106 | |||
107 | function Ace:call(obj, meth, ...) |
||
108 | return function(...) return obj[meth](obj, unpack(arg)) end |
||
109 | end |
||
110 | |||
111 | function Ace:print(...) |
||
112 | local r,g,b,frame,delay |
||
113 | if( type(arg[1]) == "table" ) then |
||
114 | r,g,b,frame,delay = unpack(tremove(arg,1)) |
||
115 | end |
||
116 | (frame or DEFAULT_CHAT_FRAME):AddMessage(self.concat(arg),r,g,b,1,delay or 5) |
||
117 | end |
||
118 | |||
119 | |||
120 | --[[-------------------------------------------------------------------------------- |
||
121 | Addon Registering |
||
122 | -----------------------------------------------------------------------------------]] |
||
123 | |||
124 | function Ace:LoadTranslation(id) |
||
125 | local loader = getglobal(id.."_Locals_"..GetLocale()) |
||
126 | if( loader ) then loader() loader = TRUE end |
||
127 | for _, lang in self.langs do |
||
128 | setglobal(id.."_Locals_"..lang, nil) |
||
129 | end |
||
130 | return loader |
||
131 | end |
||
132 | |||
133 | function Ace:RegisterFunctions(class, utils) |
||
134 | if( not utils ) then utils = class; class = nil end |
||
135 | local ver = self.tonum(utils.version) |
||
136 | -- Clear the version so it doesn't get registered. |
||
137 | utils.version = nil |
||
138 | for name, val in utils do |
||
139 | if( (not Ace[name]) and ((ver >= self.fVersion) or (not self[name])) ) then |
||
140 | self[name] = nil |
||
141 | self[name] = val |
||
142 | end |
||
143 | if( class ) then class[name] = self[name] end |
||
144 | end |
||
145 | if( ver > self.fVersion ) then self.fVersion = ver end |
||
146 | utils = nil |
||
147 | end |
||
148 | |||
149 | function Ace:RegisterGlobals(globals) |
||
150 | local ver, trans = self.tonum(globals.version), globals.translation |
||
151 | -- Clear the version and translation so they don't get registered. |
||
152 | globals.version = nil |
||
153 | globals.translation = nil |
||
154 | -- A specific translation takes precedence over the default. If the translation matches |
||
155 | -- the current locale, it will get used no matter what the default global version is. |
||
156 | for name, val in globals do |
||
157 | if( (ver >= self.gVersion) or ((trans == GetLocale()) and (ver >= self.tVersion)) or |
||
158 | (not getglobal(name)) |
||
159 | ) then |
||
160 | setglobal(name,val) |
||
161 | end |
||
162 | end |
||
163 | if( ver > self.gVersion ) then self.gVersion = ver end |
||
164 | if( (trans == GetLocale()) and (ver > self.tVersion) ) then self.tVersion = ver end |
||
165 | globals = nil |
||
166 | end |
||
167 | |||
168 | function Ace:RegisterForLoad(app) |
||
169 | self.registry:set(app.name, app) |
||
170 | tinsert(self._load, app) |
||
171 | end |
||
172 | |||
173 | |||
174 | --[[-------------------------------------------------------------------------------- |
||
175 | Dynamic Loading of Ace Addons |
||
176 | -----------------------------------------------------------------------------------]] |
||
177 | |||
178 | function Ace:LoadAddon() |
||
179 | local id = strlower(arg1) |
||
180 | |||
181 | if( not self.addons.list[id] ) then |
||
182 | local _, title, _, _, loadable = GetAddOnInfo(arg1) |
||
183 | self.addons.list[id] = { |
||
184 | name = name, |
||
185 | title = title or name, |
||
186 | loadable = TRUE |
||
187 | } |
||
188 | end |
||
189 | |||
190 | self.addons.list[id].name = arg1 |
||
191 | self.addons.list[id].loaded = TRUE |
||
192 | self.addons.numLoaded = self.addons.numLoaded + 1 |
||
193 | |||
194 | for _, dep in {GetAddOnDependencies(arg1)} do |
||
195 | if( strlower(dep) == "ace" ) then |
||
196 | self.addons.list[id].ace = TRUE |
||
197 | self.addons.numAceAddons = self.addons.numAceAddons + 1 |
||
198 | break |
||
199 | end |
||
200 | end |
||
201 | |||
202 | if( getn(self._load) < 1 ) then return end |
||
203 | |||
204 | local _, _, notes = GetAddOnInfo(arg1) |
||
205 | local apps = {unpack(self._load)} |
||
206 | self.addons.list[id].apps = self._load |
||
207 | self.addons.numAceApps = self.addons.numAceApps + getn(self._load) |
||
208 | self._load = {} |
||
209 | |||
210 | for _, app in self.addons.list[id].apps do |
||
211 | if( not app.description ) then app.description = notes end |
||
212 | if( self.initialized ) then self:InitializeApp(app) end |
||
213 | end |
||
214 | end |
||
215 | |||
216 | function Ace:InitializeAppDB(app) |
||
217 | if( app.db ) then |
||
218 | app.db.app = app |
||
219 | -- Deprecated 'addon' variable |
||
220 | app.db.addon = app |
||
221 | app.db:Initialize() |
||
222 | end |
||
223 | end |
||
224 | |||
225 | function Ace:InitializeApp(app) |
||
226 | if( ace.tonum(app.aceCompatible) > ACE_COMP_VERSION ) then |
||
227 | app.aceMismatch = TRUE |
||
228 | return |
||
229 | end |
||
230 | |||
231 | self:InitializeAppDB(app) |
||
232 | self.db:LoadAddonProfile(app) |
||
233 | |||
234 | if( app.db ) then |
||
235 | app.disabled = app.db:get(app.profilePath, "disabled") |
||
236 | end |
||
237 | |||
238 | if( app.cmd ) then |
||
239 | app.cmd.app = app |
||
240 | -- Deprecated 'addon' variable |
||
241 | app.cmd.addon = app |
||
242 | end |
||
243 | if( app.Initialize ) then app.Initialize(app) end |
||
244 | if( app.cmd and app.cmd._cmdList and (not app.cmd.registered) ) then |
||
245 | app.cmd:Register(app) |
||
246 | end |
||
247 | self:RegisterAddon(app) |
||
248 | app.initialized = TRUE |
||
249 | self.event:TriggerEvent(strupper(app.name).."_LOADED") |
||
250 | |||
251 | if( (not app.disabled) and app.Enable ) then app.Enable(app) end |
||
252 | if( not app.disabled ) then |
||
253 | self.event:TriggerEvent(strupper(app.name).."_ENABLED") |
||
254 | end |
||
255 | end |
||
256 | |||
257 | -- Register the application configuration with myAddOns so that it will be listed |
||
258 | -- in the myAddOns menu. |
||
259 | function Ace:RegisterAddon(app) |
||
260 | if (myAddOnsFrame_Register) then |
||
261 | local appdata = { |
||
262 | name = app.name, |
||
263 | version = app.version, |
||
264 | releaseDate = app.releaseDate, |
||
265 | author = app.author, |
||
266 | email = app.email, |
||
267 | website = app.website, |
||
268 | category = getglobal(MYADDONS_TABLE[strlower(app.category or app.catagory or "")] or MYADDONS_ACE_CROSSCAT[app.category] or "MYADDONS_CATEGORY_OTHERS"), |
||
269 | optionsframe = app.optionsFrame |
||
270 | }; |
||
271 | myAddOnsFrame_Register(appdata); |
||
272 | end |
||
273 | end |
||
274 | |||
275 | |||
276 | --[[-------------------------------------------------------------------------------- |
||
277 | Core Utilities Used by Ace |
||
278 | -----------------------------------------------------------------------------------]] |
||
279 | |||
280 | function Ace.ParseWords(str, pat) |
||
281 | if( ace.tostr(str) == "" ) then return {} end |
||
282 | local list = {} |
||
283 | for word in gfind(str, pat or "%S+") do |
||
284 | tinsert(list, word) |
||
285 | end |
||
286 | return list |
||
287 | end |
||
288 | |||
289 | -- Recursively iterate through the table and sub-tables until the entire table |
||
290 | -- structure is copied over. Note: I used to check whether the table was numerically |
||
291 | -- indexed and use two different for() loops, one with ipairs() and one without. I |
||
292 | -- did this because there seemed to be problems otherwise, but in rewriting this, I |
||
293 | -- haven't encountered any problems. |
||
294 | function Ace.CopyTable(into, from) |
||
295 | for key, val in from do |
||
296 | if( type(val) == "table" ) then |
||
297 | if( not into[key] ) then into[key] = {} end |
||
298 | ace.CopyTable(into[key], val) |
||
299 | else |
||
300 | into[key] = val |
||
301 | end |
||
302 | end |
||
303 | |||
304 | if (getn(from)) then |
||
305 | table.setn(into, getn(from)) |
||
306 | end |
||
307 | |||
308 | return into |
||
309 | end |
||
310 | |||
311 | function Ace.GetTableKeys(tbl) |
||
312 | local t = {} |
||
313 | for key, val in pairs(tbl) do |
||
314 | tinsert(t, key) |
||
315 | end |
||
316 | return(t) |
||
317 | end |
||
318 | |||
319 | function Ace.TableFindKeyCaseless(tbl, key) |
||
320 | key = strlower(key) |
||
321 | for i, val in tbl do |
||
322 | if( strlower(i) == key ) then return i, val end |
||
323 | end |
||
324 | end |
||
325 | |||
326 | function Ace.TableFindByKeyValue(tbl, key, val, caseless) |
||
327 | if( not tbl ) then error("No table supplied to TableFindByKeyValue.", 2) end |
||
328 | for i, t in ipairs(tbl) do |
||
329 | if( (caseless and (strlower(t[key]) == strlower(val))) or (t[key] == val) ) then |
||
330 | return i, t |
||
331 | end |
||
332 | end |
||
333 | end |
||
334 | |||
335 | function Ace.concat(t,sep) |
||
336 | local msg = "" |
||
337 | if( getn(t) > 0 ) then |
||
338 | for key, val in ipairs(t) do |
||
339 | if( msg ~= "" and sep ) then msg = msg..sep end |
||
340 | msg = msg..ace.tostr(val) |
||
341 | end |
||
342 | else |
||
343 | for key, val in t do |
||
344 | if( msg ~= "" and sep ) then msg = msg..sep end |
||
345 | msg = msg..key.."="..ace.tostr(val) |
||
346 | end |
||
347 | end |
||
348 | return msg |
||
349 | end |
||
350 | |||
351 | function Ace.round(num) |
||
352 | return floor(ace.tonum(num)+.5) |
||
353 | end |
||
354 | |||
355 | function Ace.sort(tbl, comp) |
||
356 | sort(tbl, comp) |
||
357 | return tbl |
||
358 | end |
||
359 | |||
360 | function Ace.strlen(str) |
||
361 | return strlen(str or "") |
||
362 | end |
||
363 | |||
364 | function Ace.tonum(val, base) |
||
365 | return tonumber((val or 0), base) or 0 |
||
366 | end |
||
367 | |||
368 | function Ace.tostr(val) |
||
369 | return tostring(val or "") |
||
370 | end |
||
371 | |||
372 | function Ace.toggle(val) |
||
373 | if( val ) then return FALSE end |
||
374 | return TRUE |
||
375 | end |
||
376 | |||
377 | function Ace.trim(str, opt) |
||
378 | if( (not opt) or (opt=="left" ) ) then str = gsub(str, "^%s*", "") end |
||
379 | if( (not opt) or (opt=="right") ) then str = gsub(str, "%s*$", "") end |
||
380 | return str |
||
381 | end |
||
382 | |||
383 | |||
384 | --[[-------------------------------------------------------------------------------- |
||
385 | Helpful References |
||
386 | -----------------------------------------------------------------------------------]] |
||
387 | |||
388 | -- Pointer to maintain backwards reference compatibility |
||
389 | ace = Ace |
||
390 | |||
391 | -- Functions left unmapped in the UI. Mapped here for consistency. |
||
392 | concat = table.concat |
||
393 | gfind = string.gfind |
||
394 | strrep = string.rep |