vanilla-wow-addons – Blame information for rev 1

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 office 1 --[[
2 Name: AceDB-2.0
3 Revision: $Rev: 4763 $
4 Author(s): ckknight (ckknight@gmail.com)
5 Inspired By: AceDB 1.x by Turan (<email here>)
6 Website: http://www.wowace.com/
7 Documentation: http://wiki.wowace.com/index.php/AceDB-2.0
8 SVN: http://svn.wowace.com/root/trunk/Ace2/AceDB-2.0
9 Description: Mixin to allow for fast, clean, and featureful saved variable
10 access.
11 Dependencies: AceLibrary, AceOO-2.0, AceEvent-2.0
12 ]]
13  
14 local MAJOR_VERSION = "AceDB-2.0"
15 local MINOR_VERSION = "$Revision: 4763 $"
16  
17 if not AceLibrary then error(MAJOR_VERSION .. " requires AceLibrary") end
18 if not AceLibrary:IsNewVersion(MAJOR_VERSION, MINOR_VERSION) then return end
19  
20 if not AceLibrary:HasInstance("AceOO-2.0") then error(MAJOR_VERSION .. " requires AceOO-2.0") end
21  
22 -- localize --
23 local ACTIVE = "Active"
24 local STATE = "State"
25 local TOGGLE_ACTIVE = "Suspend/resume this addon"
26 local MAP_ACTIVESUSPENDED = { [true] = "|cff00ff00Active|r", [false] = "|cffff0000Suspended|r" }
27 local SET_PROFILE = "Set profile for this addon"
28 local SET_PROFILE_USAGE = "{char || class || realm || <profile name>}"
29 local PROFILE = "Profile"
30 local PLAYER_OF_REALM = "%s of %s"
31 -- localize --
32  
33 local AceOO = AceLibrary("AceOO-2.0")
34 local AceEvent
35 local Mixin = AceOO.Mixin
36 local AceDB = Mixin {
37 "RegisterDB",
38 "RegisterDefaults",
39 "ResetDB",
40 "SetProfile",
41 "GetProfile",
42 "ToggleActive",
43 "IsActive",
44 "AcquireDBNamespace",
45 "ToggleStandby", -- remove at 2006-07-21
46 "IsEnabled", -- remove at 2006-07-21
47 }
48  
49 local _G = getfenv(0)
50  
51 local function inheritDefaults(t, defaults)
52 if not defaults then
53 return t
54 end
55 for k,v in pairs(defaults) do
56 if k == "*" then
57 local v = v
58 if type(v) == "table" then
59 setmetatable(t, {
60 __index = function(self, key)
61 if key == nil then
62 return nil
63 end
64 self[key] = {}
65 inheritDefaults(self[key], v)
66 return self[key]
67 end
68 } )
69 else
70 setmetatable(t, {
71 __index = function(self, key)
72 if key == nil then
73 return nil
74 end
75 self[key] = v
76 return self[key]
77 end
78 } )
79 end
80 for key in pairs(t) do
81 if (defaults[key] == nil or key == "*") and type(t[key]) == "table" then
82 inheritDefaults(t[key], v)
83 end
84 end
85 else
86 if type(v) == "table" then
87 if type(t[k]) ~= "table" then
88 t[k] = {}
89 end
90 inheritDefaults(t[k], v)
91 elseif t[k] == nil then
92 t[k] = v
93 end
94 end
95 end
96 return t
97 end
98  
99 local _,race = UnitRace("player")
100 local faction
101 if race == "Orc" or race == "Scourge" or race == "Troll" or race == "Tauren" then
102 faction = FACTION_HORDE
103 else
104 faction = FACTION_ALLIANCE
105 end
106 local charID = string.format(PLAYER_OF_REALM, UnitName("player"), (string.gsub(GetRealmName(), "^%s*(.-)%s*$", "%1")))
107 local realm = string.gsub(GetRealmName(), "^%s*(.-)%s*$", "%1")
108 local realmID = realm .. " - " .. faction
109 local classID = UnitClass("player")
110  
111 AceDB.CHAR_ID = charID
112 AceDB.REALM_ID = realmID
113 AceDB.CLASS_ID = classID
114  
115 AceDB.FACTION = faction
116 AceDB.REALM = realm
117 AceDB.NAME = UnitName("player")
118  
119 local caseInsensitive_mt = {
120 __index = function(self, key)
121 if type(key) ~= "string" then
122 return nil
123 end
124 local lowerKey = string.lower(key)
125 for k,v in pairs(self) do
126 if string.lower(k) == lowerKey then
127 return self[k]
128 end
129 end
130 end,
131 __newindex = function(self, key, value)
132 if type(key) ~= "string" then
133 return error("table index is nil", 2)
134 end
135 local lowerKey = string.lower(key)
136 for k in pairs(self) do
137 if string.lower(k) == lowerKey then
138 rawset(self, k, nil)
139 rawset(self, key, value)
140 return
141 end
142 end
143 rawset(self, key, value)
144 end
145 }
146  
147 local db_mt = { __index = function(db, key)
148 if key == "char" then
149 if db.charName then
150 if type(_G[db.charName]) ~= "table" then
151 _G[db.charName] = {}
152 end
153 if type(_G[db.charName].raw) ~= "table" then
154 _G[db.charName].global = {}
155 end
156 rawset(db, 'char', _G[db.charName].global)
157 else
158 if type(db.raw.chars) ~= "table" then
159 db.raw.chars = {}
160 end
161 local id = charID
162 if type(db.raw.chars[id]) ~= "table" then
163 db.raw.chars[id] = {}
164 end
165 rawset(db, 'char', db.raw.chars[id])
166 end
167 if db.defaults and db.defaults.char then
168 inheritDefaults(db.char, db.defaults.char)
169 end
170 return db.char
171 elseif key == "realm" then
172 if type(db.raw.realms) ~= "table" then
173 db.raw.realms = {}
174 end
175 local id = realmID
176 if type(db.raw.realms[id]) ~= "table" then
177 db.raw.realms[id] = {}
178 end
179 rawset(db, 'realm', db.raw.realms[id])
180 if db.defaults and db.defaults.realm then
181 inheritDefaults(db.realm, db.defaults.realm)
182 end
183 return db.realm
184 elseif key == "account" then
185 if type(db.raw.account) ~= "table" then
186 db.raw.account = {}
187 end
188 rawset(db, 'account', db.raw.account)
189 if db.defaults and db.defaults.account then
190 inheritDefaults(db.account, db.defaults.account)
191 end
192 return db.account
193 elseif key == "class" then
194 if type(db.raw.classes) ~= "table" then
195 db.raw.classes = {}
196 end
197 local id = classID
198 if type(db.raw.classes[id]) ~= "table" then
199 db.raw.classes[id] = {}
200 end
201 rawset(db, 'class', db.raw.classes[id])
202 if db.defaults and db.defaults.class then
203 inheritDefaults(db.class, db.defaults.class)
204 end
205 return db.class
206 elseif key == "profile" then
207 if type(db.raw.profiles) ~= "table" then
208 db.raw.profiles = setmetatable({}, caseInsensitive_mt)
209 else
210 setmetatable(db.raw.profiles, caseInsensitive_mt)
211 end
212 local id = db.raw.currentProfile[charID]
213 if id == "char" then
214 id = "char/" .. charID
215 elseif id == "class" then
216 id = "class/" .. classID
217 elseif id == "realm" then
218 id = "realm/" .. realmID
219 end
220 if type(db.raw.profiles[id]) ~= "table" then
221 db.raw.profiles[id] = {}
222 end
223 rawset(db, 'profile', db.raw.profiles[id])
224 if db.defaults and db.defaults.profile then
225 inheritDefaults(db.profile, db.defaults.profile)
226 end
227 return db.profile
228 elseif key == "raw" or key == "defaults" or key == "name" or key == "charName" or key == "namespaces" then
229 return nil
230 end
231 error(string.format('Cannot access key %q in db table. You may want to use db.profile[%q]', tostring(key), tostring(key)), 2)
232 end, __newindex = function(db, key, value)
233 error(string.format('Cannot access key %q in db table. You may want to use db.profile[%q]', tostring(key), tostring(key)), 2)
234 end }
235  
236 local namespace_mt = { __index = function(namespace, key)
237 local db = namespace.db
238 local name = namespace.name
239 if key == "char" then
240 if db.charName then
241 if type(_G[db.charName]) ~= "table" then
242 _G[db.charName] = {}
243 end
244 if type(_G[db.charName].namespaces) ~= "table" then
245 _G[db.charName].namespaces = {}
246 end
247 if type(_G[db.charName].namespaces[name]) ~= "table" then
248 _G[db.charName].namespaces[name] = {}
249 end
250 rawset(namespace, 'char', _G[db.charName].namespaces[name])
251 else
252 if type(db.raw.namespaces) ~= "table" then
253 db.raw.namespaces = {}
254 end
255 if type(db.raw.namespaces[name]) ~= "table" then
256 db.raw.namespaces[name] = {}
257 end
258 if type(db.raw.namespaces[name].chars) ~= "table" then
259 db.raw.namespaces[name].chars = {}
260 end
261 local id = charID
262 if type(db.raw.namespaces[name].chars[id]) ~= "table" then
263 db.raw.namespaces[name].chars[id] = {}
264 end
265 rawset(namespace, 'char', db.raw.namespaces[name].chars[id])
266 end
267 if namespace.defaults and namespace.defaults.char then
268 inheritDefaults(namespace.char, namespace.defaults.char)
269 end
270 return namespace.char
271 elseif key == "realm" then
272 if type(db.raw.namespaces) ~= "table" then
273 db.raw.namespaces = {}
274 end
275 if type(db.raw.namespaces[name]) ~= "table" then
276 db.raw.namespaces[name] = {}
277 end
278 if type(db.raw.namespaces[name].realms) ~= "table" then
279 db.raw.namespaces[name].realms = {}
280 end
281 local id = realmID
282 if type(db.raw.namespaces[name].realms[id]) ~= "table" then
283 db.raw.namespaces[name].realms[id] = {}
284 end
285 rawset(namespace, 'realm', db.raw.namespaces[name].realms[id])
286 if namespace.defaults and namespace.defaults.realm then
287 inheritDefaults(namespace.realm, namespace.defaults.realm)
288 end
289 return namespace.realm
290 elseif key == "account" then
291 if type(db.raw.namespaces) ~= "table" then
292 db.raw.namespaces = {}
293 end
294 if type(db.raw.namespaces[name]) ~= "table" then
295 db.raw.namespaces[name] = {}
296 end
297 if type(db.raw.namespaces[name].account) ~= "table" then
298 db.raw.namespaces[name].account = {}
299 end
300 rawset(namespace, 'account', db.raw.namespaces[name].account)
301 if namespace.defaults and namespace.defaults.account then
302 inheritDefaults(namespace.account, namespace.defaults.account)
303 end
304 return namespace.account
305 elseif key == "class" then
306 if type(db.raw.namespaces) ~= "table" then
307 db.raw.namespaces = {}
308 end
309 if type(db.raw.namespaces[name]) ~= "table" then
310 db.raw.namespaces[name] = {}
311 end
312 if type(db.raw.namespaces[name].classes) ~= "table" then
313 db.raw.namespaces[name].classes = {}
314 end
315 local id = classID
316 if type(db.raw.namespaces[name].classes[id]) ~= "table" then
317 db.raw.namespaces[name].classes[id] = {}
318 end
319 rawset(namespace, 'class', db.raw.namespaces[name].classes[id])
320 if namespace.defaults and namespace.defaults.class then
321 inheritDefaults(namespace.class, namespace.defaults.class)
322 end
323 return namespace.class
324 elseif key == "profile" then
325 if type(db.raw.namespaces) ~= "table" then
326 db.raw.namespaces = {}
327 end
328 if type(db.raw.namespaces[name]) ~= "table" then
329 db.raw.namespaces[name] = {}
330 end
331 if type(db.raw.namespaces[name].profiles) ~= "table" then
332 db.raw.namespaces[name].profiles = setmetatable({}, caseInsensitive_mt)
333 else
334 setmetatable(db.raw.namespaces[name].profiles, caseInsensitive_mt)
335 end
336 local id = db.raw.currentProfile[charID]
337 if id == "char" then
338 id = "char/" .. charID
339 elseif id == "class" then
340 id = "class/" .. classID
341 elseif id == "realm" then
342 id = "realm/" .. realmID
343 end
344 if type(db.raw.namespaces[name].profiles[id]) ~= "table" then
345 db.raw.namespaces[name].profiles[id] = {}
346 end
347 rawset(namespace, 'profile', db.raw.namespaces[name].profiles[id])
348 if namespace.defaults and namespace.defaults.profile then
349 inheritDefaults(namespace.profile, namespace.defaults.profile)
350 end
351 return namespace.profile
352 elseif key == "defaults" or key == "name" or key == "db" then
353 return nil
354 end
355 error(string.format('Cannot access key %q in db table. You may want to use db.profile[%q]', tostring(key), tostring(key)), 2)
356 end, __newindex = function(db, key, value)
357 error(string.format('Cannot access key %q in db table. You may want to use db.profile[%q]', tostring(key), tostring(key)), 2)
358 end }
359  
360 function AceDB:InitializeDB(addonName)
361 local db = self.db
362  
363 if not db then
364 if addonName then
365 AceDB.addonsLoaded[addonName] = true
366 end
367 return
368 end
369  
370 if db.raw then
371 -- someone manually initialized
372 return
373 end
374  
375 if type(_G[db.name]) ~= "table" then
376 _G[db.name] = {}
377 end
378 rawset(db, 'raw', _G[db.name])
379 if not db.raw.currentProfile then
380 db.raw.currentProfile = {}
381 end
382 if not db.raw.currentProfile[charID] then
383 db.raw.currentProfile[charID] = "default"
384 end
385 if db.raw.disabled then
386 setmetatable(db.raw.disabled, caseInsensitive_mt)
387 end
388 setmetatable(db, db_mt)
389 end
390  
391 function AceDB:RegisterDB(name, charName)
392 AceDB:argCheck(name, 2, "string")
393 AceDB:argCheck(charName, 3, "string", "nil")
394 if self.db then
395 AceDB:error("Cannot call \"RegisterDB\" if self.db is set.")
396 end
397 local stack = debugstack()
398 local addonName = string.gsub(stack, ".-\n.-\\AddOns\\(.-)\\.*", "%1")
399 self.db = {
400 name = name,
401 charName = charName
402 }
403 if AceDB.addonsLoaded[addonName] then
404 AceDB.InitializeDB(self, addonName)
405 else
406 AceDB.addonsToBeInitialized[self] = addonName
407 end
408 AceDB.registry[self] = true
409 end
410  
411 function AceDB:RegisterDefaults(kind, defaults, a3)
412 local name
413 if a3 then
414 name, kind, defaults = kind, defaults, a3
415 AceDB:argCheck(name, 2, "string")
416 AceDB:argCheck(kind, 3, "string")
417 AceDB:argCheck(defaults, 4, "table")
418 if kind ~= "char" and kind ~= "class" and kind ~= "profile" and kind ~= "account" and kind ~= "realm" then
419 AceDB:error("Bad argument #3 to `RegisterDefaults' (\"char\", \"class\", \"profile\", \"account\", or \"realm\" expected, got %q)", kind)
420 end
421 else
422 AceDB:argCheck(kind, 2, "string")
423 AceDB:argCheck(defaults, 3, "table")
424 if kind ~= "char" and kind ~= "class" and kind ~= "profile" and kind ~= "account" and kind ~= "realm" then
425 AceDB:error("Bad argument #2 to `RegisterDefaults' (\"char\", \"class\", \"profile\", \"account\", or \"realm\" expected, got %q)", kind)
426 end
427 end
428 if type(self.db) ~= "table" or type(self.db.name) ~= "string" then
429 AceDB:error("Cannot call \"RegisterDefaults\" unless \"RegisterDB\" has been previously called.")
430 end
431 local db
432 if name then
433 local namespace = self:AcquireDBNamespace(name)
434 if namespace.defaults and namespace.defaults[kind] then
435 AceDB:error("\"RegisterDefaults\" has already been called for %q::%q.", name, kind)
436 end
437 db = namespace
438 else
439 if self.db.defaults and self.db.defaults[kind] then
440 AceDB:error("\"RegisterDefaults\" has already been called for %q.", kind)
441 end
442 db = self.db
443 end
444 if not db.defaults then
445 rawset(db, 'defaults', {})
446 end
447 db.defaults[kind] = defaults
448 if rawget(db, kind) then
449 inheritDefaults(db[kind], defaults)
450 end
451 end
452  
453 function AceDB:ResetDB(kind)
454 AceDB:checkArg(kind, 2, "nil", "string")
455 if not self.db or not self.db.raw then
456 AceDB:error("Cannot call \"ResetDB\" before \"RegisterDB\" has been called and before \"ADDON_LOADED\" has been fired.")
457 end
458 local db = self.db
459 if kind == nil then
460 if db.charName then
461 _G[db.charName] = nil
462 end
463 _G[db.name] = nil
464 rawset(db, 'raw', nil)
465 AceDB.InitializeDB(self)
466 for name,v in pairs(db.namespaces) do
467 rawset(v, 'account', nil)
468 rawset(v, 'char', nil)
469 rawset(v, 'class', nil)
470 rawset(v, 'profile', nil)
471 rawset(v, 'realm', nil)
472 end
473 elseif kind == "account" then
474 db.raw.account = nil
475 rawset(db, 'account', nil)
476 for name,v in pairs(db.namespaces) do
477 rawset(v, 'account', nil)
478 end
479 elseif kind == "char" then
480 if db.charName then
481 _G[db.charName] = nil
482 else
483 db.raw.chars[charID] = nil
484 for name,v in pairs(db.raw.namespaces) do
485 if v.chars then
486 v.chars[charID] = nil
487 end
488 end
489 end
490 rawset(db, 'char', nil)
491 for name,v in pairs(db.namespaces) do
492 rawset(v, 'char', nil)
493 end
494 elseif kind == "realm" then
495 db.raw.realms[realmID] = nil
496 rawset(db, 'realm', nil)
497 for name,v in pairs(db.raw.namespaces) do
498 if v.realms then
499 v.realms[realmID] = nil
500 end
501 end
502 for name,v in pairs(db.namespaces) do
503 rawset(v, 'realm', nil)
504 end
505 elseif kind == "class" then
506 db.raw.realms[classID] = nil
507 rawset(db, 'class', nil)
508 for name,v in pairs(db.raw.namespaces) do
509 if v.classes then
510 v.classes[classID] = nil
511 end
512 end
513 for name,v in pairs(db.namespaces) do
514 rawset(v, 'class', nil)
515 end
516 elseif kind == "profile" then
517 local id = db.raw.currentProfile[charID]
518 if id == "char" then
519 id = "char/" .. charID
520 elseif id == "class" then
521 id = "class/" .. classID
522 elseif id == "realm" then
523 id = "realm/" .. realmID
524 end
525 db.raw.profiles[id] = nil
526 rawset(db, 'profile', nil)
527 for name,v in pairs(db.raw.namespaces) do
528 if v.profiles then
529 v.profiles[id] = nil
530 end
531 end
532 for name,v in pairs(db.namespaces) do
533 rawset(v, 'profile', nil)
534 end
535 end
536 end
537  
538 local function cleanDefaults(t, defaults)
539 if defaults then
540 for k,v in pairs(defaults) do
541 if k == "*" then
542 if type(v) == "table" then
543 for k in pairs(t) do
544 if (defaults[k] == nil or k == "*") and type(t[k]) == "table" then
545 if cleanDefaults(t[k], v) then
546 t[k] = nil
547 end
548 end
549 end
550 else
551 for k in pairs(t) do
552 if (defaults[k] == nil or k == "*") and t[k] == v then
553 t[k] = nil
554 end
555 end
556 end
557 else
558 if type(v) == "table" then
559 if type(t[k]) == "table" then
560 if cleanDefaults(t[k], v) then
561 t[k] = nil
562 end
563 end
564 elseif t[k] == v then
565 t[k] = nil
566 end
567 end
568 end
569 end
570 return not next(t)
571 end
572  
573 function AceDB:GetProfile()
574 if not self.db or not self.db.raw then
575 return nil
576 end
577 local profile = self.db.raw.currentProfile[charID]
578 if profile == "char" then
579 return "char", "char/" .. charID
580 elseif profile == "class" then
581 return "class", "class/" .. classID
582 elseif profile == "realm" then
583 return "realm", "realm/" .. realmID
584 end
585 return profile, profile
586 end
587  
588 local function copyTable(to, from)
589 setmetatable(to, nil)
590 for k,v in pairs(from) do
591 if type(k) == "table" then
592 k = copyTable({}, k)
593 end
594 if type(v) == "table" then
595 v = copyTable({}, v)
596 end
597 to[k] = v
598 end
599 table.setn(to, table.getn(from))
600 setmetatable(to, from)
601 return to
602 end
603  
604 local stage = 3
605 if tonumber(date("%Y%m%d")) < 20060713 then
606 stage = 1
607 elseif tonumber(date("%Y%m%d")) < 20060720 then
608 stage = 2
609 end
610  
611 function AceDB:SetProfile(name, copyFrom)
612 AceDB:argCheck(name, 2, "string")
613 AceDB:argCheck(copyFrom, 3, "string", "nil")
614 if not self.db or not self.db.raw then
615 AceDB:error("Cannot call \"SetProfile\" before \"RegisterDB\" has been called and before \"ADDON_LOADED\" has been fired.")
616 end
617 local db = self.db
618 local copy = false
619 local lowerName = string.lower(name)
620 local lowerCopyFrom = copyFrom and string.lower(copyFrom)
621 if string.sub(lowerName, 1, 5) == "char/" or string.sub(lowerName, 1, 6) == "realm/" or string.sub(lowerName, 1, 6) == "class/" then
622 if stage <= 2 then
623 if string.sub(lowerName, 1, 5) == "char/" then
624 name, copyFrom = "char", name
625 else
626 name, copyFrom = string.sub(lowerName, 1, 5), name
627 end
628 lowerName = string.lower(name)
629 lowerCopyFrom = string.lower(copyFrom)
630 if stage == 2 then
631 local line = string.gsub(debugstack(), ".-\n(.-)\n.*", "%1")
632 DEFAULT_CHAT_MESSAGE:AddMessage(line .. " - Bad argument #2 to `SetProfile'. Cannot start with char/, realm/, or class/. This will cause an error on July 20, 2006.")
633 end
634 else
635 AceDB:error("Bad argument #2 to `SetProfile'. Cannot start with char/, realm/, or class/.")
636 end
637 end
638 if copyFrom then
639 if string.sub(lowerCopyFrom, 1, 5) == "char/" then
640 AceDB:assert(lowerName == "char", "If argument #3 starts with `char/', argument #2 must be `char'")
641 elseif string.sub(lowerCopyFrom, 1, 6) == "realm/" then
642 AceDB:assert(lowerName == "realm", "If argument #3 starts with `realm/', argument #2 must be `realm'")
643 elseif string.sub(lowerCopyFrom, 1, 6) == "class/" then
644 AceDB:assert(lowerName == "class", "If argument #3 starts with `class/', argument #2 must be `class'")
645 else
646 AceDB:assert(lowerName ~= "char" and lowerName ~= "realm" and lowerName ~= "class", "If argument #3 does not start with a special prefix, that prefix cannot be copied to.")
647 end
648 if not db.raw.profiles or not db.raw.profiles[copyFrom] then
649 AceDB:error("Cannot copy profile %q, it does not exist.", copyFrom)
650 elseif (string.sub(lowerName, 1, 5) == "char/" and string.sub(lowerName, 6) == string.lower(charID)) or (string.sub(lowerName, 1, 6) == "realm/" and string.sub(lowerName, 7) == string.lower(realmID)) or (string.sub(lowerName, 1, 6) == "class/" and string.sub(lowerName, 7) == string.lower(classID)) then
651 AceDB:error("Cannot copy profile %q, it is currently in use.", name)
652 end
653 end
654 local oldName = db.raw.currentProfile[charID]
655 if type(self.OnProfileDisable) == "function" then
656 self:OnProfileDisable()
657 end
658 local oldProfileData = db.profile
659 local realName = name
660 if lowerName == "char" then
661 realName = name .. "/" .. charID
662 elseif lowerName == "realm/" then
663 realName = name .. "/" .. realmID
664 elseif lowerName == "class/" then
665 realName = name .. "/" .. classID
666 end
667 local active = self:IsActive()
668 db.raw.currentProfile[charID] = name
669 rawset(db, 'profile', nil)
670 if copyFrom then
671 for k,v in pairs(db.profile) do
672 db.profile[k] = nil
673 end
674 copyTable(db.profile, db.raw.profiles[copyFrom])
675 inheritDefaults(db.profile, db.defaults and db.defaults.profile)
676 end
677 if type(self.OnProfileEnable) == "function" then
678 self:OnProfileEnable(oldName, oldProfileData)
679 end
680 if cleanDefaults(oldProfileData, db.defaults and db.defaults.profile) then
681 db.raw.profiles[oldName] = nil
682 if not next(db.raw.profiles) then
683 db.raw.profiles = nil
684 end
685 end
686 local newactive = self:IsActive()
687 if active ~= newactive then
688 if AceOO.inherits(self, "AceAddon-2.0") then
689 local AceAddon = AceLibrary("AceAddon-2.0")
690 if not AceAddon.addonsStarted[self] then
691 return
692 end
693 end
694 if newactive then
695 if type(self.OnEnable) == "function" then
696 self:OnEnable()
697 end
698 else
699 local current = self.class
700 while true do
701 if current == AceOO.Class then
702 break
703 end
704 if current.mixins then
705 for mixin in pairs(current.mixins) do
706 if type(mixin.OnEmbedDisable) == "function" then
707 mixin:OnEmbedDisable(self)
708 end
709 end
710 end
711 current = current.super
712 end
713 if type(self.OnDisabled) == "function" then
714 self:OnDisable()
715 end
716 end
717 end
718 end
719  
720 local stage = 3
721 if tonumber(date("%Y%m%d")) < 20060714 then
722 stage = 1
723 elseif tonumber(date("%Y%m%d")) < 20060721 then
724 stage = 2
725 end
726  
727 function AceDB:IsActive()
728 return not self.db or not self.db.raw or not self.db.raw.disabled or not self.db.raw.disabled[self.db.raw.currentProfile[charID]]
729 end
730  
731 function AceDB:ToggleActive(state)
732 AceDB:argCheck(state, 2, "boolean", "nil")
733 if not self.db or not self.db.raw then
734 AceDB:error("Cannot call \"ToggleActive\" before \"RegisterDB\" has been called and before \"ADDON_LOADED\" has been fired.")
735 end
736 local db = self.db
737 if not db.raw.disabled then
738 db.raw.disabled = setmetatable({}, caseInsensitive_mt)
739 end
740 local profile = db.raw.currentProfile[charID]
741 local disable
742 if state == nil then
743 disable = not db.raw.disabled[profile]
744 else
745 disable = not state
746 if disable == db.raw.disabled[profile] then
747 return
748 end
749 end
750 db.raw.disabled[profile] = disable or nil
751 if AceOO.inherits(self, "AceAddon-2.0") then
752 local AceAddon = AceLibrary("AceAddon-2.0")
753 if not AceAddon.addonsStarted[self] then
754 return
755 end
756 end
757 if not disable then
758 if type(self.OnEnable) == "function" then
759 self:OnEnable()
760 end
761 else
762 local current = self.class
763 while true do
764 if current == AceOO.Class then
765 break
766 end
767 if current.mixins then
768 for mixin in pairs(current.mixins) do
769 if type(mixin.OnEmbedDisable) == "function" then
770 mixin:OnEmbedDisable(self)
771 end
772 end
773 end
774 current = current.super
775 end
776 if type(self.OnDisable) == "function" then
777 self:OnDisable()
778 end
779 end
780 return not disable
781 end
782  
783 if stage <= 2 then
784 function AceDB:IsEnabled()
785 if stage == 2 then
786 local line = string.gsub(debugstack(), ".-\n(.-)\n.*", "%1")
787 DEFAULT_CHAT_MESSAGE:AddMessage(line .. " - :IsEnabled() has been replaced by :IsActive(). This will cause an error on July 21, 2006.")
788 end
789 return self:IsActive()
790 end
791 function AceDB:ToggleStandby()
792 if stage == 2 then
793 local line = string.gsub(debugstack(), ".-\n(.-)\n.*", "%1")
794 DEFAULT_CHAT_MESSAGE:AddMessage(line .. " - :ToggleStandby() has been replaced by :ToggleActive([state]). This will cause an error on July 21, 2006.")
795 end
796 return self:ToggleActive()
797 end
798 end
799  
800 function AceDB:embed(target)
801 self.super.embed(self, target)
802 if not AceEvent then
803 AceDB:error(MAJOR_VERSION .. " requires AceEvent-2.0")
804 end
805 end
806  
807 function AceDB:ADDON_LOADED(name)
808 AceDB.addonsLoaded[name] = true
809 for addon, addonName in pairs(AceDB.addonsToBeInitialized) do
810 if name == addonName then
811 AceDB.InitializeDB(addon, name)
812 AceDB.addonsToBeInitialized[addon] = nil
813 end
814 end
815 end
816  
817 function AceDB:PLAYER_LOGOUT()
818 for addon in pairs(AceDB.registry) do
819 local db = addon.db
820 if db then
821 setmetatable(db, nil)
822 if db.char and cleanDefaults(db.char, db.defaults and db.defaults.char) then
823 if db.charName and _G[db.charName].global == db.char then
824 _G[db.charName].global = nil
825 if not next(_G[db.charName]) then
826 _G[db.charName] = nil
827 end
828 else
829 db.raw.chars[charID] = nil
830 if not next(db.raw.chars) then
831 db.raw.chars = nil
832 end
833 end
834 end
835 if db.realm and cleanDefaults(db.realm, db.defaults and db.defaults.realm) then
836 db.raw.realms[realmID] = nil
837 if not next(db.raw.realms) then
838 db.raw.realms = nil
839 end
840 end
841 if db.class and cleanDefaults(db.class, db.defaults and db.defaults.class) then
842 db.raw.classes[classID] = nil
843 if not next(db.raw.classes) then
844 db.raw.classes = nil
845 end
846 end
847 if db.account and cleanDefaults(db.account, db.defaults and db.defaults.account) then
848 db.raw.account = nil
849 end
850 if db.profile and cleanDefaults(db.profile, db.defaults and db.defaults.profile) then
851 db.raw.profiles[db.raw.currentProfile[charID] or "default"] = nil
852 if not next(db.raw.profiles) then
853 db.raw.profiles = nil
854 end
855 end
856 if db.namespaces then
857 for name,v in pairs(db.namespaces) do
858 setmetatable(v, nil)
859 if v.char and cleanDefaults(v.char, v.defaults and v.defaults.char) then
860 if db.charName and _G[db.charName] and _G[db.charName].namespaces and _G[db.charName].namespaces[name] == v then
861 _G[db.charName].namespaces[name] = nil
862 if not next(_G[db.charName].namespaces) then
863 _G[db.charName].namespaces = nil
864 if not next(_G[db.charName]) then
865 _G[db.charName] = nil
866 end
867 end
868 else
869 db.raw.namespaces[name].chars[charID] = nil
870 if not next(db.raw.namespaces[name].chars) then
871 db.raw.namespaces[name].chars = nil
872 end
873 end
874 end
875 if v.realm and cleanDefaults(v.realm, v.defaults and v.defaults.realm) then
876 db.raw.namespaces[name].realms[realmID] = nil
877 if not next(db.raw.namespaces[name].realms) then
878 db.raw.namespaces[name].realms = nil
879 end
880 end
881 if v.class and cleanDefaults(v.class, v.defaults and v.defaults.class) then
882 db.raw.namespaces[name].classes[classID] = nil
883 if not next(db.raw.namespaces[name].classes) then
884 db.raw.namespaces[name].classes = nil
885 end
886 end
887 if v.account and cleanDefaults(v.account, v.defaults and v.defaults.account) then
888 db.raw.namespaces[name].account = nil
889 end
890 if v.profile and cleanDefaults(v.profile, v.defaults and v.defaults.profile) then
891 db.raw.namespaces[name].profiles[db.raw.currentProfile[charID] or "default"] = nil
892 if not next(db.raw.namespaces[name].profiles) then
893 db.raw.namespaces[name].profiles = nil
894 end
895 end
896 if not next(db.raw.namespaces[name]) then
897 db.raw.namespaces[name] = nil
898 end
899 end
900 if not next(db.raw.namespaces) then
901 db.raw.namespaces = nil
902 end
903 end
904 if db.raw.disabled then
905 if not next(db.raw.disabled) then
906 db.raw.disabled = nil
907 end
908 end
909 if db.raw.currentProfile then
910 for k,v in pairs(db.raw.currentProfile) do
911 if string.lower(v) == "default" then
912 db.raw.currentProfile[k] = nil
913 end
914 end
915 if not next(db.raw.currentProfile) then
916 db.raw.currentProfile = nil
917 end
918 end
919 if not next(db.raw) then
920 _G[db.name] = nil
921 end
922 end
923 end
924 end
925  
926 function AceDB:AcquireDBNamespace(name)
927 AceDB:argCheck(name, 2, "string")
928 local db = self.db
929 if not db then
930 AceDB:error("Cannot call `AcquireDBNamespace' before `RegisterDB' has been called.", 2)
931 end
932 if not db.namespaces then
933 rawset(db, 'namespaces', {})
934 end
935 if not db.namespaces[name] then
936 local namespace = {}
937 db.namespaces[name] = namespace
938 namespace.db = db
939 namespace.name = name
940 setmetatable(namespace, namespace_mt)
941 end
942 return db.namespaces[name]
943 end
944  
945 local options
946 function AceDB:GetAceOptionsDataTable(target)
947 if not options then
948 options = {
949 standby = {
950 cmdName = STATE,
951 guiName = ACTIVE,
952 name = ACTIVE,
953 desc = TOGGLE_ACTIVE,
954 type = "toggle",
955 get = "IsActive",
956 set = "ToggleActive",
957 map = MAP_ACTIVESUSPENDED,
958 },
959 profile = {
960 name = PROFILE,
961 desc = SET_PROFILE,
962 get = "GetProfile",
963 set = "SetProfile",
964 usage = SET_PROFILE_USAGE,
965 type = "text",
966 validate = function(x) return not tonumber(x) end,
967 }
968 }
969 end
970 return options
971 end
972  
973 local function activate(self, oldLib, oldDeactivate)
974 AceDB = self
975 AceEvent = AceLibrary:HasInstance("AceEvent-2.0") and AceLibrary("AceEvent-2.0")
976  
977 self.super.activate(self, oldLib, oldDeactivate)
978  
979 for t in pairs(self.embedList) do
980 if t.db then
981 rawset(t.db, 'char', nil)
982 rawset(t.db, 'realm', nil)
983 rawset(t.db, 'class', nil)
984 rawset(t.db, 'account', nil)
985 rawset(t.db, 'profile', nil)
986 setmetatable(t.db, db_mt)
987 end
988 end
989  
990 if oldLib then
991 self.addonsToBeInitialized = oldLib.addonsToBeInitialized
992 self.addonsLoaded = oldLib.addonsLoaded
993 self.registry = oldLib.registry
994 end
995 if not self.addonsToBeInitialized then
996 self.addonsToBeInitialized = {}
997 end
998 if not self.addonsLoaded then
999 self.addonsLoaded = {}
1000 end
1001 if not self.registry then
1002 self.registry = {}
1003 end
1004  
1005 if oldLib then
1006 oldDeactivate(oldLib)
1007 end
1008 end
1009  
1010 local function external(self, major, instance)
1011 if major == "AceEvent-2.0" then
1012 AceEvent = instance
1013  
1014 AceEvent:embed(self)
1015  
1016 self:RegisterEvent("ADDON_LOADED")
1017 self:RegisterEvent("PLAYER_LOGOUT")
1018 end
1019 end
1020  
1021 AceLibrary:Register(AceDB, MAJOR_VERSION, MINOR_VERSION, activate, nil, external)
1022 AceDB = AceLibrary(MAJOR_VERSION)