Mercurial > wow > reaction
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) |