comparison lib/AceDB-2.0/AceDB-2.0.lua @ 22:1b9323256a1b

Merging in 1.0 dev tree
author Flick <flickerstreak@gmail.com>
date Fri, 07 Mar 2008 22:10:55 +0000
parents libs/AceDB-2.0/AceDB-2.0.lua@c11ca1d8ed91
children
comparison
equal deleted inserted replaced
21:90bf38d48efd 22:1b9323256a1b
1 --[[
2 Name: AceDB-2.0
3 Revision: $Rev: 46764 $
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 License: LGPL v2.1
13 ]]
14
15 local MAJOR_VERSION = "AceDB-2.0"
16 local MINOR_VERSION = "$Revision: 46764 $"
17
18 if not AceLibrary then error(MAJOR_VERSION .. " requires AceLibrary") end
19 if not AceLibrary:IsNewVersion(MAJOR_VERSION, MINOR_VERSION) then return end
20
21 if not AceLibrary:HasInstance("AceOO-2.0") then error(MAJOR_VERSION .. " requires AceOO-2.0") end
22
23 local function safecall(func,...)
24 local success, err = pcall(func,...)
25 if not success then geterrorhandler()(err) end
26 end
27
28 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, RESET_PROFILE, RESET_PROFILE_DESC, CHARACTER_COLON, REALM_COLON, CLASS_COLON, DEFAULT, ALTERNATIVE
29
30 -- Move these into "enUS" when they've been translated in all other locales
31 local DELETE_PROFILE = "Delete"
32 local DELETE_PROFILE_DESC = "Deletes a profile. Note that no check is made whether this profile is in use by other characters or not."
33 local DELETE_PROFILE_USAGE = "<profile name>"
34
35 if GetLocale() == "deDE" then
36 ACTIVE = "Aktiv"
37 ENABLED = "Aktiviert"
38 STATE = "Status"
39 TOGGLE_ACTIVE = "Stoppt/Aktiviert dieses Addon."
40 MAP_ACTIVESUSPENDED = { [true] = "|cff00ff00Aktiv|r", [false] = "|cffff0000Gestoppt|r" }
41 SET_PROFILE = "Setzt das Profil f\195\188r dieses Addon."
42 SET_PROFILE_USAGE = "{Charakter || Klasse || Realm || <Profilname>}"
43 PROFILE = "Profil"
44 PLAYER_OF_REALM = "%s von %s"
45 CHOOSE_PROFILE_DESC = "W\195\164hle ein Profil."
46 CHOOSE_PROFILE_GUI = "W\195\164hle"
47 COPY_PROFILE_DESC = "Kopiert Einstellungen von einem anderem Profil."
48 COPY_PROFILE_GUI = "Kopiere von"
49 OTHER_PROFILE_DESC = "W\195\164hle ein anderes Profil."
50 OTHER_PROFILE_GUI = "Anderes"
51 OTHER_PROFILE_USAGE = "<Profilname>"
52 RESET_PROFILE = "Reset profile" -- fix
53 RESET_PROFILE_DESC = "Clear all settings of the current profile." -- fix
54
55 CHARACTER_COLON = "Charakter: "
56 REALM_COLON = "Realm: "
57 CLASS_COLON = "Klasse: "
58
59 DEFAULT = "Default" -- fix
60 ALTERNATIVE = "Alternative" -- fix
61 elseif GetLocale() == "frFR" then
62 ACTIVE = "Actif"
63 ENABLED = "Activ\195\169"
64 STATE = "Etat"
65 TOGGLE_ACTIVE = "Suspend/active cet addon."
66 MAP_ACTIVESUSPENDED = { [true] = "|cff00ff00Actif|r", [false] = "|cffff0000Suspendu|r" }
67 SET_PROFILE = "S\195\169lectionne le profil pour cet addon."
68 SET_PROFILE_USAGE = "{perso || classe || royaume || <nom de profil>}"
69 PROFILE = "Profil"
70 PLAYER_OF_REALM = "%s de %s"
71 CHOOSE_PROFILE_DESC = "Choisissez un profil."
72 CHOOSE_PROFILE_GUI = "Choix"
73 COPY_PROFILE_DESC = "Copier les param\195\168tres d'un autre profil."
74 COPY_PROFILE_GUI = "Copier \195\160 partir de"
75 OTHER_PROFILE_DESC = "Choisissez un autre profil."
76 OTHER_PROFILE_GUI = "Autre"
77 OTHER_PROFILE_USAGE = "<nom de profil>"
78 RESET_PROFILE = "Reset profile" -- fix
79 RESET_PROFILE_DESC = "Clear all settings of the current profile." -- fix
80
81 CHARACTER_COLON = "Personnage: "
82 REALM_COLON = "Royaume: "
83 CLASS_COLON = "Classe: "
84
85 DEFAULT = "Default" -- fix
86 ALTERNATIVE = "Alternative" -- fix
87 elseif GetLocale() == "koKR" then
88 DELETE_PROFILE = "삭제"
89 DELETE_PROFILE_DESC = "프로필을 삭제합니다."
90 DELETE_PROFILE_USAGE = "<프로필명>"
91
92 ACTIVE = "사용"
93 ENABLED = "사용"
94 STATE = "상태"
95 TOGGLE_ACTIVE = "이 애드온 중지/다시 시작"
96 MAP_ACTIVESUSPENDED = { [true] = "|cff00ff00사용|r", [false] = "|cffff0000중지|r" }
97 SET_PROFILE = "이 애드온에 프로필 설정"
98 SET_PROFILE_USAGE = "{캐릭터명 || 직업 || 서버명 || <프로필명>}"
99 PROFILE = "프로필"
100 PLAYER_OF_REALM = "%s (%s 서버)"
101 CHOOSE_PROFILE_DESC = "프로필을 선택합니다."
102 CHOOSE_PROFILE_GUI = "선택"
103 COPY_PROFILE_DESC = "다른 프로필 설정을 복사합니다."
104 COPY_PROFILE_GUI = "복사"
105 OTHER_PROFILE_DESC = "다른 프로필을 선택합니다."
106 OTHER_PROFILE_GUI = "기타"
107 OTHER_PROFILE_USAGE = "<프로필명>"
108 RESET_PROFILE = "프로필 초기화"
109 RESET_PROFILE_DESC = "모든 세팅에서 현재 프로필을 초기화 합니다."
110
111 CHARACTER_COLON = "캐릭터: "
112 REALM_COLON = "서버: "
113 CLASS_COLON = "직업: "
114
115 DEFAULT = "기본값"
116 ALTERNATIVE = "대체"
117 elseif GetLocale() == "zhTW" then
118 DELETE_PROFILE = "刪除"
119 DELETE_PROFILE_DESC = "刪除記錄檔。注意,有可能別的角色也使用這個記錄檔。"
120 DELETE_PROFILE_USAGE = "<記錄檔名稱>"
121
122 ACTIVE = "啟動"
123 ENABLED = "啟用"
124 STATE = "狀態"
125 TOGGLE_ACTIVE = "暫停/繼續使用這個插件。"
126 MAP_ACTIVESUSPENDED = { [true] = "|cff00ff00啟動|r", [false] = "|cffff0000已暫停|r" }
127 SET_PROFILE = "設定這插件的記錄檔。"
128 SET_PROFILE_USAGE = "{角色 || 職業 || 伺服器 || <記錄檔名稱>}"
129 PROFILE = "記錄檔"
130 PLAYER_OF_REALM = "%s - %s"
131 CHOOSE_PROFILE_DESC = "選擇一個記錄檔。"
132 CHOOSE_PROFILE_GUI = "選擇"
133 COPY_PROFILE_DESC = "由其他記錄檔複製設定。"
134 COPY_PROFILE_GUI = "複製自"
135 OTHER_PROFILE_DESC = "選擇其他記錄檔。"
136 OTHER_PROFILE_GUI = "其他"
137 OTHER_PROFILE_USAGE = "<記錄檔名稱>"
138 RESET_PROFILE = "重設記錄檔"
139 RESET_PROFILE_DESC = "清除目前的記錄檔上的所有設定。"
140
141 CHARACTER_COLON = "角色: "
142 REALM_COLON = "伺服器: "
143 CLASS_COLON = "職業: "
144
145 DEFAULT = "預設"
146 ALTERNATIVE = "替代"
147 elseif GetLocale() == "zhCN" then
148 ACTIVE = "\230\156\137\230\149\136"
149 ENABLED = "\229\144\175\231\148\168"
150 STATE = "\231\138\182\230\128\129"
151 TOGGLE_ACTIVE = "\230\154\130\229\129\156/\230\129\162\229\164\141 \230\173\164\230\143\146\228\187\182."
152 MAP_ACTIVESUSPENDED = { [true] = "|cff00ff00\230\156\137\230\149\136|r", [false] = "|cffff0000\230\154\130\229\129\156|r" }
153 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."
154 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>}"
155 PROFILE = "\233\133\141\231\189\174\230\150\135\228\187\182"
156 PLAYER_OF_REALM = "%s \231\154\132 %s"
157 CHOOSE_PROFILE_DESC = "\233\128\137\230\139\169\233\133\141\231\189\174\230\150\135\228\187\182."
158 CHOOSE_PROFILE_GUI = "\233\128\137\230\139\169"
159 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."
160 COPY_PROFILE_GUI = "\229\164\141\229\136\182\228\187\142"
161 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."
162 OTHER_PROFILE_GUI = "\229\133\182\228\187\150"
163 OTHER_PROFILE_USAGE = "<\233\133\141\231\189\174\230\150\135\228\187\182\229\144\141\229\173\151>"
164 RESET_PROFILE = "Reset profile" -- fix
165 RESET_PROFILE_DESC = "Clear all settings of the current profile." -- fix
166
167 CHARACTER_COLON = "\229\173\151\231\172\166: "
168 REALM_COLON = "\229\159\159: "
169 CLASS_COLON = "\233\128\137\228\187\182\231\177\187: "
170
171 DEFAULT = "Default" -- fix
172 ALTERNATIVE = "Alternative" -- fix
173 elseif GetLocale() == "esES" then
174 ACTIVE = "Activo"
175 ENABLED = "Activado"
176 STATE = "Estado"
177 TOGGLE_ACTIVE = "Parar/Continuar este accesorio"
178 MAP_ACTIVESUSPENDED = { [true] = "|cff00ff00Activo|r", [false] = "|cffff0000Parado|r" }
179 SET_PROFILE = "Selecciona el perfil para este accesorio."
180 SET_PROFILE_USAGE = "{perso || clase || reino || <nombre del perfil>}"
181 PROFILE = "Perfil"
182 PLAYER_OF_REALM = "%s de %s"
183 CHOOSE_PROFILE_DESC = "Elige un perfil."
184 CHOOSE_PROFILE_GUI = "Elige"
185 COPY_PROFILE_DESC = "Copiar de un perfil a otro"
186 COPY_PROFILE_GUI = "Copiar desde"
187 OTHER_PROFILE_DESC = "Elige otro perfil."
188 OTHER_PROFILE_GUI = "Otro"
189 OTHER_PROFILE_USAGE = "<nombre del perfil>"
190 RESET_PROFILE = "Reset profile" -- fix
191 RESET_PROFILE_DESC = "Clear all settings of the current profile." -- fix
192
193 CHARACTER_COLON = "Personaje: "
194 REALM_COLON = "Reino: "
195 CLASS_COLON = "Clase: "
196
197 DEFAULT = "Por defecto"
198 ALTERNATIVE = "Alternativo"
199 else -- enUS
200 ACTIVE = "Active"
201 ENABLED = "Enabled"
202 STATE = "State"
203 TOGGLE_ACTIVE = "Suspend/resume this addon."
204 MAP_ACTIVESUSPENDED = { [true] = "|cff00ff00Active|r", [false] = "|cffff0000Suspended|r" }
205 SET_PROFILE = "Set profile for this addon."
206 SET_PROFILE_USAGE = "{char || class || realm || <profile name>}"
207 PROFILE = "Profile"
208 PLAYER_OF_REALM = "%s of %s"
209 CHOOSE_PROFILE_DESC = "Choose a profile."
210 CHOOSE_PROFILE_GUI = "Choose"
211 COPY_PROFILE_DESC = "Copy settings from another profile."
212 COPY_PROFILE_GUI = "Copy from"
213 OTHER_PROFILE_DESC = "Choose another profile."
214 OTHER_PROFILE_GUI = "Other"
215 OTHER_PROFILE_USAGE = "<profile name>"
216 RESET_PROFILE = "Reset profile"
217 RESET_PROFILE_DESC = "Clear all settings of the current profile."
218
219 CHARACTER_COLON = "Character: "
220 REALM_COLON = "Realm: "
221 CLASS_COLON = "Class: "
222
223 DEFAULT = "Default"
224 ALTERNATIVE = "Alternative"
225 end
226 local convertFromOldCharID
227 do
228 local matchStr = "^" .. PLAYER_OF_REALM:gsub("([%(%)%.%*%+%-%[%]%?%^%$%%])", "%%%1"):gsub("%%s", "(.+)") .. "$"
229 function convertFromOldCharID(str)
230 local player, realm = str:match(matchStr)
231 if not player then
232 return str
233 end
234 return player .. " - " .. realm
235 end
236 end
237
238 local AceOO = AceLibrary("AceOO-2.0")
239 local AceEvent
240 local Mixin = AceOO.Mixin
241 local AceDB = Mixin {
242 "RegisterDB",
243 "RegisterDefaults",
244 "ResetDB",
245 "SetProfile",
246 "GetProfile",
247 "CopyProfileFrom",
248 "DeleteProfile",
249 "ToggleActive",
250 "IsActive",
251 "AcquireDBNamespace",
252 }
253 local Dewdrop = AceLibrary:HasInstance("Dewdrop-2.0") and AceLibrary("Dewdrop-2.0")
254
255 local _G = getfenv(0)
256
257 local function inheritDefaults(t, defaults)
258 if not defaults then
259 return t
260 end
261 for k,v in pairs(defaults) do
262 if k == "*" or k == "**" then
263 local v = v
264 if type(v) == "table" then
265 setmetatable(t, {
266 __index = function(self, key)
267 if key == nil then
268 return nil
269 end
270 self[key] = {}
271 inheritDefaults(self[key], v)
272 return self[key]
273 end
274 } )
275 else
276 setmetatable(t, {
277 __index = function(self, key)
278 if key == nil then
279 return nil
280 end
281 self[key] = v
282 return self[key]
283 end
284 } )
285 end
286 for key in pairs(t) do
287 if (defaults[key] == nil or key == k) and type(t[key]) == "table" then
288 inheritDefaults(t[key], v)
289 end
290 end
291 else
292 if type(v) == "table" then
293 if type(rawget(t, k)) ~= "table" then
294 t[k] = {}
295 end
296 inheritDefaults(t[k], v)
297 if defaults["**"] then
298 inheritDefaults(t[k], defaults["**"])
299 end
300 elseif rawget(t, k) == nil then
301 t[k] = v
302 end
303 end
304 end
305 return t
306 end
307
308 local _,race = UnitRace("player")
309 local faction
310 if race == "Orc" or race == "Scourge" or race == "Troll" or race == "Tauren" or race == "BloodElf" then
311 faction = FACTION_HORDE
312 else
313 faction = FACTION_ALLIANCE
314 end
315 local server = GetRealmName():trim()
316 local charID = UnitName("player") .. " - " .. server
317 local realmID = server .. " - " .. faction
318 local classID = UnitClass("player")
319
320 AceDB.CHAR_ID = charID
321 AceDB.REALM_ID = realmID
322 AceDB.CLASS_ID = classID
323
324 AceDB.FACTION = faction
325 AceDB.REALM = server
326 AceDB.NAME = UnitName("player")
327
328 local new, del
329 do
330 local list = setmetatable({}, {__mode="k"})
331 function new()
332 local t = next(list)
333 if t then
334 list[t] = nil
335 return t
336 else
337 return {}
338 end
339 end
340
341 function del(t)
342 setmetatable(t, nil)
343 for k in pairs(t) do
344 t[k] = nil
345 end
346 list[t] = true
347 end
348 end
349
350 local caseInsensitive_mt = {
351 __index = function(self, key)
352 if type(key) ~= "string" then
353 return nil
354 end
355 local lowerKey = key:lower()
356 for k,v in pairs(self) do
357 if k:lower() == lowerKey then
358 return self[k]
359 end
360 end
361 end,
362 __newindex = function(self, key, value)
363 if type(key) ~= "string" then
364 return error("table index is nil", 2)
365 end
366 local lowerKey = key:lower()
367 for k in pairs(self) do
368 if k:lower() == lowerKey then
369 rawset(self, k, nil)
370 rawset(self, key, value)
371 return
372 end
373 end
374 rawset(self, key, value)
375 end
376 }
377
378 local db_mt = { __index = function(db, key)
379 if key == "char" then
380 if db.charName then
381 if type(_G[db.charName]) ~= "table" then
382 _G[db.charName] = {}
383 end
384 if type(_G[db.charName].global) ~= "table" then
385 _G[db.charName].global = {}
386 end
387 rawset(db, 'char', _G[db.charName].global)
388 else
389 if type(db.raw.chars) ~= "table" then
390 db.raw.chars = {}
391 end
392 local id = charID
393 if type(db.raw.chars[id]) ~= "table" then
394 db.raw.chars[id] = {}
395 end
396 rawset(db, 'char', db.raw.chars[id])
397 end
398 if db.defaults and db.defaults.char then
399 inheritDefaults(db.char, db.defaults.char)
400 end
401 return db.char
402 elseif key == "realm" then
403 if type(db.raw.realms) ~= "table" then
404 db.raw.realms = {}
405 end
406 local id = realmID
407 if type(db.raw.realms[id]) ~= "table" then
408 db.raw.realms[id] = {}
409 end
410 rawset(db, 'realm', db.raw.realms[id])
411 if db.defaults and db.defaults.realm then
412 inheritDefaults(db.realm, db.defaults.realm)
413 end
414 return db.realm
415 elseif key == "server" then
416 if type(db.raw.servers) ~= "table" then
417 db.raw.servers = {}
418 end
419 local id = server
420 if type(db.raw.servers[id]) ~= "table" then
421 db.raw.servers[id] = {}
422 end
423 rawset(db, 'server', db.raw.servers[id])
424 if db.defaults and db.defaults.server then
425 inheritDefaults(db.server, db.defaults.server)
426 end
427 return db.server
428 elseif key == "account" then
429 if type(db.raw.account) ~= "table" then
430 db.raw.account = {}
431 end
432 rawset(db, 'account', db.raw.account)
433 if db.defaults and db.defaults.account then
434 inheritDefaults(db.account, db.defaults.account)
435 end
436 return db.account
437 elseif key == "faction" then
438 if type(db.raw.factions) ~= "table" then
439 db.raw.factions = {}
440 end
441 local id = faction
442 if type(db.raw.factions[id]) ~= "table" then
443 db.raw.factions[id] = {}
444 end
445 rawset(db, 'faction', db.raw.factions[id])
446 if db.defaults and db.defaults.faction then
447 inheritDefaults(db.faction, db.defaults.faction)
448 end
449 return db.faction
450 elseif key == "class" then
451 if type(db.raw.classes) ~= "table" then
452 db.raw.classes = {}
453 end
454 local id = classID
455 if type(db.raw.classes[id]) ~= "table" then
456 db.raw.classes[id] = {}
457 end
458 rawset(db, 'class', db.raw.classes[id])
459 if db.defaults and db.defaults.class then
460 inheritDefaults(db.class, db.defaults.class)
461 end
462 return db.class
463 elseif key == "profile" then
464 if type(db.raw.profiles) ~= "table" then
465 db.raw.profiles = setmetatable({}, caseInsensitive_mt)
466 else
467 setmetatable(db.raw.profiles, caseInsensitive_mt)
468 end
469 local id = db.raw.currentProfile[charID]
470 if id == "char" then
471 id = "char/" .. charID
472 elseif id == "class" then
473 id = "class/" .. classID
474 elseif id == "realm" then
475 id = "realm/" .. realmID
476 end
477 if type(db.raw.profiles[id]) ~= "table" then
478 db.raw.profiles[id] = {}
479 end
480 rawset(db, 'profile', db.raw.profiles[id])
481 if db.defaults and db.defaults.profile then
482 inheritDefaults(db.profile, db.defaults.profile)
483 end
484 return db.profile
485 elseif key == "raw" or key == "defaults" or key == "name" or key == "charName" or key == "namespaces" then
486 return nil
487 end
488 error(("Cannot access key %q in db table. You may want to use db.profile[%q]"):format(tostring(key), tostring(key)), 2)
489 end, __newindex = function(db, key, value)
490 error(("Cannot access key %q in db table. You may want to use db.profile[%q]"):format(tostring(key), tostring(key)), 2)
491 end }
492
493 local function RecalculateAceDBCopyFromList(target)
494 local db = target.db
495 local t = target['acedb-profile-copylist']
496 for k,v in pairs(t) do
497 t[k] = nil
498 end
499 local _,currentProfile = AceDB.GetProfile(target)
500 if db and db.raw then
501 if db.raw.profiles then
502 for k in pairs(db.raw.profiles) do
503 if currentProfile ~= k then
504 if k:find("^char/") then
505 local name = k:sub(6)
506 local player, realm = name:match("^(.*) %- (.*)$")
507 if player then
508 name = PLAYER_OF_REALM:format(player, realm)
509 end
510 t[k] = CHARACTER_COLON .. name
511 elseif k:find("^realm/") then
512 local name = k:sub(7)
513 t[k] = REALM_COLON .. name
514 elseif k:find("^class/") then
515 local name = k:sub(7)
516 t[k] = CLASS_COLON .. name
517 else
518 t[k] = k
519 end
520 end
521 end
522 end
523 if db.raw.namespaces then
524 for _,n in pairs(db.raw.namespaces) do
525 if n.profiles then
526 for k in pairs(n.profiles) do
527 if currentProfile ~= k then
528 if k:find('^char/') then
529 local name = k:sub(6)
530 local player, realm = name:match("^(.*) %- (.*)$")
531 if player then
532 name = PLAYER_OF_REALM:format(player, realm)
533 end
534 t[k] = CHARACTER_COLON .. name
535 elseif k:find('^realm/') then
536 local name = k:sub(7)
537 t[k] = REALM_COLON .. name
538 elseif k:find('^class/') then
539 local name = k:sub(7)
540 t[k] = CLASS_COLON .. name
541 else
542 t[k] = k
543 end
544 end
545 end
546 end
547 end
548 end
549 end
550 if t.Default then
551 t.Default = DEFAULT
552 end
553 if t.Alternative then
554 t.Alternative = ALTERNATIVE
555 end
556 end
557
558 local function RecalculateAceDBProfileList(target)
559 local t = target['acedb-profile-list']
560 for k,v in pairs(t) do
561 t[k] = nil
562 end
563 t.char = CHARACTER_COLON .. PLAYER_OF_REALM:format(UnitName("player"), server)
564 t.realm = REALM_COLON .. realmID
565 t.class = CLASS_COLON .. classID
566 t.Default = DEFAULT
567 local db = target.db
568 if db and db.raw then
569 if db.raw.profiles then
570 for k in pairs(db.raw.profiles) do
571 if not k:find("^char/") and not k:find("^realm/") and not k:find("^class/") then
572 t[k] = k
573 end
574 end
575 end
576 if db.raw.namespaces then
577 for _,n in pairs(db.raw.namespaces) do
578 if n.profiles then
579 for k in pairs(n.profiles) do
580 if not k:find("^char/") and not k:find("^realm/") and not k:find("^class/") then
581 t[k] = k
582 end
583 end
584 end
585 end
586 end
587 local curr = db.raw.currentProfile and db.raw.currentProfile[charID]
588 if curr and not t[curr] then
589 t[curr] = curr
590 end
591 end
592 if t.Alternative then
593 t.Alternative = ALTERNATIVE
594 end
595 end
596
597 local CrawlForSerialization
598 local CrawlForDeserialization
599
600 local function SerializeObject(o)
601 local t = { o:Serialize() }
602 CrawlForSerialization(t)
603 t[0] = o.class:GetLibraryVersion()
604 return t
605 end
606
607 local function DeserializeObject(t)
608 CrawlForDeserialization(t)
609 local className = t[0]
610 t[0] = nil
611 return AceLibrary(className):Deserialize(unpack(t))
612 end
613
614 local function IsSerializable(t)
615 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"
616 end
617
618 function CrawlForSerialization(t)
619 local tmp = new()
620 for k,v in pairs(t) do
621 tmp[k] = v
622 end
623 for k,v in pairs(tmp) do
624 if type(v) == "table" and type(rawget(v, 0)) ~= "userdata" then
625 if IsSerializable(v) then
626 v = SerializeObject(v)
627 t[k] = v
628 else
629 CrawlForSerialization(v)
630 end
631 end
632 if type(k) == "table" and type(rawget(k, 0)) ~= "userdata" then
633 if IsSerializable(k) then
634 t[k] = nil
635 t[SerializeObject(k)] = v
636 else
637 CrawlForSerialization(k)
638 end
639 end
640 tmp[k] = nil
641 k = nil
642 end
643 tmp = del(tmp)
644 end
645
646 local function IsDeserializable(t)
647 return type(rawget(t, 0)) == "string" and AceLibrary:HasInstance(rawget(t, 0))
648 end
649
650 function CrawlForDeserialization(t)
651 local tmp = new()
652 for k,v in pairs(t) do
653 tmp[k] = v
654 end
655 for k,v in pairs(tmp) do
656 if type(v) == "table" then
657 if IsDeserializable(v) then
658 t[k] = DeserializeObject(v)
659 del(v)
660 v = t[k]
661 elseif type(rawget(v, 0)) ~= "userdata" then
662 CrawlForDeserialization(v)
663 end
664 end
665 if type(k) == "table" then
666 if IsDeserializable(k) then
667 t[k] = nil
668 t[DeserializeObject(k)] = v
669 del(k)
670 elseif type(rawget(k, 0)) ~= "userdata" then
671 CrawlForDeserialization(k)
672 end
673 end
674 tmp[k] = nil
675 k = nil
676 end
677 tmp = del(tmp)
678 end
679
680 local namespace_mt = { __index = function(namespace, key)
681 local db = namespace.db
682 local name = namespace.name
683 if key == "char" then
684 if db.charName then
685 if type(_G[db.charName]) ~= "table" then
686 _G[db.charName] = {}
687 end
688 if type(_G[db.charName].namespaces) ~= "table" then
689 _G[db.charName].namespaces = {}
690 end
691 if type(_G[db.charName].namespaces[name]) ~= "table" then
692 _G[db.charName].namespaces[name] = {}
693 end
694 rawset(namespace, 'char', _G[db.charName].namespaces[name])
695 else
696 if type(db.raw.namespaces) ~= "table" then
697 db.raw.namespaces = {}
698 end
699 if type(db.raw.namespaces[name]) ~= "table" then
700 db.raw.namespaces[name] = {}
701 end
702 if type(db.raw.namespaces[name].chars) ~= "table" then
703 db.raw.namespaces[name].chars = {}
704 end
705 local id = charID
706 if type(db.raw.namespaces[name].chars[id]) ~= "table" then
707 db.raw.namespaces[name].chars[id] = {}
708 end
709 rawset(namespace, 'char', db.raw.namespaces[name].chars[id])
710 end
711 if namespace.defaults and namespace.defaults.char then
712 inheritDefaults(namespace.char, namespace.defaults.char)
713 end
714 return namespace.char
715 elseif key == "realm" then
716 if type(db.raw.namespaces) ~= "table" then
717 db.raw.namespaces = {}
718 end
719 if type(db.raw.namespaces[name]) ~= "table" then
720 db.raw.namespaces[name] = {}
721 end
722 if type(db.raw.namespaces[name].realms) ~= "table" then
723 db.raw.namespaces[name].realms = {}
724 end
725 local id = realmID
726 if type(db.raw.namespaces[name].realms[id]) ~= "table" then
727 db.raw.namespaces[name].realms[id] = {}
728 end
729 rawset(namespace, 'realm', db.raw.namespaces[name].realms[id])
730 if namespace.defaults and namespace.defaults.realm then
731 inheritDefaults(namespace.realm, namespace.defaults.realm)
732 end
733 return namespace.realm
734 elseif key == "server" then
735 if type(db.raw.namespaces) ~= "table" then
736 db.raw.namespaces = {}
737 end
738 if type(db.raw.namespaces[name]) ~= "table" then
739 db.raw.namespaces[name] = {}
740 end
741 if type(db.raw.namespaces[name].servers) ~= "table" then
742 db.raw.namespaces[name].servers = {}
743 end
744 local id = server
745 if type(db.raw.namespaces[name].servers[id]) ~= "table" then
746 db.raw.namespaces[name].servers[id] = {}
747 end
748 rawset(namespace, 'server', db.raw.namespaces[name].servers[id])
749 if namespace.defaults and namespace.defaults.server then
750 inheritDefaults(namespace.server, namespace.defaults.server)
751 end
752 return namespace.server
753 elseif key == "account" then
754 if type(db.raw.namespaces) ~= "table" then
755 db.raw.namespaces = {}
756 end
757 if type(db.raw.namespaces[name]) ~= "table" then
758 db.raw.namespaces[name] = {}
759 end
760 if type(db.raw.namespaces[name].account) ~= "table" then
761 db.raw.namespaces[name].account = {}
762 end
763 rawset(namespace, 'account', db.raw.namespaces[name].account)
764 if namespace.defaults and namespace.defaults.account then
765 inheritDefaults(namespace.account, namespace.defaults.account)
766 end
767 return namespace.account
768 elseif key == "faction" then
769 if type(db.raw.namespaces) ~= "table" then
770 db.raw.namespaces = {}
771 end
772 if type(db.raw.namespaces[name]) ~= "table" then
773 db.raw.namespaces[name] = {}
774 end
775 if type(db.raw.namespaces[name].factions) ~= "table" then
776 db.raw.namespaces[name].factions = {}
777 end
778 local id = faction
779 if type(db.raw.namespaces[name].factions[id]) ~= "table" then
780 db.raw.namespaces[name].factions[id] = {}
781 end
782 rawset(namespace, 'faction', db.raw.namespaces[name].factions[id])
783 if namespace.defaults and namespace.defaults.faction then
784 inheritDefaults(namespace.faction, namespace.defaults.faction)
785 end
786 return namespace.faction
787 elseif key == "class" then
788 if type(db.raw.namespaces) ~= "table" then
789 db.raw.namespaces = {}
790 end
791 if type(db.raw.namespaces[name]) ~= "table" then
792 db.raw.namespaces[name] = {}
793 end
794 if type(db.raw.namespaces[name].classes) ~= "table" then
795 db.raw.namespaces[name].classes = {}
796 end
797 local id = classID
798 if type(db.raw.namespaces[name].classes[id]) ~= "table" then
799 db.raw.namespaces[name].classes[id] = {}
800 end
801 rawset(namespace, 'class', db.raw.namespaces[name].classes[id])
802 if namespace.defaults and namespace.defaults.class then
803 inheritDefaults(namespace.class, namespace.defaults.class)
804 end
805 return namespace.class
806 elseif key == "profile" then
807 if type(db.raw.namespaces) ~= "table" then
808 db.raw.namespaces = {}
809 end
810 if type(db.raw.namespaces[name]) ~= "table" then
811 db.raw.namespaces[name] = {}
812 end
813 if type(db.raw.namespaces[name].profiles) ~= "table" then
814 db.raw.namespaces[name].profiles = setmetatable({}, caseInsensitive_mt)
815 else
816 setmetatable(db.raw.namespaces[name].profiles, caseInsensitive_mt)
817 end
818 local id = db.raw.currentProfile[charID]
819 if id == "char" then
820 id = "char/" .. charID
821 elseif id == "class" then
822 id = "class/" .. classID
823 elseif id == "realm" then
824 id = "realm/" .. realmID
825 end
826 if type(db.raw.namespaces[name].profiles[id]) ~= "table" then
827 db.raw.namespaces[name].profiles[id] = {}
828 end
829 rawset(namespace, 'profile', db.raw.namespaces[name].profiles[id])
830 if namespace.defaults and namespace.defaults.profile then
831 inheritDefaults(namespace.profile, namespace.defaults.profile)
832 end
833 return namespace.profile
834 elseif key == "defaults" or key == "name" or key == "db" then
835 return nil
836 end
837 error(("Cannot access key %q in db table. You may want to use db.profile[%q]"):format(tostring(key), tostring(key)), 2)
838 end, __newindex = function(db, key, value)
839 error(("Cannot access key %q in db table. You may want to use db.profile[%q]"):format(tostring(key), tostring(key)), 2)
840 end }
841
842 local tmp = {}
843 function AceDB:InitializeDB(addonName)
844 local db = self.db
845
846 if not db then
847 if addonName then
848 AceDB.addonsLoaded[addonName] = true
849 end
850 return
851 end
852
853 if db.raw then
854 -- someone manually initialized
855 return
856 end
857
858 if type(_G[db.name]) ~= "table" then
859 _G[db.name] = {}
860 else
861 CrawlForDeserialization(_G[db.name])
862 end
863 if db.charName then
864 if type(_G[db.charName]) ~= "table" then
865 _G[db.charName] = {}
866 else
867 CrawlForDeserialization(_G[db.charName])
868 end
869 end
870 rawset(db, 'raw', _G[db.name])
871 if not db.raw.currentProfile then
872 db.raw.currentProfile = {}
873 else
874 for k,v in pairs(db.raw.currentProfile) do
875 tmp[convertFromOldCharID(k)] = v
876 db.raw.currentProfile[k] = nil
877 end
878 for k,v in pairs(tmp) do
879 db.raw.currentProfile[k] = v
880 tmp[k] = nil
881 end
882 end
883 if not db.raw.currentProfile[charID] then
884 db.raw.currentProfile[charID] = AceDB.registry[self] or "Default"
885 end
886 if db.raw.profiles then
887 for k,v in pairs(db.raw.profiles) do
888 local new_k = k
889 if k:find("^char/") then
890 new_k = "char/" .. convertFromOldCharID(k:sub(6))
891 end
892 tmp[new_k] = v
893 db.raw.profiles[k] = nil
894 end
895 for k,v in pairs(tmp) do
896 db.raw.profiles[k] = v
897 tmp[k] = nil
898 end
899 end
900 if db.raw.disabledModules then -- AceModuleCore-2.0
901 for k,v in pairs(db.raw.disabledModules) do
902 local new_k = k
903 if k:find("^char/") then
904 new_k = "char/" .. convertFromOldCharID(k:sub(6))
905 end
906 tmp[new_k] = v
907 db.raw.disabledModules[k] = nil
908 end
909 for k,v in pairs(tmp) do
910 db.raw.disabledModules[k] = v
911 tmp[k] = nil
912 end
913 end
914 if db.raw.chars then
915 for k,v in pairs(db.raw.chars) do
916 tmp[convertFromOldCharID(k)] = v
917 db.raw.chars[k] = nil
918 end
919 for k,v in pairs(tmp) do
920 db.raw.chars[k] = v
921 tmp[k] = nil
922 end
923 end
924 if db.raw.namespaces then
925 for l,u in pairs(db.raw.namespaces) do
926 if u.chars then
927 for k,v in pairs(u.chars) do
928 tmp[convertFromOldCharID(k)] = v
929 u.chars[k] = nil
930 end
931 for k,v in pairs(tmp) do
932 u.chars[k] = v
933 tmp[k] = nil
934 end
935 end
936 end
937 end
938 if db.raw.disabled then
939 setmetatable(db.raw.disabled, caseInsensitive_mt)
940 end
941 if self['acedb-profile-copylist'] then
942 RecalculateAceDBCopyFromList(self)
943 end
944 if self['acedb-profile-list'] then
945 RecalculateAceDBProfileList(self)
946 end
947 setmetatable(db, db_mt)
948 end
949
950 function AceDB:OnEmbedInitialize(target, name)
951 if name then
952 self:ADDON_LOADED(name)
953 end
954 self.InitializeDB(target, name)
955 end
956
957 function AceDB:RegisterDB(name, charName, defaultProfile)
958 AceDB:argCheck(name, 2, "string")
959 AceDB:argCheck(charName, 3, "string", "nil")
960 AceDB:argCheck(defaultProfile, 4, "string", "nil")
961 if self.db then
962 AceDB:error("Cannot call \"RegisterDB\" if self.db is set.")
963 end
964 local stack = debugstack()
965 local addonName = stack:gsub(".-\n.-\\AddOns\\(.-)\\.*", "%1")
966 self.db = {
967 name = name,
968 charName = charName
969 }
970 AceDB.registry[self] = defaultProfile or "Default"
971 if AceDB.addonsLoaded[addonName] then
972 AceDB.InitializeDB(self, addonName)
973 else
974 AceDB.addonsToBeInitialized[self] = addonName
975 end
976 end
977
978 function AceDB:RegisterDefaults(kind, defaults, a3)
979 local name
980 if a3 then
981 name, kind, defaults = kind, defaults, a3
982 AceDB:argCheck(name, 2, "string")
983 AceDB:argCheck(kind, 3, "string")
984 AceDB:argCheck(defaults, 4, "table")
985 else
986 AceDB:argCheck(kind, 2, "string")
987 AceDB:argCheck(defaults, 3, "table")
988 end
989 if kind ~= "char" and kind ~= "class" and kind ~= "profile" and kind ~= "account" and kind ~= "realm" and kind ~= "faction" and kind ~= "server" then
990 AceDB:error("Bad argument #%d to `RegisterDefaults' (\"char\", \"class\", \"profile\", \"account\", \"realm\", \"server\", or \"faction\" expected, got %q)", a3 and 3 or 2, kind)
991 end
992 if type(self.db) ~= "table" or type(self.db.name) ~= "string" then
993 AceDB:error("Cannot call \"RegisterDefaults\" unless \"RegisterDB\" has been previously called.")
994 end
995 local db
996 if name then
997 local namespace = self:AcquireDBNamespace(name)
998 if namespace.defaults and namespace.defaults[kind] then
999 AceDB:error("\"RegisterDefaults\" has already been called for %q::%q.", name, kind)
1000 end
1001 db = namespace
1002 else
1003 if self.db.defaults and self.db.defaults[kind] then
1004 AceDB:error("\"RegisterDefaults\" has already been called for %q.", kind)
1005 end
1006 db = self.db
1007 end
1008 if not db.defaults then
1009 rawset(db, 'defaults', {})
1010 end
1011 db.defaults[kind] = defaults
1012 if rawget(db, kind) then
1013 inheritDefaults(db[kind], defaults)
1014 end
1015 end
1016
1017 function AceDB:ResetDB(kind, a2)
1018 local name
1019 if a2 then
1020 name, kind = kind, a2
1021 AceDB:argCheck(name, 2, "nil", "string")
1022 AceDB:argCheck(kind, 3, "nil", "string")
1023 else
1024 AceDB:argCheck(kind, 2, "nil", "string")
1025 if kind ~= "char" and kind ~= "class" and kind ~= "profile" and kind ~= "account" and kind ~= "realm" and kind ~= "faction" and kind ~= "server" then
1026 name, kind = kind, nil
1027 end
1028 end
1029 if not self.db or not self.db.raw then
1030 AceDB:error("Cannot call \"ResetDB\" before \"RegisterDB\" has been called and before \"ADDON_LOADED\" has been fired.")
1031 end
1032 local db = self.db
1033 if not kind then
1034 if not name then
1035 if db.charName then
1036 _G[db.charName] = nil
1037 end
1038 _G[db.name] = nil
1039 rawset(db, 'raw', nil)
1040 AceDB.InitializeDB(self)
1041 if db.namespaces then
1042 for name,v in pairs(db.namespaces) do
1043 rawset(v, 'account', nil)
1044 rawset(v, 'char', nil)
1045 rawset(v, 'class', nil)
1046 rawset(v, 'profile', nil)
1047 rawset(v, 'realm', nil)
1048 rawset(v, 'server', nil)
1049 rawset(v, 'faction', nil)
1050 end
1051 end
1052 else
1053 if db.raw.namespaces then
1054 db.raw.namespaces[name] = nil
1055 end
1056 if db.namespaces then
1057 local v = db.namespaces[name]
1058 if v then
1059 rawset(v, 'account', nil)
1060 rawset(v, 'char', nil)
1061 rawset(v, 'class', nil)
1062 rawset(v, 'profile', nil)
1063 rawset(v, 'realm', nil)
1064 rawset(v, 'server', nil)
1065 rawset(v, 'faction', nil)
1066 end
1067 end
1068 end
1069 elseif kind == "account" then
1070 if name then
1071 db.raw.account = nil
1072 rawset(db, 'account', nil)
1073 if db.raw.namespaces then
1074 for name,v in pairs(db.raw.namespaces) do
1075 v.account = nil
1076 end
1077 end
1078 if db.namespaces then
1079 for name,v in pairs(db.namespaces) do
1080 rawset(v, 'account', nil)
1081 end
1082 end
1083 else
1084 if db.raw.namespaces and db.raw.namespaces[name] then
1085 db.raw.namespaces[name].account = nil
1086 end
1087 if db.namespaces then
1088 local v = db.namespaces[name]
1089 if v then
1090 rawset(v, 'account', nil)
1091 end
1092 end
1093 end
1094 elseif kind == "char" then
1095 if name then
1096 if db.charName then
1097 _G[db.charName] = nil
1098 else
1099 if db.raw.chars then
1100 db.raw.chars[charID] = nil
1101 end
1102 if db.raw.namespaces then
1103 for name,v in pairs(db.raw.namespaces) do
1104 if v.chars then
1105 v.chars[charID] = nil
1106 end
1107 end
1108 end
1109 end
1110 rawset(db, 'char', nil)
1111 if db.namespaces then
1112 for name,v in pairs(db.namespaces) do
1113 rawset(v, 'char', nil)
1114 end
1115 end
1116 else
1117 if db.charName then
1118 local x = _G[db.charName]
1119 if x.namespaces then
1120 x.namespaces[name] = nil
1121 end
1122 else
1123 if db.raw.namespaces then
1124 local v = db.namespaces[name]
1125 if v and v.chars then
1126 v.chars[charID] = nil
1127 end
1128 end
1129 end
1130 if db.namespaces then
1131 local v = db.namespaces[name]
1132 if v then
1133 rawset(v, 'char', nil)
1134 end
1135 end
1136 end
1137 elseif kind == "realm" then
1138 if not name then
1139 if db.raw.realms then
1140 db.raw.realms[realmID] = nil
1141 end
1142 rawset(db, 'realm', nil)
1143 if db.raw.namespaces then
1144 for name,v in pairs(db.raw.namespaces) do
1145 if v.realms then
1146 v.realms[realmID] = nil
1147 end
1148 end
1149 end
1150 if db.namespaces then
1151 for name,v in pairs(db.namespaces) do
1152 rawset(v, 'realm', nil)
1153 end
1154 end
1155 else
1156 if db.raw.namespaces then
1157 local v = db.raw.namespaces[name]
1158 if v and v.realms then
1159 v.realms[realmID] = nil
1160 end
1161 end
1162 if db.namespaces then
1163 local v = db.namespaces[name]
1164 if v then
1165 rawset(v, 'realm', nil)
1166 end
1167 end
1168 end
1169 elseif kind == "server" then
1170 if not name then
1171 if db.raw.servers then
1172 db.raw.servers[server] = nil
1173 end
1174 rawset(db, 'server', nil)
1175 if db.raw.namespaces then
1176 for name,v in pairs(db.raw.namespaces) do
1177 if v.servers then
1178 v.servers[server] = nil
1179 end
1180 end
1181 end
1182 if db.namespaces then
1183 for name,v in pairs(db.namespaces) do
1184 rawset(v, 'server', nil)
1185 end
1186 end
1187 else
1188 if db.raw.namespaces then
1189 local v = db.raw.namespaces[name]
1190 if v and v.servers then
1191 v.servers[server] = nil
1192 end
1193 end
1194 if db.namespaces then
1195 local v = db.namespaces[name]
1196 if v then
1197 rawset(v, 'server', nil)
1198 end
1199 end
1200 end
1201 elseif kind == "faction" then
1202 if not name then
1203 if db.raw.factions then
1204 db.raw.factions[faction] = nil
1205 end
1206 rawset(db, 'faction', nil)
1207 if db.raw.namespaces then
1208 for name,v in pairs(db.raw.namespaces) do
1209 if v.factions then
1210 v.factions[faction] = nil
1211 end
1212 end
1213 end
1214 if db.namespaces then
1215 for name,v in pairs(db.namespaces) do
1216 rawset(v, 'faction', nil)
1217 end
1218 end
1219 else
1220 if db.raw.namespaces then
1221 local v = db.raw.namespaces[name]
1222 if v and v.factions then
1223 v.factions[faction] = nil
1224 end
1225 end
1226 if db.namespaces then
1227 local v = db.namespaces[name]
1228 if v then
1229 rawset(v, 'faction', nil)
1230 end
1231 end
1232 end
1233 elseif kind == "class" then
1234 if not name then
1235 if db.raw.realms then
1236 db.raw.realms[classID] = nil
1237 end
1238 rawset(db, 'class', nil)
1239 if db.raw.namespaces then
1240 for name,v in pairs(db.raw.namespaces) do
1241 if v.classes then
1242 v.classes[classID] = nil
1243 end
1244 end
1245 end
1246 if db.namespaces then
1247 for name,v in pairs(db.namespaces) do
1248 rawset(v, 'class', nil)
1249 end
1250 end
1251 else
1252 if db.raw.namespaces then
1253 local v = db.raw.namespaces[name]
1254 if v and v.classes then
1255 v.classes[classID] = nil
1256 end
1257 end
1258 if db.namespaces then
1259 local v = db.namespaces[name]
1260 if v then
1261 rawset(v, 'class', nil)
1262 end
1263 end
1264 end
1265 elseif kind == "profile" then
1266 local id = db.raw.currentProfile and db.raw.currentProfile[charID] or AceDB.registry[self] or "Default"
1267 if id == "char" then
1268 id = "char/" .. charID
1269 elseif id == "class" then
1270 id = "class/" .. classID
1271 elseif id == "realm" then
1272 id = "realm/" .. realmID
1273 end
1274
1275 local current = self.class
1276 while current and current ~= AceOO.Class do
1277 if current.mixins then
1278 for mixin in pairs(current.mixins) do
1279 if type(mixin.OnEmbedProfileDisable) == "function" then
1280 safecall(mixin.OnEmbedProfileDisable, mixin, self, id)
1281 end
1282 end
1283 end
1284 current = current.super
1285 end
1286 if type(self.OnProfileDisable) == "function" then
1287 safecall(self.OnProfileDisable, self, id)
1288 end
1289 local active = self:IsActive()
1290
1291 if not name then
1292 if db.raw.profiles then
1293 db.raw.profiles[id] = nil
1294 end
1295 rawset(db, 'profile', nil)
1296 if db.raw.namespaces then
1297 for name,v in pairs(db.raw.namespaces) do
1298 if v.profiles then
1299 v.profiles[id] = nil
1300 end
1301 end
1302 end
1303 if db.namespaces then
1304 for name,v in pairs(db.namespaces) do
1305 rawset(v, 'profile', nil)
1306 end
1307 end
1308 else
1309 if db.raw.namespaces then
1310 local v = db.raw.namespaces[name]
1311 if v and v.profiles then
1312 v.profiles[id] = nil
1313 end
1314 end
1315 if db.namespaces then
1316 local v = db.namespaces[name]
1317 if v then
1318 rawset(v, 'profile', nil)
1319 end
1320 end
1321 end
1322
1323 local current = self.class
1324 while current and current ~= AceOO.Class do
1325 if current.mixins then
1326 for mixin in pairs(current.mixins) do
1327 if type(mixin.OnEmbedProfileEnable) == "function" then
1328 safecall(mixin.OnEmbedProfileEnable, mixin, self, id)
1329 end
1330 end
1331 end
1332 current = current.super
1333 end
1334 if type(self.OnProfileEnable) == "function" then
1335 safecall(self.OnProfileEnable, self, id)
1336 end
1337 local newactive = self:IsActive()
1338 if active ~= newactive then
1339 if newactive then
1340 local first = nil
1341 if AceOO.inherits(self, "AceAddon-2.0") then
1342 local AceAddon = AceLibrary("AceAddon-2.0")
1343 if not AceAddon.addonsStarted[self] then
1344 return
1345 end
1346 if AceAddon.addonsEnabled and not AceAddon.addonsEnabled[self] then
1347 AceAddon.addonsEnabled[self] = true
1348 first = true
1349 end
1350 end
1351 local current = self.class
1352 while current and current ~= AceOO.Class do
1353 if current.mixins then
1354 for mixin in pairs(current.mixins) do
1355 if type(mixin.OnEmbedEnable) == "function" then
1356 safecall(mixin.OnEmbedEnable, mixin, self, first)
1357 end
1358 end
1359 end
1360 current = current.super
1361 end
1362 if type(self.OnEnable) == "function" then
1363 safecall(self.OnEnable, self, first)
1364 end
1365 if AceEvent then
1366 AceEvent:TriggerEvent("Ace2_AddonEnabled", self, first)
1367 end
1368 else
1369 local current = self.class
1370 while current and current ~= AceOO.Class do
1371 if current.mixins then
1372 for mixin in pairs(current.mixins) do
1373 if type(mixin.OnEmbedDisable) == "function" then
1374 safecall(mixin.OnEmbedDisable, mixin, self)
1375 end
1376 end
1377 end
1378 current = current.super
1379 end
1380 if type(self.OnDisable) == "function" then
1381 safecall(self.OnDisable, self)
1382 end
1383 if AceEvent then
1384 AceEvent:TriggerEvent("Ace2_AddonDisabled", self)
1385 end
1386 end
1387 end
1388 else
1389 return -- skip event
1390 end
1391 if AceEvent then
1392 AceEvent:TriggerEvent("AceDB20_ResetDB", self, self.db.name, kind)
1393 end
1394 end
1395
1396 local function cleanDefaults(t, defaults, blocker)
1397 if defaults then
1398 for k,v in pairs(t) do
1399 if (not blocker or (blocker[k] == nil and blocker['*'] == nil and blocker['**'] == nil)) and (defaults[k] ~= nil or defaults['*'] ~= nil or defaults['**'] ~= nil) then
1400 local u = defaults[k]
1401 if u == nil then
1402 u = defaults['*']
1403 if u == nil then
1404 u = defaults['**']
1405 end
1406 end
1407 if v == u then
1408 t[k] = nil
1409 elseif type(v) == "table" and type(u) == "table" then
1410 if cleanDefaults(v, u) then
1411 t[k] = nil
1412 else
1413 local w = defaults['**']
1414 if w ~= u then
1415 if cleanDefaults(v, w, u) then
1416 t[k] = nil
1417 end
1418 end
1419 end
1420 end
1421 end
1422 end
1423 end
1424 return t and next(t) == nil
1425 end
1426
1427 function AceDB:GetProfile()
1428 if not self.db or not self.db.raw then
1429 return nil
1430 end
1431 if not self.db.raw.currentProfile then
1432 self.db.raw.currentProfile = {}
1433 end
1434 if not self.db.raw.currentProfile[charID] then
1435 self.db.raw.currentProfile[charID] = AceDB.registry[self] or "Default"
1436 end
1437 local profile = self.db.raw.currentProfile[charID]
1438 if profile == "char" then
1439 return "char", "char/" .. charID
1440 elseif profile == "class" then
1441 return "class", "class/" .. classID
1442 elseif profile == "realm" then
1443 return "realm", "realm/" .. realmID
1444 end
1445 return profile, profile
1446 end
1447
1448 local function copyTable(to, from)
1449 setmetatable(to, nil)
1450 for k,v in pairs(from) do
1451 if type(k) == "table" then
1452 k = copyTable({}, k)
1453 end
1454 if type(v) == "table" then
1455 v = copyTable({}, v)
1456 end
1457 to[k] = v
1458 end
1459 setmetatable(to, from)
1460 return to
1461 end
1462
1463 function AceDB:SetProfile(name)
1464 AceDB:argCheck(name, 2, "string")
1465 if not self.db or not self.db.raw then
1466 AceDB:error("Cannot call \"SetProfile\" before \"RegisterDB\" has been called and before \"ADDON_LOADED\" has been fired.")
1467 end
1468 local db = self.db
1469 local lowerName = name:lower()
1470 if lowerName:find("^char/") or lowerName:find("^realm/") or lowerName:find("^class/") then
1471 if lowerName:find("^char/") then
1472 name = "char"
1473 else
1474 name = lowerName:sub(1, 5)
1475 end
1476 lowerName = name:lower()
1477 end
1478 local oldName = db.raw.currentProfile[charID]
1479 if oldName:lower() == name:lower() then
1480 return
1481 end
1482 local oldProfileData = db.profile
1483 local realName = name
1484 if lowerName == "char" then
1485 realName = name .. "/" .. charID
1486 elseif lowerName == "realm" then
1487 realName = name .. "/" .. realmID
1488 elseif lowerName == "class" then
1489 realName = name .. "/" .. classID
1490 end
1491 local current = self.class
1492 while current and current ~= AceOO.Class do
1493 if current.mixins then
1494 for mixin in pairs(current.mixins) do
1495 if type(mixin.OnEmbedProfileDisable) == "function" then
1496 safecall(mixin.OnEmbedProfileDisable, mixin, self, realName)
1497 end
1498 end
1499 end
1500 current = current.super
1501 end
1502 if type(self.OnProfileDisable) == "function" then
1503 safecall(self.OnProfileDisable, self, realName)
1504 end
1505 local active = self:IsActive()
1506 db.raw.currentProfile[charID] = name
1507 rawset(db, 'profile', nil)
1508 if db.namespaces then
1509 for k,v in pairs(db.namespaces) do
1510 rawset(v, 'profile', nil)
1511 end
1512 end
1513 local current = self.class
1514 while current and current ~= AceOO.Class do
1515 if current.mixins then
1516 for mixin in pairs(current.mixins) do
1517 if type(mixin.OnEmbedProfileEnable) == "function" then
1518 safecall(mixin.OnEmbedProfileEnable, mixin, self, oldName, oldProfileData)
1519 end
1520 end
1521 end
1522 current = current.super
1523 end
1524 if type(self.OnProfileEnable) == "function" then
1525 safecall(self.OnProfileEnable, self, oldName, oldProfileData)
1526 end
1527 if cleanDefaults(oldProfileData, db.defaults and db.defaults.profile) then
1528 db.raw.profiles[oldName] = nil
1529 if not next(db.raw.profiles) then
1530 db.raw.profiles = nil
1531 end
1532 end
1533 local newactive = self:IsActive()
1534 if active ~= newactive then
1535 local first = nil
1536 if AceOO.inherits(self, "AceAddon-2.0") then
1537 local AceAddon = AceLibrary("AceAddon-2.0")
1538 if not AceAddon.addonsStarted[self] then
1539 return
1540 end
1541 if AceAddon.addonsEnabled and not AceAddon.addonsEnabled[self] then
1542 first = true
1543 end
1544 end
1545 if newactive then
1546 local current = self.class
1547 while current and current ~= AceOO.Class do
1548 if current.mixins then
1549 for mixin in pairs(current.mixins) do
1550 if type(mixin.OnEmbedEnable) == "function" then
1551 safecall(mixin.OnEmbedEnable, mixin, self, first)
1552 end
1553 end
1554 end
1555 current = current.super
1556 end
1557 if type(self.OnEnable) == "function" then
1558 safecall(self.OnEnable, self, first)
1559 end
1560 if AceEvent then
1561 AceEvent:TriggerEvent("Ace2_AddonEnabled", self, first)
1562 end
1563 else
1564 local current = self.class
1565 while current and current ~= AceOO.Class do
1566 if current.mixins then
1567 for mixin in pairs(current.mixins) do
1568 if type(mixin.OnEmbedDisable) == "function" then
1569 safecall(mixin.OnEmbedDisable, mixin, self)
1570 end
1571 end
1572 end
1573 current = current.super
1574 end
1575 if type(self.OnDisable) == "function" then
1576 safecall(self.OnDisable, self)
1577 end
1578 if AceEvent then
1579 AceEvent:TriggerEvent("Ace2_AddonDisabled", self)
1580 end
1581 end
1582 end
1583 if self['acedb-profile-list'] then
1584 RecalculateAceDBProfileList(self)
1585 end
1586 if self['acedb-profile-copylist'] then
1587 RecalculateAceDBCopyFromList(self)
1588 end
1589 if Dewdrop then
1590 Dewdrop:Refresh()
1591 end
1592 end
1593
1594 function AceDB:CopyProfileFrom(copyFrom)
1595 AceDB:argCheck(copyFrom, 2, "string")
1596 if not self.db or not self.db.raw then
1597 AceDB:error("Cannot call \"CopyProfileFrom\" before \"RegisterDB\" has been called and before \"ADDON_LOADED\" has been fired.")
1598 end
1599 local db = self.db
1600 local lowerCopyFrom = copyFrom:lower()
1601 if not db.raw.profiles or not db.raw.profiles[copyFrom] then
1602 local good = false
1603 if db.raw.namespaces then
1604 for _,n in pairs(db.raw.namespaces) do
1605 if n.profiles and n.profiles[copyFrom] then
1606 good = true
1607 break
1608 end
1609 end
1610 end
1611 if not good then
1612 AceDB:error("Cannot copy from profile %q, it does not exist.", copyFrom)
1613 end
1614 end
1615 local currentProfile = db.raw.currentProfile[charID]
1616 if currentProfile:lower() == lowerCopyFrom then
1617 AceDB:error("Cannot copy from profile %q, it is currently in use.", copyFrom)
1618 end
1619 local oldProfileData = db.profile
1620 local current = self.class
1621 while current and current ~= AceOO.Class do
1622 if current.mixins then
1623 for mixin in pairs(current.mixins) do
1624 if type(mixin.OnEmbedProfileDisable) == "function" then
1625 safecall(mixin.OnEmbedProfileDisable, mixin, self, currentProfile)
1626 end
1627 end
1628 end
1629 current = current.super
1630 end
1631 if type(self.OnProfileDisable) == "function" then
1632 safecall(self.OnProfileDisable, self, realName)
1633 end
1634 local active = self:IsActive()
1635 for k,v in pairs(db.profile) do
1636 db.profile[k] = nil
1637 end
1638 if db.raw.profiles[copyFrom] then
1639 copyTable(db.profile, db.raw.profiles[copyFrom])
1640 end
1641 inheritDefaults(db.profile, db.defaults and db.defaults.profile)
1642 if db.namespaces then
1643 for l,u in pairs(db.namespaces) do
1644 for k,v in pairs(u.profile) do
1645 u.profile[k] = nil
1646 end
1647 if db.raw.namespaces[l].profiles[copyFrom] then
1648 copyTable(u.profile, db.raw.namespaces[l].profiles[copyFrom])
1649 end
1650 inheritDefaults(u.profile, u.defaults and u.defaults.profile)
1651 end
1652 end
1653 local current = self.class
1654 while current and current ~= AceOO.Class do
1655 if current.mixins then
1656 for mixin in pairs(current.mixins) do
1657 if type(mixin.OnEmbedProfileEnable) == "function" then
1658 safecall(mixin.OnEmbedProfileEnable, mixin, self, copyFrom, oldProfileData, copyFrom)
1659 end
1660 end
1661 end
1662 current = current.super
1663 end
1664 if type(self.OnProfileEnable) == "function" then
1665 safecall(self.OnProfileEnable, self, copyFrom, oldProfileData, copyFrom)
1666 end
1667 local newactive = self:IsActive()
1668 if active ~= newactive then
1669 if AceOO.inherits(self, "AceAddon-2.0") then
1670 local AceAddon = AceLibrary("AceAddon-2.0")
1671 if not AceAddon.addonsStarted[self] then
1672 return
1673 end
1674 end
1675 if newactive then
1676 local current = self.class
1677 while current and current ~= AceOO.Class do
1678 if current.mixins then
1679 for mixin in pairs(current.mixins) do
1680 if type(mixin.OnEmbedEnable) == "function" then
1681 safecall(mixin.OnEmbedEnable, mixin, self)
1682 end
1683 end
1684 end
1685 current = current.super
1686 end
1687 if type(self.OnEnable) == "function" then
1688 safecall(self.OnEnable, self)
1689 end
1690 if AceEvent then
1691 AceEvent:TriggerEvent("Ace2_AddonEnabled", self)
1692 end
1693 else
1694 local current = self.class
1695 while current and current ~= AceOO.Class do
1696 if current.mixins then
1697 for mixin in pairs(current.mixins) do
1698 if type(mixin.OnEmbedDisable) == "function" then
1699 safecall(mixin.OnEmbedDisable, mixin, self)
1700 end
1701 end
1702 end
1703 current = current.super
1704 end
1705 if type(self.OnDisable) == "function" then
1706 safecall(self.OnDisable, self)
1707 end
1708 if AceEvent then
1709 AceEvent:TriggerEvent("Ace2_AddonDisabled", self)
1710 end
1711 end
1712 end
1713 if self['acedb-profile-list'] then
1714 RecalculateAceDBProfileList(self)
1715 end
1716 if self['acedb-profile-copylist'] then
1717 RecalculateAceDBCopyFromList(self)
1718 end
1719 if Dewdrop then
1720 Dewdrop:Refresh()
1721 end
1722 end
1723
1724 function AceDB:DeleteProfile(profile, noconfirm)
1725 AceDB:argCheck(profile , 2, "string")
1726 if not self.db or not self.db.raw then
1727 AceDB:error("Cannot call \"DeleteProfile\" before \"RegisterDB\" has been called and before \"ADDON_LOADED\" has been fired.")
1728 end
1729 local db = self.db
1730
1731 local currentProfile = db.raw.currentProfile[charID]
1732 if currentProfile:lower() == profile:lower() then
1733 AceDB:error("Cannot delete profile %q, it is currently in use.", profile)
1734 end
1735
1736 if not (noconfirm or IsShiftKeyDown()) then
1737 if not StaticPopupDialogs["ACEDB20_CONFIRM_DELETE_DIALOG"] then
1738 StaticPopupDialogs["ACEDB20_CONFIRM_DELETE_DIALOG"] = {}
1739 end
1740 local t = StaticPopupDialogs["ACEDB20_CONFIRM_DELETE_DIALOG"]
1741 t.text = format("%s: %s?", DELETE_PROFILE, profile)
1742 t.button1 = DELETE_PROFILE
1743 t.button2 = CANCEL or "Cancel"
1744 t.OnAccept = function()
1745 self:DeleteProfile(profile, true)
1746 end
1747 t.timeout = 0
1748 t.whileDead = 1
1749 t.hideOnEscape = 1
1750
1751 StaticPopup_Show("ACEDB20_CONFIRM_DELETE_DIALOG")
1752 return;
1753 end
1754
1755 local good = false
1756 if db.raw.profiles and db.raw.profiles[profile] then
1757 good = true;
1758 db.raw.profiles[profile] = nil;
1759 end
1760
1761 if db.raw.namespaces then
1762 for _,n in pairs(db.raw.namespaces) do
1763 if n.profiles and n.profiles[profile] then
1764 n.profiles[profile] = nil;
1765 good = true
1766 end
1767 end
1768 end
1769
1770 if not good then
1771 AceDB:error("Cannot delete profile %q, it does not exist.", profile)
1772 end
1773
1774 if self['acedb-profile-list'] then
1775 RecalculateAceDBProfileList(self)
1776 end
1777 if self['acedb-profile-copylist'] then
1778 RecalculateAceDBCopyFromList(self)
1779 end
1780
1781 if Dewdrop then
1782 Dewdrop:Refresh()
1783 end
1784 end
1785
1786 function AceDB:IsActive()
1787 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]]
1788 end
1789
1790 function AceDB:ToggleActive(state)
1791 AceDB:argCheck(state, 2, "boolean", "nil")
1792 if not self.db or not self.db.raw then
1793 AceDB:error("Cannot call \"ToggleActive\" before \"RegisterDB\" has been called and before \"ADDON_LOADED\" has been fired.")
1794 end
1795 local db = self.db
1796 if not db.raw.disabled then
1797 db.raw.disabled = setmetatable({}, caseInsensitive_mt)
1798 end
1799 local profile = db.raw.currentProfile[charID]
1800 local disable
1801 if state == nil then
1802 disable = not db.raw.disabled[profile]
1803 else
1804 disable = not state
1805 if disable == db.raw.disabled[profile] then
1806 return
1807 end
1808 end
1809 db.raw.disabled[profile] = disable or nil
1810 if AceOO.inherits(self, "AceAddon-2.0") then
1811 local AceAddon = AceLibrary("AceAddon-2.0")
1812 if not AceAddon.addonsStarted[self] then
1813 return
1814 end
1815 end
1816 if not disable then
1817 local current = self.class
1818 while current and current ~= AceOO.Class do
1819 if current.mixins then
1820 for mixin in pairs(current.mixins) do
1821 if type(mixin.OnEmbedEnable) == "function" then
1822 safecall(mixin.OnEmbedEnable, mixin, self)
1823 end
1824 end
1825 end
1826 current = current.super
1827 end
1828 if type(self.OnEnable) == "function" then
1829 safecall(self.OnEnable, self)
1830 end
1831 if AceEvent then
1832 AceEvent:TriggerEvent("Ace2_AddonEnabled", self)
1833 end
1834 else
1835 local current = self.class
1836 while current and current ~= AceOO.Class do
1837 if current.mixins then
1838 for mixin in pairs(current.mixins) do
1839 if type(mixin.OnEmbedDisable) == "function" then
1840 safecall(mixin.OnEmbedDisable, mixin, self)
1841 end
1842 end
1843 end
1844 current = current.super
1845 end
1846 if type(self.OnDisable) == "function" then
1847 safecall(self.OnDisable, self)
1848 end
1849 if AceEvent then
1850 AceEvent:TriggerEvent("Ace2_AddonDisabled", self)
1851 end
1852 end
1853 return not disable
1854 end
1855
1856 function AceDB:embed(target)
1857 self.super.embed(self, target)
1858 if not AceEvent then
1859 AceDB:error(MAJOR_VERSION .. " requires AceEvent-2.0")
1860 end
1861 end
1862
1863 function AceDB:ADDON_LOADED(name)
1864 AceDB.addonsLoaded[name] = true
1865 for addon, addonName in pairs(AceDB.addonsToBeInitialized) do
1866 if name == addonName then
1867 AceDB.InitializeDB(addon, name)
1868 AceDB.addonsToBeInitialized[addon] = nil
1869 end
1870 end
1871 end
1872
1873 function AceDB:PLAYER_LOGOUT()
1874 for addon, defaultProfile in pairs(AceDB.registry) do
1875 local db = addon.db
1876 if db then
1877 if type(addon.OnDatabaseCleanup) == "function" then
1878 safecall(addon.OnDatabaseCleanup, addon)
1879 end
1880 setmetatable(db, nil)
1881 CrawlForSerialization(db.raw)
1882 if type(_G[db.charName]) == "table" then
1883 CrawlForSerialization(_G[db.charName])
1884 end
1885 if db.char and cleanDefaults(db.char, db.defaults and db.defaults.char) then
1886 if db.charName and _G[db.charName] and _G[db.charName].global == db.char then
1887 _G[db.charName].global = nil
1888 if not next(_G[db.charName]) then
1889 _G[db.charName] = nil
1890 end
1891 else
1892 if db.raw.chars then
1893 db.raw.chars[charID] = nil
1894 if not next(db.raw.chars) then
1895 db.raw.chars = nil
1896 end
1897 end
1898 end
1899 end
1900 if db.realm and cleanDefaults(db.realm, db.defaults and db.defaults.realm) then
1901 if db.raw.realms then
1902 db.raw.realms[realmID] = nil
1903 if not next(db.raw.realms) then
1904 db.raw.realms = nil
1905 end
1906 end
1907 end
1908 if db.server and cleanDefaults(db.server, db.defaults and db.defaults.server) then
1909 if db.raw.servers then
1910 db.raw.servers[server] = nil
1911 if not next(db.raw.servers) then
1912 db.raw.servers = nil
1913 end
1914 end
1915 end
1916 if db.faction and cleanDefaults(db.faction, db.defaults and db.defaults.faction) then
1917 if db.raw.factions then
1918 db.raw.factions[faction] = nil
1919 if not next(db.raw.factions) then
1920 db.raw.factions = nil
1921 end
1922 end
1923 end
1924 if db.class and cleanDefaults(db.class, db.defaults and db.defaults.class) then
1925 if db.raw.classes then
1926 db.raw.classes[classID] = nil
1927 if not next(db.raw.classes) then
1928 db.raw.classes = nil
1929 end
1930 end
1931 end
1932 if db.account and cleanDefaults(db.account, db.defaults and db.defaults.account) then
1933 db.raw.account = nil
1934 end
1935 if db.profile and cleanDefaults(db.profile, db.defaults and db.defaults.profile) then
1936 if db.raw.profiles then
1937 db.raw.profiles[db.raw.currentProfile and db.raw.currentProfile[charID] or defaultProfile or "Default"] = nil
1938 if not next(db.raw.profiles) then
1939 db.raw.profiles = nil
1940 end
1941 end
1942 end
1943 if db.namespaces and db.raw.namespaces then
1944 for name,v in pairs(db.namespaces) do
1945 if db.raw.namespaces[name] then
1946 setmetatable(v, nil)
1947 if v.char and cleanDefaults(v.char, v.defaults and v.defaults.char) then
1948 if db.charName and _G[db.charName] and _G[db.charName].namespaces and _G[db.charName].namespaces[name] == v then
1949 _G[db.charName].namespaces[name] = nil
1950 if not next(_G[db.charName].namespaces) then
1951 _G[db.charName].namespaces = nil
1952 if not next(_G[db.charName]) then
1953 _G[db.charName] = nil
1954 end
1955 end
1956 else
1957 if db.raw.namespaces[name].chars then
1958 db.raw.namespaces[name].chars[charID] = nil
1959 if not next(db.raw.namespaces[name].chars) then
1960 db.raw.namespaces[name].chars = nil
1961 end
1962 end
1963 end
1964 end
1965 if v.realm and cleanDefaults(v.realm, v.defaults and v.defaults.realm) then
1966 if db.raw.namespaces[name].realms then
1967 db.raw.namespaces[name].realms[realmID] = nil
1968 if not next(db.raw.namespaces[name].realms) then
1969 db.raw.namespaces[name].realms = nil
1970 end
1971 end
1972 end
1973 if v.server and cleanDefaults(v.server, v.defaults and v.defaults.server) then
1974 if db.raw.namespaces[name].servers then
1975 db.raw.namespaces[name].servers[server] = nil
1976 if not next(db.raw.namespaces[name].servers) then
1977 db.raw.namespaces[name].servers = nil
1978 end
1979 end
1980 end
1981 if v.faction and cleanDefaults(v.faction, v.defaults and v.defaults.faction) then
1982 if db.raw.namespaces[name].factions then
1983 db.raw.namespaces[name].factions[faction] = nil
1984 if not next(db.raw.namespaces[name].factions) then
1985 db.raw.namespaces[name].factions = nil
1986 end
1987 end
1988 end
1989 if v.class and cleanDefaults(v.class, v.defaults and v.defaults.class) then
1990 if db.raw.namespaces[name].classes then
1991 db.raw.namespaces[name].classes[classID] = nil
1992 if not next(db.raw.namespaces[name].classes) then
1993 db.raw.namespaces[name].classes = nil
1994 end
1995 end
1996 end
1997 if v.account and cleanDefaults(v.account, v.defaults and v.defaults.account) then
1998 db.raw.namespaces[name].account = nil
1999 end
2000 if v.profile and cleanDefaults(v.profile, v.defaults and v.defaults.profile) then
2001 if db.raw.namespaces[name].profiles then
2002 db.raw.namespaces[name].profiles[db.raw.currentProfile and db.raw.currentProfile[charID] or defaultProfile or "Default"] = nil
2003 if not next(db.raw.namespaces[name].profiles) then
2004 db.raw.namespaces[name].profiles = nil
2005 end
2006 end
2007 end
2008 if not next(db.raw.namespaces[name]) then
2009 db.raw.namespaces[name] = nil
2010 end
2011 end
2012 end
2013 if not next(db.raw.namespaces) then
2014 db.raw.namespaces = nil
2015 end
2016 end
2017 if db.raw.disabled and not next(db.raw.disabled) then
2018 db.raw.disabled = nil
2019 end
2020 if db.raw.currentProfile then
2021 for k,v in pairs(db.raw.currentProfile) do
2022 if v:lower() == (defaultProfile or "Default"):lower() then
2023 db.raw.currentProfile[k] = nil
2024 end
2025 end
2026 if not next(db.raw.currentProfile) then
2027 db.raw.currentProfile = nil
2028 end
2029 end
2030 if _G[db.name] and not next(_G[db.name]) then
2031 _G[db.name] = nil
2032 end
2033 end
2034 end
2035 end
2036
2037 function AceDB:AcquireDBNamespace(name)
2038 AceDB:argCheck(name, 2, "string")
2039 local db = self.db
2040 if not db then
2041 AceDB:error("Cannot call `AcquireDBNamespace' before `RegisterDB' has been called.", 2)
2042 end
2043 if not db.namespaces then
2044 rawset(db, 'namespaces', {})
2045 end
2046 if not db.namespaces[name] then
2047 local namespace = {}
2048 db.namespaces[name] = namespace
2049 namespace.db = db
2050 namespace.name = name
2051 setmetatable(namespace, namespace_mt)
2052 end
2053 return db.namespaces[name]
2054 end
2055
2056 function AceDB:GetAceOptionsDataTable(target)
2057 if not target['acedb-profile-list'] then
2058 target['acedb-profile-list'] = setmetatable({}, caseInsensitive_mt)
2059 RecalculateAceDBProfileList(target)
2060 end
2061 if not target['acedb-profile-copylist'] then
2062 target['acedb-profile-copylist'] = setmetatable({}, caseInsensitive_mt)
2063 RecalculateAceDBCopyFromList(target)
2064 end
2065 return {
2066 standby = {
2067 cmdName = STATE,
2068 guiName = ENABLED,
2069 name = ACTIVE,
2070 desc = TOGGLE_ACTIVE,
2071 type = "toggle",
2072 get = "IsActive",
2073 set = "ToggleActive",
2074 map = MAP_ACTIVESUSPENDED,
2075 order = -3,
2076 },
2077 profile = {
2078 type = 'group',
2079 name = PROFILE,
2080 desc = SET_PROFILE,
2081 order = -3.5,
2082 get = "GetProfile",
2083 args = {
2084 choose = {
2085 guiName = CHOOSE_PROFILE_GUI,
2086 cmdName = PROFILE,
2087 desc = CHOOSE_PROFILE_DESC,
2088 type = 'text',
2089 get = "GetProfile",
2090 set = "SetProfile",
2091 validate = target['acedb-profile-list']
2092 },
2093 copy = {
2094 guiName = COPY_PROFILE_GUI,
2095 cmdName = PROFILE,
2096 desc = COPY_PROFILE_DESC,
2097 type = 'text',
2098 get = false,
2099 set = "CopyProfileFrom",
2100 validate = target['acedb-profile-copylist'],
2101 disabled = function()
2102 return not next(target['acedb-profile-copylist'])
2103 end,
2104 },
2105 other = {
2106 guiName = OTHER_PROFILE_GUI,
2107 cmdName = PROFILE,
2108 desc = OTHER_PROFILE_DESC,
2109 usage = OTHER_PROFILE_USAGE,
2110 type = 'text',
2111 get = "GetProfile",
2112 set = "SetProfile",
2113 },
2114 delete = {
2115 name = DELETE_PROFILE,
2116 desc = DELETE_PROFILE_DESC,
2117 usage = DELETE_PROFILE_USAGE,
2118 type = 'text',
2119 set = "DeleteProfile",
2120 get = false,
2121 validate = target['acedb-profile-copylist'],
2122 disabled = function()
2123 return not next(target['acedb-profile-copylist'])
2124 end,
2125 },
2126 reset = {
2127 name = RESET_PROFILE,
2128 desc = RESET_PROFILE_DESC,
2129 type = 'execute',
2130 func = function()
2131 target:ResetDB('profile')
2132 end,
2133 confirm = true,
2134 }
2135 }
2136 },
2137 }
2138 end
2139
2140 local function activate(self, oldLib, oldDeactivate)
2141 AceDB = self
2142 AceEvent = AceLibrary:HasInstance("AceEvent-2.0") and AceLibrary("AceEvent-2.0")
2143
2144 self.addonsToBeInitialized = oldLib and oldLib.addonsToBeInitialized or {}
2145 self.addonsLoaded = oldLib and oldLib.addonsLoaded or {}
2146 self.registry = oldLib and oldLib.registry or {}
2147 for k, v in pairs(self.registry) do
2148 if v == true then
2149 self.registry[k] = "Default"
2150 end
2151 end
2152
2153 self:activate(oldLib, oldDeactivate)
2154
2155 for t in pairs(self.embedList) do
2156 if t.db then
2157 rawset(t.db, 'char', nil)
2158 rawset(t.db, 'realm', nil)
2159 rawset(t.db, 'class', nil)
2160 rawset(t.db, 'account', nil)
2161 rawset(t.db, 'server', nil)
2162 rawset(t.db, 'faction', nil)
2163 rawset(t.db, 'profile', nil)
2164 setmetatable(t.db, db_mt)
2165 end
2166 end
2167
2168 if oldLib then
2169 oldDeactivate(oldLib)
2170 end
2171 end
2172
2173 local function external(self, major, instance)
2174 if major == "AceEvent-2.0" then
2175 AceEvent = instance
2176
2177 AceEvent:embed(self)
2178
2179 self:RegisterEvent("ADDON_LOADED")
2180 self:RegisterEvent("PLAYER_LOGOUT")
2181 elseif major == "Dewdrop-2.0" then
2182 Dewdrop = instance
2183 end
2184 end
2185
2186 AceLibrary:Register(AceDB, MAJOR_VERSION, MINOR_VERSION, activate, nil, external)
2187 AceDB = AceLibrary(MAJOR_VERSION)