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: 16114 $
4 Developed by: The Ace Development Team (http://www.wowace.com/index.php/The_Ace_Development_Team)
5 Inspired By: Ace 1.x by Turan (turan@gryphon.com)
6 Website: http://www.wowace.com/
7 Documentation: http://www.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: 16114 $"
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 local ACTIVE, ENABLED, STATE, TOGGLE_ACTIVE, MAP_ACTIVESUSPENDED, SET_PROFILE, SET_PROFILE_USAGE, PROFILE, PLAYER_OF_REALM, CHOOSE_PROFILE_DESC, CHOOSE_PROFILE_GUI, COPY_PROFILE_DESC, COPY_PROFILE_GUI, OTHER_PROFILE_DESC, OTHER_PROFILE_GUI, OTHER_PROFILE_USAGE, CHARACTER, REALM, CLASS
23  
24 if GetLocale() == "deDE" then
25 ACTIVE = "Aktiv"
26 ENABLED = "Aktiviert"
27 STATE = "Status"
28 TOGGLE_ACTIVE = "Stoppt/Aktiviert dieses Addon."
29 MAP_ACTIVESUSPENDED = { [true] = "|cff00ff00Aktiv|r", [false] = "|cffff0000Gestoppt|r" }
30 SET_PROFILE = "Setzt das Profil f\195\188r dieses Addon."
31 SET_PROFILE_USAGE = "{Charakter || Klasse || Realm || <Profilname>}"
32 PROFILE = "Profil"
33 PLAYER_OF_REALM = "%s von %s"
34 CHOOSE_PROFILE_DESC = "W\195\164hle ein Profil."
35 CHOOSE_PROFILE_GUI = "W\195\164hle"
36 COPY_PROFILE_DESC = "Kopiert Einstellungen von einem anderem Profil."
37 COPY_PROFILE_GUI = "Kopiere von"
38 OTHER_PROFILE_DESC = "W\195\164hle ein anderes Profil."
39 OTHER_PROFILE_GUI = "Anderes"
40 OTHER_PROFILE_USAGE = "<Profilname>"
41  
42 CHARACTER = "Charakter: "
43 REALM = "Realm: "
44 CLASS = "Klasse: "
45 elseif GetLocale() == "frFR" then
46 ACTIVE = "Actif"
47 ENABLED = "Activ\195\169"
48 STATE = "Etat"
49 TOGGLE_ACTIVE = "Suspend/active cet addon."
50 MAP_ACTIVESUSPENDED = { [true] = "|cff00ff00Actif|r", [false] = "|cffff0000Suspendu|r" }
51 SET_PROFILE = "S\195\169lectionne le profil pour cet addon."
52 SET_PROFILE_USAGE = "{perso || classe || royaume || <nom de profil>}"
53 PROFILE = "Profil"
54 PLAYER_OF_REALM = "%s de %s"
55 CHOOSE_PROFILE_DESC = "Choisissez un profil."
56 CHOOSE_PROFILE_GUI = "Choix"
57 COPY_PROFILE_DESC = "Copier les param\195\168tres d'un autre profil."
58 COPY_PROFILE_GUI = "Copier \195\160 partir de"
59 OTHER_PROFILE_DESC = "Choisissez un autre profil."
60 OTHER_PROFILE_GUI = "Autre"
61 OTHER_PROFILE_USAGE = "<nom de profil>"
62  
63 CHARACTER = "Personnage: "
64 REALM = "Royaume: "
65 CLASS = "Classe: "
66 elseif GetLocale() == "koKR" then
67 ACTIVE = "활성화"
68 ENABLED = "활성화"
69 STATE = "상태"
70 TOGGLE_ACTIVE = "이 애드온 중지/계속 실행"
71 MAP_ACTIVESUSPENDED = { [true] = "|cff00ff00활성화|r", [false] = "|cffff0000중지됨|r" }
72 SET_PROFILE = "이 애드온에 프로필 설정"
73 SET_PROFILE_USAGE = "{캐릭터명 || 직업 || 서버명 || <프로필명>}"
74 PROFILE = "프로필"
75 PLAYER_OF_REALM = "%s (%s 서버)"
76 CHOOSE_PROFILE_DESC = "프로파일을 선택합니다."
77 CHOOSE_PROFILE_GUI = "선택"
78 COPY_PROFILE_DESC = "다른 프로파일에서 설정을 복사합니다."
79 COPY_PROFILE_GUI = "복사"
80 OTHER_PROFILE_DESC = "다른 프로파일을 선택합니다."
81 OTHER_PROFILE_GUI = "기타"
82 OTHER_PROFILE_USAGE = "<프로파일명>"
83  
84 CHARACTER = "캐릭터: "
85 REALM = "서버: "
86 CLASS = "직업: "
87 elseif GetLocale() == "zhTW" then
88 ACTIVE = "啟動"
89 ENABLED = "啟用"
90 STATE = "狀態"
91 TOGGLE_ACTIVE = "暫停/重啟這個插件。"
92 MAP_ACTIVESUSPENDED = { [true] = "|cff00ff00啟動|r", [false] = "|cffff0000已暫停|r" }
93 SET_PROFILE = "設定這插件的記錄檔。"
94 SET_PROFILE_USAGE = "{角色 || 聯業 || 伺服器 || <記錄檔名稱>}"
95 PROFILE = "記錄檔"
96 PLAYER_OF_REALM = "%s 於 %s"
97 CHOOSE_PROFILE_DESC = "選擇一個記錄檔"
98 CHOOSE_PROFILE_GUI = "選擇"
99 COPY_PROFILE_DESC = "由其他記錄檔複製設定。"
100 COPY_PROFILE_GUI = "複製由"
101 OTHER_PROFILE_DESC = "選擇其他記錄檔。"
102 OTHER_PROFILE_GUI = "其他"
103 OTHER_PROFILE_USAGE = "<記錄檔名稱>"
104  
105 CHARACTER = "角色:"
106 REALM = "伺服器:"
107 CLASS = "聯業:"
108 elseif GetLocale() == "zhCN" then
109 ACTIVE = "\230\156\137\230\149\136"
110 ENABLED = "\229\144\175\231\148\168"
111 STATE = "\231\138\182\230\128\129"
112 TOGGLE_ACTIVE = "\230\154\130\229\129\156/\230\129\162\229\164\141 \230\173\164\230\143\146\228\187\182."
113 MAP_ACTIVESUSPENDED = { [true] = "|cff00ff00\230\156\137\230\149\136|r", [false] = "|cffff0000\230\154\130\229\129\156|r" }
114 SET_PROFILE = "\232\174\190\231\189\174\233\133\141\231\189\174\230\150\135\228\187\182\228\184\186\232\191\153\230\143\146\228\187\182."
115 SET_PROFILE_USAGE = "{\229\173\151\231\172\166 || \233\128\137\228\187\182\231\177\187 || \229\159\159 || <\233\133\141\231\189\174\230\150\135\228\187\182\229\144\141\229\173\151>}"
116 PROFILE = "\233\133\141\231\189\174\230\150\135\228\187\182"
117 PLAYER_OF_REALM = "%s \231\154\132 %s"
118 CHOOSE_PROFILE_DESC = "\233\128\137\230\139\169\233\133\141\231\189\174\230\150\135\228\187\182."
119 CHOOSE_PROFILE_GUI = "\233\128\137\230\139\169"
120 COPY_PROFILE_DESC = "\229\164\141\229\136\182\232\174\190\231\189\174\228\187\142\229\143\166\228\184\128\228\184\170\233\133\141\231\189\174\230\150\135\228\187\182."
121 COPY_PROFILE_GUI = "\229\164\141\229\136\182\228\187\142"
122 OTHER_PROFILE_DESC = "\233\128\137\230\139\169\229\143\166\228\184\128\228\184\170\233\133\141\231\189\174\230\150\135\228\187\182."
123 OTHER_PROFILE_GUI = "\229\133\182\228\187\150"
124 OTHER_PROFILE_USAGE = "<\233\133\141\231\189\174\230\150\135\228\187\182\229\144\141\229\173\151>"
125  
126 CHARACTER = "\229\173\151\231\172\166: "
127 REALM = "\229\159\159: "
128 CLASS = "\233\128\137\228\187\182\231\177\187: "
129 else -- enUS
130 ACTIVE = "Active"
131 ENABLED = "Enabled"
132 STATE = "State"
133 TOGGLE_ACTIVE = "Suspend/resume this addon."
134 MAP_ACTIVESUSPENDED = { [true] = "|cff00ff00Active|r", [false] = "|cffff0000Suspended|r" }
135 SET_PROFILE = "Set profile for this addon."
136 SET_PROFILE_USAGE = "{char || class || realm || <profile name>}"
137 PROFILE = "Profile"
138 PLAYER_OF_REALM = "%s of %s"
139 CHOOSE_PROFILE_DESC = "Choose a profile."
140 CHOOSE_PROFILE_GUI = "Choose"
141 COPY_PROFILE_DESC = "Copy settings from another profile."
142 COPY_PROFILE_GUI = "Copy from"
143 OTHER_PROFILE_DESC = "Choose another profile."
144 OTHER_PROFILE_GUI = "Other"
145 OTHER_PROFILE_USAGE = "<profile name>"
146  
147 CHARACTER = "Character: "
148 REALM = "Realm: "
149 CLASS = "Class: "
150 end
151  
152 local AceOO = AceLibrary("AceOO-2.0")
153 local AceEvent
154 local Mixin = AceOO.Mixin
155 local AceDB = Mixin {
156 "RegisterDB",
157 "RegisterDefaults",
158 "ResetDB",
159 "SetProfile",
160 "GetProfile",
161 "ToggleActive",
162 "IsActive",
163 "AcquireDBNamespace",
164 }
165 local Dewdrop = AceLibrary:HasInstance("Dewdrop-2.0") and AceLibrary("Dewdrop-2.0")
166  
167 local _G = getfenv(0)
168  
169 local table_setn
170 do
171 local version = GetBuildInfo()
172 if string.find(version, "^2%.") then
173 -- 2.0.0
174 table_setn = function() end
175 else
176 table_setn = table.setn
177 end
178 end
179  
180 local function inheritDefaults(t, defaults)
181 if not defaults then
182 return t
183 end
184 for k,v in pairs(defaults) do
185 if k == "*" then
186 local v = v
187 if type(v) == "table" then
188 setmetatable(t, {
189 __index = function(self, key)
190 if key == nil then
191 return nil
192 end
193 self[key] = {}
194 inheritDefaults(self[key], v)
195 return self[key]
196 end
197 } )
198 else
199 setmetatable(t, {
200 __index = function(self, key)
201 if key == nil then
202 return nil
203 end
204 self[key] = v
205 return self[key]
206 end
207 } )
208 end
209 for key in pairs(t) do
210 if (defaults[key] == nil or key == "*") and type(t[key]) == "table" then
211 inheritDefaults(t[key], v)
212 end
213 end
214 else
215 if type(v) == "table" then
216 if type(t[k]) ~= "table" then
217 t[k] = {}
218 end
219 inheritDefaults(t[k], v)
220 elseif t[k] == nil then
221 t[k] = v
222 end
223 end
224 end
225 return t
226 end
227  
228 local _,race = UnitRace("player")
229 local faction
230 if race == "Orc" or race == "Scourge" or race == "Troll" or race == "Tauren" then
231 faction = FACTION_HORDE
232 else
233 faction = FACTION_ALLIANCE
234 end
235 local charID = string.format(PLAYER_OF_REALM, UnitName("player"), (string.gsub(GetRealmName(), "^%s*(.-)%s*$", "%1")))
236 local realm = string.gsub(GetRealmName(), "^%s*(.-)%s*$", "%1")
237 local realmID = realm .. " - " .. faction
238 local classID = UnitClass("player")
239  
240 AceDB.CHAR_ID = charID
241 AceDB.REALM_ID = realmID
242 AceDB.CLASS_ID = classID
243  
244 AceDB.FACTION = faction
245 AceDB.REALM = realm
246 AceDB.NAME = UnitName("player")
247  
248 local new, del
249 do
250 local list = setmetatable({}, {__mode="k"})
251 function new()
252 local t = next(list)
253 if t then
254 list[t] = nil
255 return t
256 else
257 return {}
258 end
259 end
260  
261 function del(t)
262 setmetatable(t, nil)
263 for k in pairs(t) do
264 t[k] = nil
265 end
266 table_setn(t, 0)
267 list[t] = true
268 end
269 end
270  
271 local caseInsensitive_mt = {
272 __index = function(self, key)
273 if type(key) ~= "string" then
274 return nil
275 end
276 local lowerKey = string.lower(key)
277 for k,v in pairs(self) do
278 if string.lower(k) == lowerKey then
279 return self[k]
280 end
281 end
282 end,
283 __newindex = function(self, key, value)
284 if type(key) ~= "string" then
285 return error("table index is nil", 2)
286 end
287 local lowerKey = string.lower(key)
288 for k in pairs(self) do
289 if string.lower(k) == lowerKey then
290 rawset(self, k, nil)
291 rawset(self, key, value)
292 return
293 end
294 end
295 rawset(self, key, value)
296 end
297 }
298  
299 local db_mt = { __index = function(db, key)
300 if key == "char" then
301 if db.charName then
302 if type(_G[db.charName]) ~= "table" then
303 _G[db.charName] = {}
304 end
305 if type(_G[db.charName].global) ~= "table" then
306 _G[db.charName].global = {}
307 end
308 rawset(db, 'char', _G[db.charName].global)
309 else
310 if type(db.raw.chars) ~= "table" then
311 db.raw.chars = {}
312 end
313 local id = charID
314 if type(db.raw.chars[id]) ~= "table" then
315 db.raw.chars[id] = {}
316 end
317 rawset(db, 'char', db.raw.chars[id])
318 end
319 if db.defaults and db.defaults.char then
320 inheritDefaults(db.char, db.defaults.char)
321 end
322 return db.char
323 elseif key == "realm" then
324 if type(db.raw.realms) ~= "table" then
325 db.raw.realms = {}
326 end
327 local id = realmID
328 if type(db.raw.realms[id]) ~= "table" then
329 db.raw.realms[id] = {}
330 end
331 rawset(db, 'realm', db.raw.realms[id])
332 if db.defaults and db.defaults.realm then
333 inheritDefaults(db.realm, db.defaults.realm)
334 end
335 return db.realm
336 elseif key == "account" then
337 if type(db.raw.account) ~= "table" then
338 db.raw.account = {}
339 end
340 rawset(db, 'account', db.raw.account)
341 if db.defaults and db.defaults.account then
342 inheritDefaults(db.account, db.defaults.account)
343 end
344 return db.account
345 elseif key == "class" then
346 if type(db.raw.classes) ~= "table" then
347 db.raw.classes = {}
348 end
349 local id = classID
350 if type(db.raw.classes[id]) ~= "table" then
351 db.raw.classes[id] = {}
352 end
353 rawset(db, 'class', db.raw.classes[id])
354 if db.defaults and db.defaults.class then
355 inheritDefaults(db.class, db.defaults.class)
356 end
357 return db.class
358 elseif key == "profile" then
359 if type(db.raw.profiles) ~= "table" then
360 db.raw.profiles = setmetatable({}, caseInsensitive_mt)
361 else
362 setmetatable(db.raw.profiles, caseInsensitive_mt)
363 end
364 local id = db.raw.currentProfile[charID]
365 if id == "char" then
366 id = "char/" .. charID
367 elseif id == "class" then
368 id = "class/" .. classID
369 elseif id == "realm" then
370 id = "realm/" .. realmID
371 end
372 if type(db.raw.profiles[id]) ~= "table" then
373 db.raw.profiles[id] = {}
374 end
375 rawset(db, 'profile', db.raw.profiles[id])
376 if db.defaults and db.defaults.profile then
377 inheritDefaults(db.profile, db.defaults.profile)
378 end
379 return db.profile
380 elseif key == "raw" or key == "defaults" or key == "name" or key == "charName" or key == "namespaces" then
381 return nil
382 end
383 error(string.format('Cannot access key %q in db table. You may want to use db.profile[%q]', tostring(key), tostring(key)), 2)
384 end, __newindex = function(db, key, value)
385 error(string.format('Cannot access key %q in db table. You may want to use db.profile[%q]', tostring(key), tostring(key)), 2)
386 end }
387  
388 local CrawlForSerialization
389 local CrawlForDeserialization
390  
391 local function SerializeObject(o)
392 local t = { o:Serialize() }
393 t[0] = o.class:GetLibraryVersion()
394 CrawlForSerialization(t)
395 return t
396 end
397  
398 local function DeserializeObject(t)
399 CrawlForDeserialization(t)
400 local className = t[0]
401 for i = 20, 1, -1 do
402 if t[i] then
403 table_setn(t, i)
404 break
405 end
406 end
407 local o = AceLibrary(className):Deserialize(unpack(t))
408 table_setn(t, 0)
409 return o
410 end
411  
412 local function IsSerializable(t)
413 return AceOO.inherits(t, AceOO.Class) and t.class and type(t.class.Deserialize) == "function" and type(t.Serialize) == "function" and type(t.class.GetLibraryVersion) == "function"
414 end
415  
416 function CrawlForSerialization(t)
417 local tmp = new()
418 for k,v in pairs(t) do
419 tmp[k] = v
420 end
421 for k,v in pairs(tmp) do
422 if type(v) == "table" and type(v[0]) ~= "userdata" then
423 if IsSerializable(v) then
424 v = SerializeObject(v)
425 t[k] = v
426 else
427 CrawlForSerialization(v)
428 end
429 end
430 if type(k) == "table" and type(k[0]) ~= "userdata" then
431 if IsSerializable(k) then
432 t[k] = nil
433 t[SerializeObject(k)] = v
434 else
435 CrawlForSerialization(k)
436 end
437 end
438 tmp[k] = nil
439 k = nil
440 end
441 tmp = del(tmp)
442 end
443  
444 local function IsDeserializable(t)
445 return type(t[0]) == "string" and AceLibrary:HasInstance(t[0])
446 end
447  
448 function CrawlForDeserialization(t)
449 local tmp = new()
450 for k,v in pairs(t) do
451 tmp[k] = v
452 end
453 for k,v in pairs(tmp) do
454 if type(v) == "table" then
455 if IsDeserializable(v) then
456 t[k] = DeserializeObject(v)
457 del(v)
458 v = t[k]
459 elseif type(v[0]) ~= "userdata" then
460 CrawlForDeserialization(v)
461 end
462 end
463 if type(k) == "table" then
464 if IsDeserializable(k) then
465 t[k] = nil
466 t[DeserializeObject(k)] = v
467 del(k)
468 elseif type(k[0]) ~= "userdata" then
469 CrawlForDeserialization(k)
470 end
471 end
472 tmp[k] = nil
473 k = nil
474 end
475 tmp = del(tmp)
476 end
477  
478 local namespace_mt = { __index = function(namespace, key)
479 local db = namespace.db
480 local name = namespace.name
481 if key == "char" then
482 if db.charName then
483 if type(_G[db.charName]) ~= "table" then
484 _G[db.charName] = {}
485 end
486 if type(_G[db.charName].namespaces) ~= "table" then
487 _G[db.charName].namespaces = {}
488 end
489 if type(_G[db.charName].namespaces[name]) ~= "table" then
490 _G[db.charName].namespaces[name] = {}
491 end
492 rawset(namespace, 'char', _G[db.charName].namespaces[name])
493 else
494 if type(db.raw.namespaces) ~= "table" then
495 db.raw.namespaces = {}
496 end
497 if type(db.raw.namespaces[name]) ~= "table" then
498 db.raw.namespaces[name] = {}
499 end
500 if type(db.raw.namespaces[name].chars) ~= "table" then
501 db.raw.namespaces[name].chars = {}
502 end
503 local id = charID
504 if type(db.raw.namespaces[name].chars[id]) ~= "table" then
505 db.raw.namespaces[name].chars[id] = {}
506 end
507 rawset(namespace, 'char', db.raw.namespaces[name].chars[id])
508 end
509 if namespace.defaults and namespace.defaults.char then
510 inheritDefaults(namespace.char, namespace.defaults.char)
511 end
512 return namespace.char
513 elseif key == "realm" then
514 if type(db.raw.namespaces) ~= "table" then
515 db.raw.namespaces = {}
516 end
517 if type(db.raw.namespaces[name]) ~= "table" then
518 db.raw.namespaces[name] = {}
519 end
520 if type(db.raw.namespaces[name].realms) ~= "table" then
521 db.raw.namespaces[name].realms = {}
522 end
523 local id = realmID
524 if type(db.raw.namespaces[name].realms[id]) ~= "table" then
525 db.raw.namespaces[name].realms[id] = {}
526 end
527 rawset(namespace, 'realm', db.raw.namespaces[name].realms[id])
528 if namespace.defaults and namespace.defaults.realm then
529 inheritDefaults(namespace.realm, namespace.defaults.realm)
530 end
531 return namespace.realm
532 elseif key == "account" then
533 if type(db.raw.namespaces) ~= "table" then
534 db.raw.namespaces = {}
535 end
536 if type(db.raw.namespaces[name]) ~= "table" then
537 db.raw.namespaces[name] = {}
538 end
539 if type(db.raw.namespaces[name].account) ~= "table" then
540 db.raw.namespaces[name].account = {}
541 end
542 rawset(namespace, 'account', db.raw.namespaces[name].account)
543 if namespace.defaults and namespace.defaults.account then
544 inheritDefaults(namespace.account, namespace.defaults.account)
545 end
546 return namespace.account
547 elseif key == "class" then
548 if type(db.raw.namespaces) ~= "table" then
549 db.raw.namespaces = {}
550 end
551 if type(db.raw.namespaces[name]) ~= "table" then
552 db.raw.namespaces[name] = {}
553 end
554 if type(db.raw.namespaces[name].classes) ~= "table" then
555 db.raw.namespaces[name].classes = {}
556 end
557 local id = classID
558 if type(db.raw.namespaces[name].classes[id]) ~= "table" then
559 db.raw.namespaces[name].classes[id] = {}
560 end
561 rawset(namespace, 'class', db.raw.namespaces[name].classes[id])
562 if namespace.defaults and namespace.defaults.class then
563 inheritDefaults(namespace.class, namespace.defaults.class)
564 end
565 return namespace.class
566 elseif key == "profile" then
567 if type(db.raw.namespaces) ~= "table" then
568 db.raw.namespaces = {}
569 end
570 if type(db.raw.namespaces[name]) ~= "table" then
571 db.raw.namespaces[name] = {}
572 end
573 if type(db.raw.namespaces[name].profiles) ~= "table" then
574 db.raw.namespaces[name].profiles = setmetatable({}, caseInsensitive_mt)
575 else
576 setmetatable(db.raw.namespaces[name].profiles, caseInsensitive_mt)
577 end
578 local id = db.raw.currentProfile[charID]
579 if id == "char" then
580 id = "char/" .. charID
581 elseif id == "class" then
582 id = "class/" .. classID
583 elseif id == "realm" then
584 id = "realm/" .. realmID
585 end
586 if type(db.raw.namespaces[name].profiles[id]) ~= "table" then
587 db.raw.namespaces[name].profiles[id] = {}
588 end
589 rawset(namespace, 'profile', db.raw.namespaces[name].profiles[id])
590 if namespace.defaults and namespace.defaults.profile then
591 inheritDefaults(namespace.profile, namespace.defaults.profile)
592 end
593 return namespace.profile
594 elseif key == "defaults" or key == "name" or key == "db" then
595 return nil
596 end
597 error(string.format('Cannot access key %q in db table. You may want to use db.profile[%q]', tostring(key), tostring(key)), 2)
598 end, __newindex = function(db, key, value)
599 error(string.format('Cannot access key %q in db table. You may want to use db.profile[%q]', tostring(key), tostring(key)), 2)
600 end }
601  
602 function AceDB:InitializeDB(addonName)
603 local db = self.db
604  
605 if not db then
606 if addonName then
607 AceDB.addonsLoaded[addonName] = true
608 end
609 return
610 end
611  
612 if db.raw then
613 -- someone manually initialized
614 return
615 end
616  
617 if type(_G[db.name]) ~= "table" then
618 _G[db.name] = {}
619 else
620 CrawlForDeserialization(_G[db.name])
621 end
622 if type(_G[db.charName]) == "table" then
623 CrawlForDeserialization(_G[db.charName])
624 end
625 rawset(db, 'raw', _G[db.name])
626 if not db.raw.currentProfile then
627 db.raw.currentProfile = {}
628 end
629 if not db.raw.currentProfile[charID] then
630 db.raw.currentProfile[charID] = "Default"
631 end
632 if db.raw.disabled then
633 setmetatable(db.raw.disabled, caseInsensitive_mt)
634 end
635 if self['acedb-profile-copylist'] then
636 local t = self['acedb-profile-copylist']
637 for k,v in pairs(t) do
638 t[k] = nil
639 end
640 if db.raw.profiles then
641 for k in pairs(db.raw.profiles) do
642 if string.find(k, '^char/') then
643 local name = string.sub(k, 6)
644 if name ~= charID then
645 t[k] = CHARACTER .. name
646 end
647 elseif string.find(k, '^realm/') then
648 local name = string.sub(k, 7)
649 if name ~= realmID then
650 t[k] = REALM .. name
651 end
652 elseif string.find(k, '^class/') then
653 local name = string.sub(k, 7)
654 if name ~= classID then
655 t[k] = CLASS .. name
656 end
657 end
658 end
659 end
660 end
661 if self['acedb-profile-list'] then
662 local t = self['acedb-profile-list']
663 for k,v in pairs(t) do
664 t[k] = nil
665 end
666 t.char = CHARACTER .. charID
667 t.realm = REALM .. realmID
668 t.class = CLASS .. classID
669 t.Default = "Default"
670 if db.raw.profiles then
671 for k in pairs(db.raw.profiles) do
672 if not string.find(k, '^char/') and not string.find(k, '^realm/') and not string.find(k, '^class/') then
673 t[k] = k
674 end
675 end
676 end
677 end
678 setmetatable(db, db_mt)
679 end
680  
681 function AceDB:OnEmbedInitialize(target, name)
682 if name then
683 self:ADDON_LOADED(name)
684 end
685 self.InitializeDB(target, name)
686 end
687  
688 function AceDB:RegisterDB(name, charName)
689 AceDB:argCheck(name, 2, "string")
690 AceDB:argCheck(charName, 3, "string", "nil")
691 if self.db then
692 AceDB:error("Cannot call \"RegisterDB\" if self.db is set.")
693 end
694 local stack = debugstack()
695 local addonName = string.gsub(stack, ".-\n.-\\AddOns\\(.-)\\.*", "%1")
696 self.db = {
697 name = name,
698 charName = charName
699 }
700 if AceDB.addonsLoaded[addonName] then
701 AceDB.InitializeDB(self, addonName)
702 else
703 AceDB.addonsToBeInitialized[self] = addonName
704 end
705 AceDB.registry[self] = true
706 end
707  
708 function AceDB:RegisterDefaults(kind, defaults, a3)
709 local name
710 if a3 then
711 name, kind, defaults = kind, defaults, a3
712 AceDB:argCheck(name, 2, "string")
713 AceDB:argCheck(kind, 3, "string")
714 AceDB:argCheck(defaults, 4, "table")
715 if kind ~= "char" and kind ~= "class" and kind ~= "profile" and kind ~= "account" and kind ~= "realm" then
716 AceDB:error("Bad argument #3 to `RegisterDefaults' (\"char\", \"class\", \"profile\", \"account\", or \"realm\" expected, got %q)", kind)
717 end
718 else
719 AceDB:argCheck(kind, 2, "string")
720 AceDB:argCheck(defaults, 3, "table")
721 if kind ~= "char" and kind ~= "class" and kind ~= "profile" and kind ~= "account" and kind ~= "realm" then
722 AceDB:error("Bad argument #2 to `RegisterDefaults' (\"char\", \"class\", \"profile\", \"account\", or \"realm\" expected, got %q)", kind)
723 end
724 end
725 if type(self.db) ~= "table" or type(self.db.name) ~= "string" then
726 AceDB:error("Cannot call \"RegisterDefaults\" unless \"RegisterDB\" has been previously called.")
727 end
728 local db
729 if name then
730 local namespace = self:AcquireDBNamespace(name)
731 if namespace.defaults and namespace.defaults[kind] then
732 AceDB:error("\"RegisterDefaults\" has already been called for %q::%q.", name, kind)
733 end
734 db = namespace
735 else
736 if self.db.defaults and self.db.defaults[kind] then
737 AceDB:error("\"RegisterDefaults\" has already been called for %q.", kind)
738 end
739 db = self.db
740 end
741 if not db.defaults then
742 rawset(db, 'defaults', {})
743 end
744 db.defaults[kind] = defaults
745 if rawget(db, kind) then
746 inheritDefaults(db[kind], defaults)
747 end
748 end
749  
750 function AceDB:ResetDB(kind)
751 AceDB:argCheck(kind, 2, "nil", "string")
752 if not self.db or not self.db.raw then
753 AceDB:error("Cannot call \"ResetDB\" before \"RegisterDB\" has been called and before \"ADDON_LOADED\" has been fired.")
754 end
755 local db = self.db
756 if kind == nil then
757 if db.charName then
758 _G[db.charName] = nil
759 end
760 _G[db.name] = nil
761 rawset(db, 'raw', nil)
762 AceDB.InitializeDB(self)
763 if db.namespaces then
764 for name,v in pairs(db.namespaces) do
765 rawset(v, 'account', nil)
766 rawset(v, 'char', nil)
767 rawset(v, 'class', nil)
768 rawset(v, 'profile', nil)
769 rawset(v, 'realm', nil)
770 end
771 end
772 elseif kind == "account" then
773 db.raw.account = nil
774 rawset(db, 'account', nil)
775 if db.namespaces then
776 for name,v in pairs(db.namespaces) do
777 rawset(v, 'account', nil)
778 end
779 end
780 elseif kind == "char" then
781 if db.charName then
782 _G[db.charName] = nil
783 else
784 if db.raw.chars then
785 db.raw.chars[charID] = nil
786 end
787 if db.raw.namespaces then
788 for name,v in pairs(db.raw.namespaces) do
789 if v.chars then
790 v.chars[charID] = nil
791 end
792 end
793 end
794 end
795 rawset(db, 'char', nil)
796 if db.namespaces then
797 for name,v in pairs(db.namespaces) do
798 rawset(v, 'char', nil)
799 end
800 end
801 elseif kind == "realm" then
802 if db.raw.realms then
803 db.raw.realms[realmID] = nil
804 end
805 rawset(db, 'realm', nil)
806 if db.raw.namespaces then
807 for name,v in pairs(db.raw.namespaces) do
808 if v.realms then
809 v.realms[realmID] = nil
810 end
811 end
812 end
813 if db.namespaces then
814 for name,v in pairs(db.namespaces) do
815 rawset(v, 'realm', nil)
816 end
817 end
818 elseif kind == "class" then
819 if db.raw.realms then
820 db.raw.realms[classID] = nil
821 end
822 rawset(db, 'class', nil)
823 if db.raw.namespaces then
824 for name,v in pairs(db.raw.namespaces) do
825 if v.classes then
826 v.classes[classID] = nil
827 end
828 end
829 end
830 if db.namespaces then
831 for name,v in pairs(db.namespaces) do
832 rawset(v, 'class', nil)
833 end
834 end
835 elseif kind == "profile" then
836 local id = db.raw.currentProfile and db.raw.currentProfile[charID] or "Default"
837 if id == "char" then
838 id = "char/" .. charID
839 elseif id == "class" then
840 id = "class/" .. classID
841 elseif id == "realm" then
842 id = "realm/" .. realmID
843 end
844 if db.raw.profiles then
845 db.raw.profiles[id] = nil
846 end
847 rawset(db, 'profile', nil)
848 if db.raw.namespaces then
849 for name,v in pairs(db.raw.namespaces) do
850 if v.profiles then
851 v.profiles[id] = nil
852 end
853 end
854 end
855 if db.namespaces then
856 for name,v in pairs(db.namespaces) do
857 rawset(v, 'profile', nil)
858 end
859 end
860 end
861 end
862  
863 local function cleanDefaults(t, defaults)
864 if defaults then
865 for k,v in pairs(defaults) do
866 if k == "*" then
867 if type(v) == "table" then
868 for k in pairs(t) do
869 if (defaults[k] == nil or k == "*") and type(t[k]) == "table" then
870 if cleanDefaults(t[k], v) then
871 t[k] = nil
872 end
873 end
874 end
875 else
876 for k in pairs(t) do
877 if (defaults[k] == nil or k == "*") and t[k] == v then
878 t[k] = nil
879 end
880 end
881 end
882 else
883 if type(v) == "table" then
884 if type(t[k]) == "table" then
885 if cleanDefaults(t[k], v) then
886 t[k] = nil
887 end
888 end
889 elseif t[k] == v then
890 t[k] = nil
891 end
892 end
893 end
894 end
895 return t and not next(t)
896 end
897  
898 function AceDB:GetProfile()
899 if not self.db or not self.db.raw then
900 return nil
901 end
902 if not self.db.raw.currentProfile then
903 self.db.raw.currentProfile = {}
904 end
905 if not self.db.raw.currentProfile[charID] then
906 self.db.raw.currentProfile[charID] = "Default"
907 end
908 local profile = self.db.raw.currentProfile[charID]
909 if profile == "char" then
910 return "char", "char/" .. charID
911 elseif profile == "class" then
912 return "class", "class/" .. classID
913 elseif profile == "realm" then
914 return "realm", "realm/" .. realmID
915 end
916 return profile, profile
917 end
918  
919 local function copyTable(to, from)
920 setmetatable(to, nil)
921 for k,v in pairs(from) do
922 if type(k) == "table" then
923 k = copyTable({}, k)
924 end
925 if type(v) == "table" then
926 v = copyTable({}, v)
927 end
928 to[k] = v
929 end
930 table_setn(to, table.getn(from))
931 setmetatable(to, from)
932 return to
933 end
934  
935 function AceDB:SetProfile(name, copyFrom)
936 AceDB:argCheck(name, 2, "string")
937 AceDB:argCheck(copyFrom, 3, "string", "nil")
938 if not self.db or not self.db.raw then
939 AceDB:error("Cannot call \"SetProfile\" before \"RegisterDB\" has been called and before \"ADDON_LOADED\" has been fired.")
940 end
941 local db = self.db
942 local copy = false
943 local lowerName = string.lower(name)
944 local lowerCopyFrom = copyFrom and string.lower(copyFrom)
945 if string.sub(lowerName, 1, 5) == "char/" or string.sub(lowerName, 1, 6) == "realm/" or string.sub(lowerName, 1, 6) == "class/" then
946 if string.sub(lowerName, 1, 5) == "char/" then
947 name, copyFrom = "char", name
948 else
949 name, copyFrom = string.sub(lowerName, 1, 5), name
950 end
951 lowerName = string.lower(name)
952 lowerCopyFrom = string.lower(copyFrom)
953 end
954 if copyFrom then
955 if string.sub(lowerCopyFrom, 1, 5) == "char/" then
956 AceDB:assert(lowerName == "char", "If argument #3 starts with `char/', argument #2 must be `char'")
957 elseif string.sub(lowerCopyFrom, 1, 6) == "realm/" then
958 AceDB:assert(lowerName == "realm", "If argument #3 starts with `realm/', argument #2 must be `realm'")
959 elseif string.sub(lowerCopyFrom, 1, 6) == "class/" then
960 AceDB:assert(lowerName == "class", "If argument #3 starts with `class/', argument #2 must be `class'")
961 else
962 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.")
963 end
964 if not db.raw.profiles or not db.raw.profiles[copyFrom] then
965 AceDB:error("Cannot copy profile %q, it does not exist.", copyFrom)
966 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
967 AceDB:error("Cannot copy profile %q, it is currently in use.", name)
968 end
969 end
970 local oldName = db.raw.currentProfile[charID]
971 if string.lower(oldName) == string.lower(name) then
972 return
973 end
974 local oldProfileData = db.profile
975 local realName = name
976 if lowerName == "char" then
977 realName = name .. "/" .. charID
978 elseif lowerName == "realm" then
979 realName = name .. "/" .. realmID
980 elseif lowerName == "class" then
981 realName = name .. "/" .. classID
982 end
983 local current = self.class
984 while current and current ~= AceOO.Class do
985 if current.mixins then
986 for mixin in pairs(current.mixins) do
987 if type(mixin.OnEmbedProfileDisable) == "function" then
988 mixin:OnEmbedProfileDisable(self, realName)
989 end
990 end
991 end
992 current = current.super
993 end
994 if type(self.OnProfileDisable) == "function" then
995 self:OnProfileDisable(realName)
996 end
997 local active = self:IsActive()
998 db.raw.currentProfile[charID] = name
999 rawset(db, 'profile', nil)
1000 if db.namespaces then
1001 for k,v in pairs(db.namespaces) do
1002 rawset(v, 'profile', nil)
1003 end
1004 end
1005 if copyFrom then
1006 for k,v in pairs(db.profile) do
1007 db.profile[k] = nil
1008 end
1009 copyTable(db.profile, db.raw.profiles[copyFrom])
1010 inheritDefaults(db.profile, db.defaults and db.defaults.profile)
1011 if db.namespaces then
1012 for l,u in pairs(db.namespaces) do
1013 for k,v in pairs(u.profile) do
1014 u.profile[k] = nil
1015 end
1016 copyTable(u.profile, db.raw.namespaces[l].profiles[copyFrom])
1017 inheritDefaults(u.profile, u.defaults and u.defaults.profile)
1018 end
1019 end
1020 end
1021 local current = self.class
1022 while current and current ~= AceOO.Class do
1023 if current.mixins then
1024 for mixin in pairs(current.mixins) do
1025 if type(mixin.OnEmbedProfileEnable) == "function" then
1026 mixin:OnEmbedProfileEnable(self, oldName, oldProfileData, copyFrom)
1027 end
1028 end
1029 end
1030 current = current.super
1031 end
1032 if type(self.OnProfileEnable) == "function" then
1033 self:OnProfileEnable(oldName, oldProfileData, copyFrom)
1034 end
1035 if cleanDefaults(oldProfileData, db.defaults and db.defaults.profile) then
1036 db.raw.profiles[oldName] = nil
1037 if not next(db.raw.profiles) then
1038 db.raw.profiles = nil
1039 end
1040 end
1041 local newactive = self:IsActive()
1042 if active ~= newactive then
1043 if AceOO.inherits(self, "AceAddon-2.0") then
1044 local AceAddon = AceLibrary("AceAddon-2.0")
1045 if not AceAddon.addonsStarted[self] then
1046 return
1047 end
1048 end
1049 if newactive then
1050 local current = self.class
1051 while current and current ~= AceOO.Class do
1052 if current.mixins then
1053 for mixin in pairs(current.mixins) do
1054 if type(mixin.OnEmbedEnable) == "function" then
1055 mixin:OnEmbedEnable(self)
1056 end
1057 end
1058 end
1059 current = current.super
1060 end
1061 if type(self.OnEnable) == "function" then
1062 self:OnEnable()
1063 end
1064 else
1065 local current = self.class
1066 while current and current ~= AceOO.Class do
1067 if current.mixins then
1068 for mixin in pairs(current.mixins) do
1069 if type(mixin.OnEmbedDisable) == "function" then
1070 mixin:OnEmbedDisable(self)
1071 end
1072 end
1073 end
1074 current = current.super
1075 end
1076 if type(self.OnDisable) == "function" then
1077 self:OnDisable()
1078 end
1079 end
1080 end
1081 if self['acedb-profile-list'] then
1082 if not self['acedb-profile-list'][name] then
1083 self['acedb-profile-list'][name] = name
1084 end
1085 end
1086 if Dewdrop then
1087 Dewdrop:Refresh(1)
1088 Dewdrop:Refresh(2)
1089 Dewdrop:Refresh(3)
1090 Dewdrop:Refresh(4)
1091 Dewdrop:Refresh(5)
1092 end
1093 end
1094  
1095 function AceDB:IsActive()
1096 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]]
1097 end
1098  
1099 function AceDB:ToggleActive(state)
1100 AceDB:argCheck(state, 2, "boolean", "nil")
1101 if not self.db or not self.db.raw then
1102 AceDB:error("Cannot call \"ToggleActive\" before \"RegisterDB\" has been called and before \"ADDON_LOADED\" has been fired.")
1103 end
1104 local db = self.db
1105 if not db.raw.disabled then
1106 db.raw.disabled = setmetatable({}, caseInsensitive_mt)
1107 end
1108 local profile = db.raw.currentProfile[charID]
1109 local disable
1110 if state == nil then
1111 disable = not db.raw.disabled[profile]
1112 else
1113 disable = not state
1114 if disable == db.raw.disabled[profile] then
1115 return
1116 end
1117 end
1118 db.raw.disabled[profile] = disable or nil
1119 if AceOO.inherits(self, "AceAddon-2.0") then
1120 local AceAddon = AceLibrary("AceAddon-2.0")
1121 if not AceAddon.addonsStarted[self] then
1122 return
1123 end
1124 end
1125 if not disable then
1126 local current = self.class
1127 while current and current ~= AceOO.Class do
1128 if current.mixins then
1129 for mixin in pairs(current.mixins) do
1130 if type(mixin.OnEmbedEnable) == "function" then
1131 mixin:OnEmbedEnable(self)
1132 end
1133 end
1134 end
1135 current = current.super
1136 end
1137 if type(self.OnEnable) == "function" then
1138 self:OnEnable()
1139 end
1140 else
1141 local current = self.class
1142 while current and current ~= AceOO.Class do
1143 if current.mixins then
1144 for mixin in pairs(current.mixins) do
1145 if type(mixin.OnEmbedDisable) == "function" then
1146 mixin:OnEmbedDisable(self)
1147 end
1148 end
1149 end
1150 current = current.super
1151 end
1152 if type(self.OnDisable) == "function" then
1153 self:OnDisable()
1154 end
1155 end
1156 return not disable
1157 end
1158  
1159 function AceDB:embed(target)
1160 self.super.embed(self, target)
1161 if not AceEvent then
1162 AceDB:error(MAJOR_VERSION .. " requires AceEvent-2.0")
1163 end
1164 end
1165  
1166 function AceDB:ADDON_LOADED(name)
1167 AceDB.addonsLoaded[name] = true
1168 for addon, addonName in pairs(AceDB.addonsToBeInitialized) do
1169 if name == addonName then
1170 AceDB.InitializeDB(addon, name)
1171 AceDB.addonsToBeInitialized[addon] = nil
1172 end
1173 end
1174 end
1175  
1176 function AceDB:PLAYER_LOGOUT()
1177 for addon in pairs(AceDB.registry) do
1178 local db = addon.db
1179 if db then
1180 setmetatable(db, nil)
1181 CrawlForSerialization(db.raw)
1182 if type(_G[db.charName]) == "table" then
1183 CrawlForSerialization(_G[db.charName])
1184 end
1185 if db.char and cleanDefaults(db.char, db.defaults and db.defaults.char) then
1186 if db.charName and _G[db.charName] and _G[db.charName].global == db.char then
1187 _G[db.charName].global = nil
1188 if not next(_G[db.charName]) then
1189 _G[db.charName] = nil
1190 end
1191 else
1192 if db.raw.chars then
1193 db.raw.chars[charID] = nil
1194 if not next(db.raw.chars) then
1195 db.raw.chars = nil
1196 end
1197 end
1198 end
1199 end
1200 if db.realm and cleanDefaults(db.realm, db.defaults and db.defaults.realm) then
1201 if db.raw.realms then
1202 db.raw.realms[realmID] = nil
1203 if not next(db.raw.realms) then
1204 db.raw.realms = nil
1205 end
1206 end
1207 end
1208 if db.class and cleanDefaults(db.class, db.defaults and db.defaults.class) then
1209 if db.raw.classes then
1210 db.raw.classes[classID] = nil
1211 if not next(db.raw.classes) then
1212 db.raw.classes = nil
1213 end
1214 end
1215 end
1216 if db.account and cleanDefaults(db.account, db.defaults and db.defaults.account) then
1217 db.raw.account = nil
1218 end
1219 if db.profile and cleanDefaults(db.profile, db.defaults and db.defaults.profile) then
1220 if db.raw.profiles then
1221 db.raw.profiles[db.raw.currentProfile and db.raw.currentProfile[charID] or "Default"] = nil
1222 if not next(db.raw.profiles) then
1223 db.raw.profiles = nil
1224 end
1225 end
1226 end
1227 if db.namespaces and db.raw.namespaces then
1228 for name,v in pairs(db.namespaces) do
1229 if db.raw.namespaces[name] then
1230 setmetatable(v, nil)
1231 if v.char and cleanDefaults(v.char, v.defaults and v.defaults.char) then
1232 if db.charName and _G[db.charName] and _G[db.charName].namespaces and _G[db.charName].namespaces[name] == v then
1233 _G[db.charName].namespaces[name] = nil
1234 if not next(_G[db.charName].namespaces) then
1235 _G[db.charName].namespaces = nil
1236 if not next(_G[db.charName]) then
1237 _G[db.charName] = nil
1238 end
1239 end
1240 else
1241 if db.raw.namespaces[name].chars then
1242 db.raw.namespaces[name].chars[charID] = nil
1243 if not next(db.raw.namespaces[name].chars) then
1244 db.raw.namespaces[name].chars = nil
1245 end
1246 end
1247 end
1248 end
1249 if v.realm and cleanDefaults(v.realm, v.defaults and v.defaults.realm) then
1250 if db.raw.namespaces[name].realms then
1251 db.raw.namespaces[name].realms[realmID] = nil
1252 if not next(db.raw.namespaces[name].realms) then
1253 db.raw.namespaces[name].realms = nil
1254 end
1255 end
1256 end
1257 if v.class and cleanDefaults(v.class, v.defaults and v.defaults.class) then
1258 if db.raw.namespaces[name].classes then
1259 db.raw.namespaces[name].classes[classID] = nil
1260 if not next(db.raw.namespaces[name].classes) then
1261 db.raw.namespaces[name].classes = nil
1262 end
1263 end
1264 end
1265 if v.account and cleanDefaults(v.account, v.defaults and v.defaults.account) then
1266 db.raw.namespaces[name].account = nil
1267 end
1268 if v.profile and cleanDefaults(v.profile, v.defaults and v.defaults.profile) then
1269 if db.raw.namespaces[name].profiles then
1270 db.raw.namespaces[name].profiles[db.raw.currentProfile and db.raw.currentProfile[charID] or "Default"] = nil
1271 if not next(db.raw.namespaces[name].profiles) then
1272 db.raw.namespaces[name].profiles = nil
1273 end
1274 end
1275 end
1276 if not next(db.raw.namespaces[name]) then
1277 db.raw.namespaces[name] = nil
1278 end
1279 end
1280 end
1281 if not next(db.raw.namespaces) then
1282 db.raw.namespaces = nil
1283 end
1284 end
1285 if db.raw.disabled and not next(db.raw.disabled) then
1286 db.raw.disabled = nil
1287 end
1288 if db.raw.currentProfile then
1289 for k,v in pairs(db.raw.currentProfile) do
1290 if string.lower(v) == "default" then
1291 db.raw.currentProfile[k] = nil
1292 end
1293 end
1294 if not next(db.raw.currentProfile) then
1295 db.raw.currentProfile = nil
1296 end
1297 end
1298 if _G[db.name] and not next(_G[db.name]) then
1299 _G[db.name] = nil
1300 end
1301 end
1302 end
1303 end
1304  
1305 function AceDB:AcquireDBNamespace(name)
1306 AceDB:argCheck(name, 2, "string")
1307 local db = self.db
1308 if not db then
1309 AceDB:error("Cannot call `AcquireDBNamespace' before `RegisterDB' has been called.", 2)
1310 end
1311 if not db.namespaces then
1312 rawset(db, 'namespaces', {})
1313 end
1314 if not db.namespaces[name] then
1315 local namespace = {}
1316 db.namespaces[name] = namespace
1317 namespace.db = db
1318 namespace.name = name
1319 setmetatable(namespace, namespace_mt)
1320 end
1321 return db.namespaces[name]
1322 end
1323  
1324 function AceDB:GetAceOptionsDataTable(target)
1325 if not target['acedb-profile-list'] then
1326 target['acedb-profile-list'] = setmetatable({}, caseInsensitive_mt)
1327 local t = target['acedb-profile-list']
1328 for k,v in pairs(t) do
1329 t[k] = nil
1330 end
1331 t.char = CHARACTER .. charID
1332 t.realm = REALM .. realmID
1333 t.class = CLASS .. classID
1334 t.Default = "Default"
1335 if target.db and target.db.raw then
1336 local db = target.db
1337 if db.raw.profiles then
1338 for k in pairs(db.raw.profiles) do
1339 if not string.find(k, '^char/') and not string.find(k, '^realm/') and not string.find(k, '^class/') then
1340 t[k] = k
1341 end
1342 end
1343 end
1344 end
1345 end
1346 if not target['acedb-profile-copylist'] then
1347 target['acedb-profile-copylist'] = setmetatable({}, caseInsensitive_mt)
1348 if target.db and target.db.raw then
1349 local t = target['acedb-profile-copylist']
1350 local db = target.db
1351  
1352 if db.raw.profiles then
1353 for k in pairs(db.raw.profiles) do
1354 if string.find(k, '^char/') then
1355 local name = string.sub(k, 6)
1356 if name ~= charID then
1357 t[k] = CHARACTER .. name
1358 end
1359 elseif string.find(k, '^realm/') then
1360 local name = string.sub(k, 7)
1361 if name ~= realmID then
1362 t[k] = REALM .. name
1363 end
1364 elseif string.find(k, '^class/') then
1365 local name = string.sub(k, 7)
1366 if name ~= classID then
1367 t[k] = CLASS .. name
1368 end
1369 end
1370 end
1371 end
1372 end
1373 end
1374 return {
1375 standby = {
1376 cmdName = STATE,
1377 guiName = ENABLED,
1378 name = ACTIVE,
1379 desc = TOGGLE_ACTIVE,
1380 type = "toggle",
1381 get = "IsActive",
1382 set = "ToggleActive",
1383 map = MAP_ACTIVESUSPENDED,
1384 order = -3,
1385 },
1386 profile = {
1387 type = 'group',
1388 name = PROFILE,
1389 desc = SET_PROFILE,
1390 order = -3.5,
1391 get = "GetProfile",
1392 args = {
1393 choose = {
1394 guiName = CHOOSE_PROFILE_GUI,
1395 cmdName = PROFILE,
1396 desc = CHOOSE_PROFILE_DESC,
1397 type = 'text',
1398 get = "GetProfile",
1399 set = "SetProfile",
1400 validate = target['acedb-profile-list']
1401 },
1402 copy = {
1403 guiName = COPY_PROFILE_GUI,
1404 cmdName = PROFILE,
1405 desc = COPY_PROFILE_DESC,
1406 type = 'text',
1407 get = "GetProfile",
1408 set = "SetProfile",
1409 validate = target['acedb-profile-copylist'],
1410 disabled = function()
1411 return not next(target['acedb-profile-copylist'])
1412 end,
1413 },
1414 other = {
1415 guiName = OTHER_PROFILE_GUI,
1416 cmdName = PROFILE,
1417 desc = OTHER_PROFILE_DESC,
1418 usage = OTHER_PROFILE_USAGE,
1419 type = 'text',
1420 get = "GetProfile",
1421 set = "SetProfile",
1422 }
1423 }
1424 },
1425 }
1426 end
1427  
1428 local function activate(self, oldLib, oldDeactivate)
1429 AceDB = self
1430 AceEvent = AceLibrary:HasInstance("AceEvent-2.0") and AceLibrary("AceEvent-2.0")
1431  
1432 self.super.activate(self, oldLib, oldDeactivate)
1433  
1434 for t in pairs(self.embedList) do
1435 if t.db then
1436 rawset(t.db, 'char', nil)
1437 rawset(t.db, 'realm', nil)
1438 rawset(t.db, 'class', nil)
1439 rawset(t.db, 'account', nil)
1440 rawset(t.db, 'profile', nil)
1441 setmetatable(t.db, db_mt)
1442 end
1443 end
1444  
1445 if oldLib then
1446 self.addonsToBeInitialized = oldLib.addonsToBeInitialized
1447 self.addonsLoaded = oldLib.addonsLoaded
1448 self.registry = oldLib.registry
1449 end
1450 if not self.addonsToBeInitialized then
1451 self.addonsToBeInitialized = {}
1452 end
1453 if not self.addonsLoaded then
1454 self.addonsLoaded = {}
1455 end
1456 if not self.registry then
1457 self.registry = {}
1458 end
1459  
1460 if oldLib then
1461 oldDeactivate(oldLib)
1462 end
1463 end
1464  
1465 local function external(self, major, instance)
1466 if major == "AceEvent-2.0" then
1467 AceEvent = instance
1468  
1469 AceEvent:embed(self)
1470  
1471 self:RegisterEvent("ADDON_LOADED")
1472 self:RegisterEvent("PLAYER_LOGOUT")
1473 elseif major == "Dewdrop-2.0" then
1474 Dewdrop = instance
1475 end
1476 end
1477  
1478 AceLibrary:Register(AceDB, MAJOR_VERSION, MINOR_VERSION, activate, nil, external)
1479 AceDB = AceLibrary(MAJOR_VERSION)