/trunk/FuBar_RecapFu/libs/AceDB-2.0
--[[ |
--[[ |
Name: AceDB-2.0 |
Revision: $Rev: 29174 $ |
Revision: $Rev: 1094 $ |
Developed by: The Ace Development Team (http://www.wowace.com/index.php/The_Ace_Development_Team) |
Inspired By: Ace 1.x by Turan (turan@gryphon.com) |
Website: http://www.wowace.com/ |
Documentation: http://www.wowace.com/index.php/AceDB-2.0 |
SVN: http://svn.wowace.com/root/trunk/Ace2/AceDB-2.0 |
SVN: http://svn.wowace.com/wowace/trunk/Ace2/AceDB-2.0 |
Description: Mixin to allow for fast, clean, and featureful saved variable |
access. |
Dependencies: AceLibrary, AceOO-2.0, AceEvent-2.0 |
]] |
local MAJOR_VERSION = "AceDB-2.0" |
local MINOR_VERSION = "$Revision: 29174 $" |
local MINOR_VERSION = 90000 + tonumber(("$Revision: 1094 $"):match("(%d+)")) |
if not AceLibrary then error(MAJOR_VERSION .. " requires AceLibrary") end |
if not AceLibrary:IsNewVersion(MAJOR_VERSION, MINOR_VERSION) then return end |
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 |
-- Move these into "enUS" when they've been translated in all other locales |
local DELETE_PROFILE = "Delete" |
local DELETE_PROFILE_DESC = "Deletes a profile. Note that no check is made whether this profile is in use by other characters or not." |
local DELETE_PROFILE_USAGE = "<profile name>" |
if GetLocale() == "deDE" then |
DELETE_PROFILE = "L\195\182schen" |
DELETE_PROFILE_DESC = "L\195\182scht ein Profil. Beachte das nicht \195\188berpr\195\188ft wird ob das zu l\195\182schende Profil von anderen Charakteren genutzt wird oder nicht." |
DELETE_PROFILE_USAGE = "<profil name>" |
ACTIVE = "Aktiv" |
ENABLED = "Aktiviert" |
STATE = "Status" |
OTHER_PROFILE_DESC = "W\195\164hle ein anderes Profil." |
OTHER_PROFILE_GUI = "Anderes" |
OTHER_PROFILE_USAGE = "<Profilname>" |
RESET_PROFILE = "Reset profile" -- fix |
RESET_PROFILE_DESC = "Clear all settings of the current profile." -- fix |
RESET_PROFILE = "Resette das Profil" |
RESET_PROFILE_DESC = "Entfernt alle Einstellungen des gegenw\195\164rtigen Profils." |
CHARACTER_COLON = "Charakter: " |
REALM_COLON = "Realm: " |
CLASS_COLON = "Klasse: " |
DEFAULT = "Default" -- fix |
ALTERNATIVE = "Alternative" -- fix |
DEFAULT = "Vorgabe" |
ALTERNATIVE = "Alternativ" |
elseif GetLocale() == "frFR" then |
ACTIVE = "Actif" |
ENABLED = "Activ\195\169" |
CHARACTER_COLON = "Personnage: " |
REALM_COLON = "Royaume: " |
CLASS_COLON = "Classe: " |
DEFAULT = "Default" -- fix |
ALTERNATIVE = "Alternative" -- fix |
elseif GetLocale() == "koKR" then |
ACTIVE = "íì±í" |
ENABLED = "íì±í" |
DELETE_PROFILE = "ìì " |
DELETE_PROFILE_DESC = "íë¡íì ìì í©ëë¤." |
DELETE_PROFILE_USAGE = "<íë¡íëª >" |
ACTIVE = "ì¬ì©" |
ENABLED = "ì¬ì©" |
STATE = "ìí" |
TOGGLE_ACTIVE = "ì´ ì ëì¨ ì¤ì§/ê³ì ì¤í" |
MAP_ACTIVESUSPENDED = { [true] = "|cff00ff00íì±í|r", [false] = "|cffff0000ì¤ì§ë¨|r" } |
TOGGLE_ACTIVE = "ì´ ì ëì¨ ì¤ì§/ë¤ì ìì" |
MAP_ACTIVESUSPENDED = { [true] = "|cff00ff00ì¬ì©|r", [false] = "|cffff0000ì¤ì§|r" } |
SET_PROFILE = "ì´ ì ëì¨ì íë¡í ì¤ì " |
SET_PROFILE_USAGE = "{ìºë¦í°ëª || ì§ì || ìë²ëª || <íë¡íëª >}" |
PROFILE = "íë¡í" |
PLAYER_OF_REALM = "%s (%s ìë²)" |
CHOOSE_PROFILE_DESC = "íë¡íì¼ì ì íí©ëë¤." |
CHOOSE_PROFILE_DESC = "íë¡íì ì íí©ëë¤." |
CHOOSE_PROFILE_GUI = "ì í" |
COPY_PROFILE_DESC = "ë¤ë¥¸ íë¡íì¼ìì ì¤ì ì ë³µì¬í©ëë¤." |
COPY_PROFILE_DESC = "ë¤ë¥¸ íë¡í ì¤ì ì ë³µì¬í©ëë¤." |
COPY_PROFILE_GUI = "ë³µì¬" |
OTHER_PROFILE_DESC = "ë¤ë¥¸ íë¡íì¼ì ì íí©ëë¤." |
OTHER_PROFILE_DESC = "ë¤ë¥¸ íë¡íì ì íí©ëë¤." |
OTHER_PROFILE_GUI = "기í" |
OTHER_PROFILE_USAGE = "<íë¡íì¼ëª >" |
RESET_PROFILE = "Reset profile" -- fix |
RESET_PROFILE_DESC = "Clear all settings of the current profile." -- fix |
OTHER_PROFILE_USAGE = "<íë¡íëª >" |
RESET_PROFILE = "íë¡í ì´ê¸°í" |
RESET_PROFILE_DESC = "모ë ì¸í ìì íì¬ íë¡íì ì´ê¸°í í©ëë¤." |
CHARACTER_COLON = "ìºë¦í°: " |
REALM_COLON = "ìë²: " |
CLASS_COLON = "ì§ì : " |
DEFAULT = "Default" -- fix |
ALTERNATIVE = "Alternative" -- fix |
DEFAULT = "기본ê°" |
ALTERNATIVE = "ëì²´" |
elseif GetLocale() == "zhTW" then |
DELETE_PROFILE = "åªé¤" |
DELETE_PROFILE_DESC = "åªé¤è¨éæªã注æï¼æå¯è½å¥çè§è²ä¹ä½¿ç¨éåè¨éæªã" |
DELETE_PROFILE_USAGE = "<è¨éæªå稱>" |
ACTIVE = "åå" |
ENABLED = "åç¨" |
STATE = "çæ " |
TOGGLE_ACTIVE = "æ«å/éåéåæ件ã" |
TOGGLE_ACTIVE = "æ«å/ç¹¼çºä½¿ç¨éåæ件ã" |
MAP_ACTIVESUSPENDED = { [true] = "|cff00ff00åå|r", [false] = "|cffff0000å·²æ«å|r" } |
SET_PROFILE = "è¨å®éæ件çè¨éæªã" |
SET_PROFILE_USAGE = "{è§è² || è¯æ¥ || 伺æå¨ || <è¨éæªå稱>}" |
SET_PROFILE_USAGE = "{è§è² || è·æ¥ || 伺æå¨ || <è¨éæªå稱>}" |
PROFILE = "è¨éæª" |
PLAYER_OF_REALM = "%s æ¼ %s" |
CHOOSE_PROFILE_DESC = "é¸æä¸åè¨éæª" |
PLAYER_OF_REALM = "%s - %s" |
CHOOSE_PROFILE_DESC = "é¸æä¸åè¨éæªã" |
CHOOSE_PROFILE_GUI = "é¸æ" |
COPY_PROFILE_DESC = "ç±å ¶ä»è¨éæªè¤è£½è¨å®ã" |
COPY_PROFILE_GUI = "è¤è£½ç±" |
COPY_PROFILE_GUI = "è¤è£½èª" |
OTHER_PROFILE_DESC = "é¸æå ¶ä»è¨éæªã" |
OTHER_PROFILE_GUI = "å ¶ä»" |
OTHER_PROFILE_USAGE = "<è¨éæªå稱>" |
RESET_PROFILE = "Reset profile" -- fix |
RESET_PROFILE_DESC = "Clear all settings of the current profile." -- fix |
RESET_PROFILE = "éè¨è¨éæª" |
RESET_PROFILE_DESC = "æ¸ é¤ç®åçè¨éæªä¸çææè¨å®ã" |
CHARACTER_COLON = "è§è²ï¼" |
REALM_COLON = "伺æå¨ï¼" |
CLASS_COLON = "è¯æ¥ï¼" |
DEFAULT = "Default" -- fix |
ALTERNATIVE = "Alternative" -- fix |
CHARACTER_COLON = "è§è²: " |
REALM_COLON = "伺æå¨: " |
CLASS_COLON = "è·æ¥: " |
DEFAULT = "é è¨" |
ALTERNATIVE = "æ¿ä»£" |
elseif GetLocale() == "zhCN" then |
ACTIVE = "\230\156\137\230\149\136" |
ENABLED = "\229\144\175\231\148\168" |
CHARACTER_COLON = "\229\173\151\231\172\166: " |
REALM_COLON = "\229\159\159: " |
CLASS_COLON = "\233\128\137\228\187\182\231\177\187: " |
DEFAULT = "Default" -- fix |
ALTERNATIVE = "Alternative" -- fix |
elseif GetLocale() == "esES" then |
CHARACTER_COLON = "Personaje: " |
REALM_COLON = "Reino: " |
CLASS_COLON = "Clase: " |
DEFAULT = "Por defecto" |
ALTERNATIVE = "Alternativo" |
elseif GetLocale() == "ruRU" then |
DELETE_PROFILE = "УдалиÑÑ" |
DELETE_PROFILE_DESC = "УдалиÑÑ Ð¿ÑоÑилÑ. ÐзнаÑалÑно пÑовеÑÑÑе не иÑполÑзÑеÑÑÑ Ð»Ð¸ ÑÑÐ¾Ñ Ð¿ÑоÑÐ¸Ð»Ñ Ð´ÑÑгими пеÑÑонажами, ÑÑÐ¾Ð±Ñ Ð½Ðµ наÑвоÑиÑÑ Ñебе неÑдобÑÑв." |
DELETE_PROFILE_USAGE = "<название пÑоÑилÑ>" |
ACTIVE = "ÐкÑивнÑй" |
ENABLED = "ÐклÑÑÑн" |
STATE = "СоÑÑоÑние" |
TOGGLE_ACTIVE = "ÐÑклÑÑиÑÑ/ÐапÑÑÑиÑÑ Ð°Ð´Ð´Ð¾Ð½." |
MAP_ACTIVESUSPENDED = { [true] = "|cff00ff00ÐкÑивнÑй|r", [false] = "|cffff0000Suspended|r" } |
SET_PROFILE = "УÑÑановиÑÑ Ð¿ÑоÑÐ¸Ð»Ñ Ð´Ð»Ñ ÑÑого аддона." |
SET_PROFILE_USAGE = "{ÑÐ°Ñ || клаÑÑ || ÑеÑÐ²ÐµÑ || <название пÑоÑилÑ>}" |
PROFILE = "ÐÑоÑилÑ" |
PLAYER_OF_REALM = "%s из %s" |
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 = "ÐлÑÑеÑнаÑива" |
else -- enUS |
ACTIVE = "Active" |
ENABLED = "Enabled" |
CHARACTER_COLON = "Character: " |
REALM_COLON = "Realm: " |
CLASS_COLON = "Class: " |
DEFAULT = "Default" |
ALTERNATIVE = "Alternative" |
end |
"SetProfile", |
"GetProfile", |
"CopyProfileFrom", |
"DeleteProfile", |
"ToggleActive", |
"IsActive", |
"AcquireDBNamespace", |
return t |
end |
for k,v in pairs(defaults) do |
if k == "*" then |
if k == "*" or k == "**" then |
local v = v |
if type(v) == "table" then |
setmetatable(t, { |
} ) |
end |
for key in pairs(t) do |
if (defaults[key] == nil or key == "*") and type(t[key]) == "table" then |
if (defaults[key] == nil or key == k) and type(t[key]) == "table" then |
inheritDefaults(t[key], v) |
end |
end |
else |
if type(v) == "table" then |
if type(t[k]) ~= "table" then |
if type(rawget(t, k)) ~= "table" then |
t[k] = {} |
end |
inheritDefaults(t[k], v) |
elseif t[k] == nil then |
if defaults["**"] then |
inheritDefaults(t[k], defaults["**"]) |
end |
elseif rawget(t, k) == nil then |
t[k] = v |
end |
end |
return {} |
end |
end |
function del(t) |
setmetatable(t, nil) |
for k in pairs(t) do |
local tmp = {} |
function AceDB:InitializeDB(addonName) |
local db = self.db |
if not db then |
if addonName then |
AceDB.addonsLoaded[addonName] = true |
end |
return |
end |
if db.raw then |
-- someone manually initialized |
return |
end |
if type(_G[db.name]) ~= "table" then |
_G[db.name] = {} |
else |
CrawlForDeserialization(_G[db.name]) |
end |
if type(_G[db.charName]) == "table" then |
CrawlForDeserialization(_G[db.charName]) |
if db.charName then |
if type(_G[db.charName]) ~= "table" then |
_G[db.charName] = {} |
else |
CrawlForDeserialization(_G[db.charName]) |
end |
end |
rawset(db, 'raw', _G[db.name]) |
if not db.raw.currentProfile then |
name, kind = kind, a2 |
AceDB:argCheck(name, 2, "nil", "string") |
AceDB:argCheck(kind, 3, "nil", "string") |
else |
else |
AceDB:argCheck(kind, 2, "nil", "string") |
if kind ~= "char" and kind ~= "class" and kind ~= "profile" and kind ~= "account" and kind ~= "realm" and kind ~= "faction" and kind ~= "server" then |
name, kind = kind, nil |
else |
if db.raw.namespaces then |
db.raw.namespaces[name] = nil |
end |
end |
if db.namespaces then |
local v = db.namespaces[name] |
if v then |
rawset(v, 'realm', nil) |
end |
end |
else |
else |
if db.raw.namespaces then |
local v = db.raw.namespaces[name] |
if v and v.realms then |
end |
end |
end |
elseif kind == "profile" then |
elseif kind == "profile" then |
local id = db.raw.currentProfile and db.raw.currentProfile[charID] or AceDB.registry[self] or "Default" |
if id == "char" then |
id = "char/" .. charID |
elseif id == "realm" then |
id = "realm/" .. realmID |
end |
local current = self.class |
while current and current ~= AceOO.Class do |
if current.mixins then |
safecall(self.OnProfileDisable, self, id) |
end |
local active = self:IsActive() |
if not name then |
if db.raw.profiles then |
db.raw.profiles[id] = nil |
end |
end |
end |
local current = self.class |
while current and current ~= AceOO.Class do |
if current.mixins then |
end |
local newactive = self:IsActive() |
if active ~= newactive then |
local first = nil |
if AceOO.inherits(self, "AceAddon-2.0") then |
local AceAddon = AceLibrary("AceAddon-2.0") |
if not AceAddon.addonsStarted[self] then |
return |
if newactive then |
local first = nil |
if AceOO.inherits(self, "AceAddon-2.0") then |
local AceAddon = AceLibrary("AceAddon-2.0") |
if not AceAddon.addonsStarted[self] then |
return |
end |
if AceAddon.addonsEnabled and not AceAddon.addonsEnabled[self] then |
AceAddon.addonsEnabled[self] = true |
first = true |
end |
end |
if AceAddon.addonsEnabled and not AceAddon.addonsEnabled[self] then |
first = true |
end |
end |
if newactive then |
local current = self.class |
while current and current ~= AceOO.Class do |
if current.mixins then |
end |
end |
end |
else |
return -- skip event |
end |
if AceEvent then |
AceEvent:TriggerEvent("AceDB20_ResetDB", self, self.db.name, kind) |
end |
end |
local function cleanDefaults(t, defaults) |
local function cleanDefaults(t, defaults, blocker) |
if defaults then |
for k,v in pairs(defaults) do |
if k == "*" then |
if type(v) == "table" then |
for k in pairs(t) do |
if (defaults[k] == nil or k == "*") and type(t[k]) == "table" then |
if cleanDefaults(t[k], v) then |
for k,v in pairs(t) do |
if (not blocker or (blocker[k] == nil and blocker['*'] == nil and blocker['**'] == nil)) and (defaults[k] ~= nil or defaults['*'] ~= nil or defaults['**'] ~= nil) then |
local u = defaults[k] |
if u == nil then |
u = defaults['*'] |
if u == nil then |
u = defaults['**'] |
end |
end |
if v == u then |
t[k] = nil |
elseif type(v) == "table" and type(u) == "table" then |
if cleanDefaults(v, u) then |
t[k] = nil |
else |
local w = defaults['**'] |
if w ~= u then |
if cleanDefaults(v, w, u) then |
t[k] = nil |
end |
end |
end |
else |
for k in pairs(t) do |
if (defaults[k] == nil or k == "*") and t[k] == v then |
t[k] = nil |
end |
end |
end |
else |
if type(v) == "table" then |
if type(t[k]) == "table" then |
if cleanDefaults(t[k], v) then |
t[k] = nil |
end |
end |
elseif t[k] == v then |
t[k] = nil |
end |
end |
end |
end |
return t and not next(t) |
return t and next(t) == nil |
end |
function AceDB:GetProfile() |
RecalculateAceDBCopyFromList(self) |
end |
if Dewdrop then |
Dewdrop:Refresh(1) |
Dewdrop:Refresh(2) |
Dewdrop:Refresh(3) |
Dewdrop:Refresh(4) |
Dewdrop:Refresh(5) |
Dewdrop:Refresh() |
end |
end |
RecalculateAceDBCopyFromList(self) |
end |
if Dewdrop then |
Dewdrop:Refresh(1) |
Dewdrop:Refresh(2) |
Dewdrop:Refresh(3) |
Dewdrop:Refresh(4) |
Dewdrop:Refresh(5) |
Dewdrop:Refresh() |
end |
end |
function AceDB:DeleteProfile(profile, noconfirm) |
AceDB:argCheck(profile , 2, "string") |
if not self.db or not self.db.raw then |
AceDB:error("Cannot call \"DeleteProfile\" before \"RegisterDB\" has been called and before \"ADDON_LOADED\" has been fired.") |
end |
local db = self.db |
local currentProfile = db.raw.currentProfile[charID] |
if currentProfile:lower() == profile:lower() then |
AceDB:error("Cannot delete profile %q, it is currently in use.", profile) |
end |
if not (noconfirm or IsShiftKeyDown()) then |
if not StaticPopupDialogs["ACEDB20_CONFIRM_DELETE_DIALOG"] then |
StaticPopupDialogs["ACEDB20_CONFIRM_DELETE_DIALOG"] = {} |
end |
local t = StaticPopupDialogs["ACEDB20_CONFIRM_DELETE_DIALOG"] |
t.text = format("%s: %s?", DELETE_PROFILE, profile) |
t.button1 = DELETE_PROFILE |
t.button2 = CANCEL or "Cancel" |
t.OnAccept = function() |
self:DeleteProfile(profile, true) |
end |
t.timeout = 0 |
t.whileDead = 1 |
t.hideOnEscape = 1 |
StaticPopup_Show("ACEDB20_CONFIRM_DELETE_DIALOG") |
return; |
end |
local good = false |
if db.raw.profiles and db.raw.profiles[profile] then |
good = true; |
db.raw.profiles[profile] = nil; |
end |
if db.raw.namespaces then |
for _,n in pairs(db.raw.namespaces) do |
if n.profiles and n.profiles[profile] then |
n.profiles[profile] = nil; |
good = true |
end |
end |
end |
if not good then |
AceDB:error("Cannot delete profile %q, it does not exist.", profile) |
end |
if self['acedb-profile-list'] then |
RecalculateAceDBProfileList(self) |
end |
if self['acedb-profile-copylist'] then |
RecalculateAceDBCopyFromList(self) |
end |
if Dewdrop then |
Dewdrop:Refresh() |
end |
end |
function AceDB:IsActive() |
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]] |
end |
for addon, defaultProfile in pairs(AceDB.registry) do |
local db = addon.db |
if db then |
if type(addon.OnDatabaseCleanup) == "function" then |
safecall(addon.OnDatabaseCleanup, addon) |
end |
setmetatable(db, nil) |
CrawlForSerialization(db.raw) |
if type(_G[db.charName]) == "table" then |
get = "GetProfile", |
set = "SetProfile", |
}, |
delete = { |
name = DELETE_PROFILE, |
desc = DELETE_PROFILE_DESC, |
usage = DELETE_PROFILE_USAGE, |
type = 'text', |
set = "DeleteProfile", |
get = false, |
validate = target['acedb-profile-copylist'], |
disabled = function() |
return not next(target['acedb-profile-copylist']) |
end, |
}, |
reset = { |
name = RESET_PROFILE, |
desc = RESET_PROFILE_DESC, |
local function activate(self, oldLib, oldDeactivate) |
AceDB = self |
AceEvent = AceLibrary:HasInstance("AceEvent-2.0") and AceLibrary("AceEvent-2.0") |
self.addonsToBeInitialized = oldLib and oldLib.addonsToBeInitialized or {} |
self.addonsLoaded = oldLib and oldLib.addonsLoaded or {} |
self.registry = oldLib and oldLib.registry or {} |
self.registry[k] = "Default" |
end |
end |
self:activate(oldLib, oldDeactivate) |
for t in pairs(self.embedList) do |
if t.db then |
rawset(t.db, 'char', nil) |
setmetatable(t.db, db_mt) |
end |
end |
if oldLib then |
oldDeactivate(oldLib) |
end |
local function external(self, major, instance) |
if major == "AceEvent-2.0" then |
AceEvent = instance |
AceEvent:embed(self) |
self:RegisterEvent("ADDON_LOADED") |
self:RegisterEvent("PLAYER_LOGOUT") |
elseif major == "Dewdrop-2.0" then |
## Interface: 30000 |
## X-Curse-Packaged-Version: r1096 |
## X-Curse-Project-Name: Ace2 |
## X-Curse-Project-ID: ace2 |
## X-Curse-Repository-ID: wow/ace2/mainline |
## Title: Lib: AceDB-2.0 |
## Notes: AddOn development framework |
## Author: Ace Development Team |
## LoadOnDemand: 1 |
## X-Website: http://www.wowace.com |
## X-Category: Library |
## X-License: LGPL v2.1 + MIT for AceOO-2.0 |
## Dependencies: AceLibrary, AceEvent-2.0, AceOO-2.0 |
AceDB-2.0.lua |