Initial import of shootyepgp 2.0
80% rewrite of shootyepgp 1.x compatible with shootyepgp 1.x
This commit is contained in:
@@ -0,0 +1,982 @@
|
||||
--[[
|
||||
Name: AceAddon-2.0
|
||||
Revision: $Rev: 14832 $
|
||||
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/AceAddon-2.0
|
||||
SVN: http://svn.wowace.com/root/trunk/Ace2/AceAddon-2.0
|
||||
Description: Base for all Ace addons to inherit from.
|
||||
Dependencies: AceLibrary, AceOO-2.0, AceEvent-2.0, (optional) AceConsole-2.0
|
||||
]]
|
||||
|
||||
local MAJOR_VERSION = "AceAddon-2.0"
|
||||
local MINOR_VERSION = "$Revision: 14832 $"
|
||||
|
||||
-- This ensures the code is only executed if the libary doesn't already exist, or is a newer version
|
||||
if not AceLibrary then error(MAJOR_VERSION .. " requires AceLibrary.") end
|
||||
if not AceLibrary:IsNewVersion(MAJOR_VERSION, MINOR_VERSION) then return end
|
||||
|
||||
if not AceLibrary:HasInstance("AceOO-2.0") then error(MAJOR_VERSION .. " requires AceOO-2.0.") end
|
||||
|
||||
-- Localization
|
||||
local STANDBY, TITLE, NOTES, VERSION, AUTHOR, DATE, CATEGORY, EMAIL, WEBSITE, CATEGORIES, ABOUT, PRINT_ADDON_INFO
|
||||
if GetLocale() == "deDE" then
|
||||
STANDBY = "|cffff5050(Standby)|r" -- capitalized
|
||||
|
||||
TITLE = "Titel"
|
||||
NOTES = "Anmerkung"
|
||||
VERSION = "Version"
|
||||
AUTHOR = "Autor"
|
||||
DATE = "Datum"
|
||||
CATEGORY = "Kategorie"
|
||||
EMAIL = "E-mail"
|
||||
WEBSITE = "Webseite"
|
||||
|
||||
ABOUT = "\195\188ber"
|
||||
PRINT_ADDON_INFO = "Gibt Addondaten aus"
|
||||
|
||||
CATEGORIES = {
|
||||
["Action Bars"] = "Aktionsleisten",
|
||||
["Auction"] = "Auktion",
|
||||
["Audio"] = "Audio",
|
||||
["Battlegrounds/PvP"] = "Schlachtfeld/PvP",
|
||||
["Buffs"] = "Buffs",
|
||||
["Chat/Communication"] = "Chat/Kommunikation",
|
||||
["Druid"] = "Druide",
|
||||
["Hunter"] = "Jäger",
|
||||
["Mage"] = "Magier",
|
||||
["Paladin"] = "Paladin",
|
||||
["Priest"] = "Priester",
|
||||
["Rogue"] = "Schurke",
|
||||
["Shaman"] = "Schamane",
|
||||
["Warlock"] = "Hexenmeister",
|
||||
["Warrior"] = "Krieger",
|
||||
["Healer"] = "Heiler",
|
||||
["Tank"] = "Tank", -- noone use "Brecher"...
|
||||
["Caster"] = "Caster",
|
||||
["Combat"] = "Kampf",
|
||||
["Compilations"] = "Compilations", -- whats that o_O
|
||||
["Data Export"] = "Datenexport",
|
||||
["Development Tools"] = "Entwicklungs Tools",
|
||||
["Guild"] = "Gilde",
|
||||
["Frame Modification"] = "Frame Modifikation",
|
||||
["Interface Enhancements"] = "Interface Verbesserungen",
|
||||
["Inventory"] = "Inventar",
|
||||
["Library"] = "Library",
|
||||
["Map"] = "Map",
|
||||
["Mail"] = "Mail",
|
||||
["Miscellaneous"] = "Diverses",
|
||||
["Quest"] = "Quest",
|
||||
["Raid"] = "Schlachtzug",
|
||||
["Tradeskill"] = "Handelsf\195\164higkeit",
|
||||
["UnitFrame"] = "UnitFrame",
|
||||
}
|
||||
elseif GetLocale() == "frFR" then
|
||||
STANDBY = "|cffff5050(attente)|r"
|
||||
|
||||
TITLE = "Titre"
|
||||
NOTES = "Notes"
|
||||
VERSION = "Version"
|
||||
AUTHOR = "Auteur"
|
||||
DATE = "Date"
|
||||
CATEGORY = "Cat\195\169gorie"
|
||||
EMAIL = "E-mail"
|
||||
WEBSITE = "Site web"
|
||||
|
||||
ABOUT = "A propos"
|
||||
PRINT_ADDON_INFO = "Afficher les informations sur l'addon"
|
||||
|
||||
CATEGORIES = {
|
||||
["Action Bars"] = "Barres d'action",
|
||||
["Auction"] = "H\195\180tel des ventes",
|
||||
["Audio"] = "Audio",
|
||||
["Battlegrounds/PvP"] = "Champs de bataille/JcJ",
|
||||
["Buffs"] = "Buffs",
|
||||
["Chat/Communication"] = "Chat/Communication",
|
||||
["Druid"] = "Druide",
|
||||
["Hunter"] = "Chasseur",
|
||||
["Mage"] = "Mage",
|
||||
["Paladin"] = "Paladin",
|
||||
["Priest"] = "Pr\195\170tre",
|
||||
["Rogue"] = "Voleur",
|
||||
["Shaman"] = "Chaman",
|
||||
["Warlock"] = "D\195\169moniste",
|
||||
["Warrior"] = "Guerrier",
|
||||
["Healer"] = "Soigneur",
|
||||
["Tank"] = "Tank",
|
||||
["Caster"] = "Casteur",
|
||||
["Combat"] = "Combat",
|
||||
["Compilations"] = "Compilations",
|
||||
["Data Export"] = "Exportation de donn\195\169es",
|
||||
["Development Tools"] = "Outils de d\195\169veloppement",
|
||||
["Guild"] = "Guilde",
|
||||
["Frame Modification"] = "Modification des fen\195\170tres",
|
||||
["Interface Enhancements"] = "Am\195\169liorations de l'interface",
|
||||
["Inventory"] = "Inventaire",
|
||||
["Library"] = "Biblioth\195\168ques",
|
||||
["Map"] = "Carte",
|
||||
["Mail"] = "Courrier",
|
||||
["Miscellaneous"] = "Divers",
|
||||
["Quest"] = "Qu\195\170tes",
|
||||
["Raid"] = "Raid",
|
||||
["Tradeskill"] = "M\195\169tiers",
|
||||
["UnitFrame"] = "Fen\195\170tres d'unit\195\169",
|
||||
}
|
||||
elseif GetLocale() == "koKR" then
|
||||
STANDBY = "|cffff5050(사용가능)|r"
|
||||
|
||||
TITLE = "ì œëª©"
|
||||
NOTES = "노트"
|
||||
VERSION = "ë²„ì „"
|
||||
AUTHOR = "ì €ìž‘ìž�"
|
||||
DATE = "ë‚ ì§œ"
|
||||
CATEGORY = "분류"
|
||||
EMAIL = "E-mail"
|
||||
WEBSITE = "웹사�트"
|
||||
|
||||
ABOUT = "ì •ë³´"
|
||||
PRINT_ADDON_INFO = "ì• ë“œì˜¨ ì •ë³´ ì¶œë ¥"
|
||||
|
||||
CATEGORIES = {
|
||||
["Action Bars"] = "액션바",
|
||||
["Auction"] = "경매",
|
||||
["Audio"] = "�향",
|
||||
["Battlegrounds/PvP"] = "ì „ìž¥/PvP",
|
||||
["Buffs"] = "버프",
|
||||
["Chat/Communication"] = "대화/�사소통",
|
||||
["Druid"] = "드루�드",
|
||||
["Hunter"] = "사냥꾼",
|
||||
["Mage"] = "마법사",
|
||||
["Paladin"] = "성기사",
|
||||
["Priest"] = "ì‚¬ì œ",
|
||||
["Rogue"] = "ë�„ì �",
|
||||
["Shaman"] = "ì£¼ìˆ ì‚¬",
|
||||
["Warlock"] = "�마법사",
|
||||
["Warrior"] = "ì „ì‚¬",
|
||||
["Healer"] = "�러",
|
||||
["Tank"] = "탱커",
|
||||
["Caster"] = "�스터",
|
||||
["Combat"] = "ì „íˆ¬",
|
||||
["Compilations"] = "복합",
|
||||
["Data Export"] = "ìž�료 ì¶œë ¥",
|
||||
["Development Tools"] = "개발 �구",
|
||||
["Guild"] = "길드",
|
||||
["Frame Modification"] = "구조 변경",
|
||||
["Interface Enhancements"] = "�터페�스 강화",
|
||||
["Inventory"] = "ì�¸ë²¤í† 리",
|
||||
["Library"] = "��브러리",
|
||||
["Map"] = "지�",
|
||||
["Mail"] = "우편",
|
||||
["Miscellaneous"] = "기타",
|
||||
["Quest"] = "퀘스트",
|
||||
["Raid"] = "공격대",
|
||||
["Tradeskill"] = "ì „ë¬¸ê¸°ìˆ ",
|
||||
["UnitFrame"] = "ìœ ë‹› í”„ë ˆìž„",
|
||||
}
|
||||
elseif GetLocale() == "zhTW" then
|
||||
STANDBY = "|cffff5050(待命)|r"
|
||||
|
||||
TITLE = "標題"
|
||||
NOTES = "註記"
|
||||
VERSION = "版本"
|
||||
AUTHOR = "作者"
|
||||
DATE = "日期"
|
||||
CATEGORY = "類別"
|
||||
EMAIL = "E-mail"
|
||||
WEBSITE = "網站"
|
||||
|
||||
ABOUT = "關於"
|
||||
PRINT_ADDON_INFO = "顯示�件資訊"
|
||||
|
||||
CATEGORIES = {
|
||||
["Action Bars"] = "動作列",
|
||||
["Auction"] = "�賣",
|
||||
["Audio"] = "音樂",
|
||||
["Battlegrounds/PvP"] = "æˆ°å ´/PvP",
|
||||
["Buffs"] = "增益",
|
||||
["Chat/Communication"] = "�天/通訊",
|
||||
["Druid"] = "å¾·é¯ä¼Š",
|
||||
["Hunter"] = "�人",
|
||||
["Mage"] = "法師",
|
||||
["Paladin"] = "�騎士",
|
||||
["Priest"] = "牧師",
|
||||
["Rogue"] = "盜賊",
|
||||
["Shaman"] = "薩滿",
|
||||
["Warlock"] = "術士",
|
||||
["Warrior"] = "戰士",
|
||||
["Healer"] = "治療者",
|
||||
["Tank"] = "�克",
|
||||
["Caster"] = "施法者",
|
||||
["Combat"] = "戰鬥",
|
||||
["Compilations"] = "編輯",
|
||||
["Data Export"] = "資料匯出",
|
||||
["Development Tools"] = "開發工具",
|
||||
["Guild"] = "公會",
|
||||
["Frame Modification"] = "框架修改",
|
||||
["Interface Enhancements"] = "介�增強",
|
||||
["Inventory"] = "背包",
|
||||
["Library"] = "資料庫",
|
||||
["Map"] = "地圖",
|
||||
["Mail"] = "郵件",
|
||||
["Miscellaneous"] = "綜�",
|
||||
["Quest"] = "任務",
|
||||
["Raid"] = "團隊",
|
||||
["Tradeskill"] = "å•†æ¥æŠ€èƒ½",
|
||||
["UnitFrame"] = "單�框架",
|
||||
}
|
||||
elseif GetLocale() == "zhCN" then
|
||||
STANDBY = "|cffff5050(\230\154\130\230\140\130)|r"
|
||||
|
||||
TITLE = "\230\160\135\233\162\152"
|
||||
NOTES = "\233\153\132\230\179\168"
|
||||
VERSION = "\231\137\136\230\156\172"
|
||||
AUTHOR = "\228\189\156\232\128\133"
|
||||
DATE = "\230\151\165\230\156\159"
|
||||
CATEGORY = "\229\136\134\231\177\187"
|
||||
EMAIL = "\231\148\181\229\173\144\233\130\174\228\187\182"
|
||||
WEBSITE = "\231\189\145\231\171\153"
|
||||
|
||||
ABOUT = "\229\133\179\228\186\142"
|
||||
PRINT_ADDON_INFO = "\229\141\176\229\136\151\229\135\186\230\143\146\228\187\182\228\191\161\230\129\175"
|
||||
|
||||
CATEGORIES = {
|
||||
["Action Bars"] = "\229\138\168\228\189\156\230\157\161",
|
||||
["Auction"] = "\230\139\141\229\141\150",
|
||||
["Audio"] = "\233\159\179\233\162\145",
|
||||
["Battlegrounds/PvP"] = "\230\136\152\229\156\186/PvP",
|
||||
["Buffs"] = "\229\162\158\231\155\138\233\173\148\230\179\149",
|
||||
["Chat/Communication"] = "\232\129\138\229\164\169/\228\186\164\230\181\129",
|
||||
["Druid"] = "\229\190\183\233\178\129\228\188\138",
|
||||
["Hunter"] = "\231\140\142\228\186\186",
|
||||
["Mage"] = "\230\179\149\229\184\136",
|
||||
["Paladin"] = "\229\156\163\233\170\145\229\163\171",
|
||||
["Priest"] = "\231\137\167\229\184\136",
|
||||
["Rogue"] = "\231\155\151\232\180\188",
|
||||
["Shaman"] = "\232\144\168\230\187\161\231\165\173\229\143\184",
|
||||
["Warlock"] = "\230\156\175\229\163\171",
|
||||
["Warrior"] = "\230\136\152\229\163\171",
|
||||
-- ["Healer"] = "\230\178\187\231\150\151\228\191\157\233\154\156",
|
||||
-- ["Tank"] = "\232\191\145\230\136\152\230\142\167\229\136\182",
|
||||
-- ["Caster"] = "\232\191\156\231\168\139\232\190\147\229\135\186",
|
||||
["Combat"] = "\230\136\152\230\150\151",
|
||||
["Compilations"] = "\231\188\150\232\175\145",
|
||||
["Data Export"] = "\230\149\176\230\141\174\229\175\188\229\135\186",
|
||||
["Development Tools"] = "\229\188\128\229\143\145\229\183\165\229\133\183",
|
||||
["Guild"] = "\229\133\172\228\188\154",
|
||||
["Frame Modification"] = "\230\161\134\230\158\182\228\191\174\230\148\185",
|
||||
["Interface Enhancements"] = "\231\149\140\233\157\162\229\162\158\229\188\186",
|
||||
["Inventory"] = "\232\131\140\229\140\133",
|
||||
["Library"] = "\229\186\147",
|
||||
["Map"] = "\229\156\176\229\155\190",
|
||||
["Mail"] = "\233\130\174\228\187\182",
|
||||
["Miscellaneous"] = "\230\157\130\233\161\185",
|
||||
["Quest"] = "\228\187\187\229\138\161",
|
||||
["Raid"] = "\229\155\162\233\152\159",
|
||||
["Tradeskill"] = "\229\149\134\228\184\154\230\138\128\232\131\189",
|
||||
["UnitFrame"] = "\229\164\180\229\131\143\230\161\134\230\158\182",
|
||||
}
|
||||
else -- enUS
|
||||
STANDBY = "|cffff5050(standby)|r"
|
||||
|
||||
TITLE = "Title"
|
||||
NOTES = "Notes"
|
||||
VERSION = "Version"
|
||||
AUTHOR = "Author"
|
||||
DATE = "Date"
|
||||
CATEGORY = "Category"
|
||||
EMAIL = "E-mail"
|
||||
WEBSITE = "Website"
|
||||
|
||||
ABOUT = "About"
|
||||
PRINT_ADDON_INFO = "Print out addon info"
|
||||
|
||||
CATEGORIES = {
|
||||
["Action Bars"] = "Action Bars",
|
||||
["Auction"] = "Auction",
|
||||
["Audio"] = "Audio",
|
||||
["Battlegrounds/PvP"] = "Battlegrounds/PvP",
|
||||
["Buffs"] = "Buffs",
|
||||
["Chat/Communication"] = "Chat/Communication",
|
||||
["Druid"] = "Druid",
|
||||
["Hunter"] = "Hunter",
|
||||
["Mage"] = "Mage",
|
||||
["Paladin"] = "Paladin",
|
||||
["Priest"] = "Priest",
|
||||
["Rogue"] = "Rogue",
|
||||
["Shaman"] = "Shaman",
|
||||
["Warlock"] = "Warlock",
|
||||
["Warrior"] = "Warrior",
|
||||
["Healer"] = "Healer",
|
||||
["Tank"] = "Tank",
|
||||
["Caster"] = "Caster",
|
||||
["Combat"] = "Combat",
|
||||
["Compilations"] = "Compilations",
|
||||
["Data Export"] = "Data Export",
|
||||
["Development Tools"] = "Development Tools",
|
||||
["Guild"] = "Guild",
|
||||
["Frame Modification"] = "Frame Modification",
|
||||
["Interface Enhancements"] = "Interface Enhancements",
|
||||
["Inventory"] = "Inventory",
|
||||
["Library"] = "Library",
|
||||
["Map"] = "Map",
|
||||
["Mail"] = "Mail",
|
||||
["Miscellaneous"] = "Miscellaneous",
|
||||
["Quest"] = "Quest",
|
||||
["Raid"] = "Raid",
|
||||
["Tradeskill"] = "Tradeskill",
|
||||
["UnitFrame"] = "UnitFrame",
|
||||
}
|
||||
end
|
||||
|
||||
setmetatable(CATEGORIES, { __index = function(self, key) -- case-insensitive
|
||||
local lowerKey = string.lower(key)
|
||||
for k,v in CATEGORIES do
|
||||
if string.lower(k) == lowerKey then
|
||||
return v
|
||||
end
|
||||
end
|
||||
end })
|
||||
|
||||
-- Create the library object
|
||||
|
||||
local AceOO = AceLibrary("AceOO-2.0")
|
||||
local AceAddon = AceOO.Class()
|
||||
local AceEvent
|
||||
local AceConsole
|
||||
local AceModuleCore
|
||||
|
||||
function AceAddon:ToString()
|
||||
return "AceAddon"
|
||||
end
|
||||
|
||||
local function print(text)
|
||||
DEFAULT_CHAT_FRAME:AddMessage(text)
|
||||
end
|
||||
|
||||
function AceAddon:ADDON_LOADED(name)
|
||||
while table.getn(self.nextAddon) > 0 do
|
||||
local addon = table.remove(self.nextAddon, 1)
|
||||
table.insert(self.addons, addon)
|
||||
if not self.addons[name] then
|
||||
self.addons[name] = addon
|
||||
end
|
||||
self:InitializeAddon(addon, name)
|
||||
end
|
||||
end
|
||||
|
||||
local function RegisterOnEnable(self)
|
||||
if DEFAULT_CHAT_FRAME and DEFAULT_CHAT_FRAME.defaultLanguage then -- HACK
|
||||
AceAddon.playerLoginFired = true
|
||||
end
|
||||
if AceAddon.playerLoginFired then
|
||||
AceAddon.addonsStarted[self] = true
|
||||
if (type(self.IsActive) ~= "function" or self:IsActive()) and (not AceModuleCore or not AceModuleCore:IsModule(self) or AceModuleCore:IsModuleActive(self)) then
|
||||
local current = self.class
|
||||
while true do
|
||||
if current == AceOO.Class then
|
||||
break
|
||||
end
|
||||
if current.mixins then
|
||||
for mixin in pairs(current.mixins) do
|
||||
if type(mixin.OnEmbedEnable) == "function" then
|
||||
mixin:OnEmbedEnable(self)
|
||||
end
|
||||
end
|
||||
end
|
||||
current = current.super
|
||||
end
|
||||
if type(self.OnEnable) == "function" then
|
||||
self:OnEnable()
|
||||
end
|
||||
end
|
||||
else
|
||||
if not AceAddon.addonsToOnEnable then
|
||||
AceAddon.addonsToOnEnable = {}
|
||||
end
|
||||
table.insert(AceAddon.addonsToOnEnable, self)
|
||||
end
|
||||
end
|
||||
|
||||
local function stripSpaces(text)
|
||||
if type(text) == "string" then
|
||||
return (string.gsub(string.gsub(text, "^%s*(.-)%s*$", "%1"), "%s%s+", " "))
|
||||
end
|
||||
return text
|
||||
end
|
||||
|
||||
function AceAddon:InitializeAddon(addon, name)
|
||||
if addon.name == nil then
|
||||
addon.name = name
|
||||
end
|
||||
if GetAddOnMetadata then
|
||||
-- TOC checks
|
||||
if addon.title == nil then
|
||||
addon.title = GetAddOnMetadata(name, "Title")
|
||||
if addon.title then
|
||||
local num = string.find(addon.title, " |cff7fff7f %-Ace2%-|r$")
|
||||
if num then
|
||||
addon.title = string.sub(addon.title, 1, num - 1)
|
||||
end
|
||||
addon.title = stripSpaces(addon.title)
|
||||
end
|
||||
end
|
||||
if addon.notes == nil then
|
||||
addon.notes = GetAddOnMetadata(name, "Notes")
|
||||
addon.notes = stripSpaces(addon.notes)
|
||||
end
|
||||
if addon.version == nil then
|
||||
addon.version = GetAddOnMetadata(name, "Version")
|
||||
if addon.version then
|
||||
if string.find(addon.version, "%$Revision: (%d+) %$") then
|
||||
addon.version = string.gsub(addon.version, "%$Revision: (%d+) %$", "%1")
|
||||
elseif string.find(addon.version, "%$Rev: (%d+) %$") then
|
||||
addon.version = string.gsub(addon.version, "%$Rev: (%d+) %$", "%1")
|
||||
elseif string.find(addon.version, "%$LastChangedRevision: (%d+) %$") then
|
||||
addon.version = string.gsub(addon.version, "%$LastChangedRevision: (%d+) %$", "%1")
|
||||
end
|
||||
end
|
||||
addon.version = stripSpaces(addon.version)
|
||||
end
|
||||
if addon.author == nil then
|
||||
addon.author = GetAddOnMetadata(name, "Author")
|
||||
addon.author = stripSpaces(addon.author)
|
||||
end
|
||||
if addon.date == nil then
|
||||
addon.date = GetAddOnMetadata(name, "X-Date") or GetAddOnMetadata(name, "X-ReleaseDate")
|
||||
if addon.date then
|
||||
if string.find(addon.date, "%$Date: (.-) %$") then
|
||||
addon.date = string.gsub(addon.date, "%$Date: (.-) %$", "%1")
|
||||
elseif string.find(addon.date, "%$LastChangedDate: (.-) %$") then
|
||||
addon.date = string.gsub(addon.date, "%$LastChangedDate: (.-) %$", "%1")
|
||||
end
|
||||
end
|
||||
addon.date = stripSpaces(addon.date)
|
||||
end
|
||||
if addon.category == nil then
|
||||
addon.category = GetAddOnMetadata(name, "X-Category")
|
||||
addon.category = stripSpaces(addon.category)
|
||||
end
|
||||
if addon.email == nil then
|
||||
addon.email = GetAddOnMetadata(name, "X-eMail") or GetAddOnMetadata(name, "X-Email")
|
||||
addon.email = stripSpaces(addon.email)
|
||||
end
|
||||
if addon.website == nil then
|
||||
addon.website = GetAddOnMetadata(name, "X-Website")
|
||||
addon.website = stripSpaces(addon.website)
|
||||
end
|
||||
end
|
||||
local current = addon.class
|
||||
while true do
|
||||
if current == AceOO.Class then
|
||||
break
|
||||
end
|
||||
if current.mixins then
|
||||
for mixin in pairs(current.mixins) do
|
||||
if type(mixin.OnEmbedInitialize) == "function" then
|
||||
mixin:OnEmbedInitialize(addon, name)
|
||||
end
|
||||
end
|
||||
end
|
||||
current = current.super
|
||||
end
|
||||
if type(addon.OnInitialize) == "function" then
|
||||
addon:OnInitialize(name)
|
||||
end
|
||||
RegisterOnEnable(addon)
|
||||
end
|
||||
|
||||
function AceAddon.prototype:PrintAddonInfo()
|
||||
local x
|
||||
if self.title then
|
||||
x = "|cffffff7f" .. tostring(self.title) .. "|r"
|
||||
elseif self.name then
|
||||
x = "|cffffff7f" .. tostring(self.name) .. "|r"
|
||||
else
|
||||
x = "|cffffff7f<" .. tostring(self.class) .. " instance>|r"
|
||||
end
|
||||
if type(self.IsActive) == "function" then
|
||||
if not self:IsActive() then
|
||||
x = x .. " " .. STANDBY
|
||||
end
|
||||
end
|
||||
if self.version then
|
||||
x = x .. " - |cffffff7f" .. tostring(self.version) .. "|r"
|
||||
end
|
||||
if self.notes then
|
||||
x = x .. " - " .. tostring(self.notes)
|
||||
end
|
||||
print(x)
|
||||
if self.author then
|
||||
print(" - |cffffff7f" .. AUTHOR .. ":|r " .. tostring(self.author))
|
||||
end
|
||||
if self.date then
|
||||
print(" - |cffffff7f" .. DATE .. ":|r " .. tostring(self.date))
|
||||
end
|
||||
if self.category then
|
||||
local category = CATEGORIES[self.category]
|
||||
if category then
|
||||
print(" - |cffffff7f" .. CATEGORY .. ":|r " .. category)
|
||||
end
|
||||
end
|
||||
if self.email then
|
||||
print(" - |cffffff7f" .. EMAIL .. ":|r " .. tostring(self.email))
|
||||
end
|
||||
if self.website then
|
||||
print(" - |cffffff7f" .. WEBSITE .. ":|r " .. tostring(self.website))
|
||||
end
|
||||
end
|
||||
|
||||
local options
|
||||
function AceAddon:GetAceOptionsDataTable(target)
|
||||
if not options then
|
||||
options = {
|
||||
about = {
|
||||
name = ABOUT,
|
||||
desc = PRINT_ADDON_INFO,
|
||||
type = "execute",
|
||||
func = "PrintAddonInfo",
|
||||
order = -1,
|
||||
}
|
||||
}
|
||||
end
|
||||
return options
|
||||
end
|
||||
|
||||
function AceAddon:PLAYER_LOGIN()
|
||||
self.playerLoginFired = true
|
||||
if self.addonsToOnEnable then
|
||||
while table.getn(self.addonsToOnEnable) > 0 do
|
||||
local addon = table.remove(self.addonsToOnEnable, 1)
|
||||
self.addonsStarted[addon] = true
|
||||
if (type(addon.IsActive) ~= "function" or addon:IsActive()) and (not AceModuleCore or not AceModuleCore:IsModule(addon) or AceModuleCore:IsModuleActive(addon)) then
|
||||
local current = addon.class
|
||||
while true do
|
||||
if current == AceOO.Class then
|
||||
break
|
||||
end
|
||||
if current.mixins then
|
||||
for mixin in pairs(current.mixins) do
|
||||
if type(mixin.OnEmbedEnable) == "function" then
|
||||
mixin:OnEmbedEnable(addon)
|
||||
end
|
||||
end
|
||||
end
|
||||
current = current.super
|
||||
end
|
||||
if type(addon.OnEnable) == "function" then
|
||||
addon:OnEnable()
|
||||
end
|
||||
end
|
||||
end
|
||||
self.addonsToOnEnable = nil
|
||||
end
|
||||
end
|
||||
|
||||
function AceAddon.prototype:Inject(t)
|
||||
AceAddon:argCheck(t, 2, "table")
|
||||
for k,v in pairs(t) do
|
||||
self[k] = v
|
||||
end
|
||||
end
|
||||
|
||||
function AceAddon.prototype:init()
|
||||
if not AceEvent then
|
||||
error(MAJOR_VERSION .. " requires AceEvent-2.0", 4)
|
||||
end
|
||||
AceAddon.super.prototype.init(self)
|
||||
|
||||
self.super = self.class.prototype
|
||||
|
||||
AceAddon:RegisterEvent("ADDON_LOADED", "ADDON_LOADED", true)
|
||||
table.insert(AceAddon.nextAddon, self)
|
||||
end
|
||||
|
||||
function AceAddon.prototype:ToString()
|
||||
local x
|
||||
if type(self.title) == "string" then
|
||||
x = self.title
|
||||
elseif type(self.name) == "string" then
|
||||
x = self.name
|
||||
else
|
||||
x = "<" .. tostring(self.class) .. " instance>"
|
||||
end
|
||||
if (type(self.IsActive) == "function" and not self:IsActive()) or (AceModuleCore and AceModuleCore:IsModule(addon) and AceModuleCore:IsModuleActive(addon)) then
|
||||
x = x .. " " .. STANDBY
|
||||
end
|
||||
return x
|
||||
end
|
||||
|
||||
AceAddon.new = function(self, m1, m2, m3, m4, m5, m6, m7, m8, m9, m10, m11, m12, m13, m14, m15, m16, m17, m18, m19, m20)
|
||||
local class = AceAddon:pcall(AceOO.Classpool, self, m1, m2, m3, m4, m5, m6, m7, m8, m9, m10, m11, m12, m13, m14, m15, m16, m17, m18, m19, m20)
|
||||
return class:new()
|
||||
end
|
||||
|
||||
local function external(self, major, instance)
|
||||
if major == "AceEvent-2.0" then
|
||||
AceEvent = instance
|
||||
|
||||
AceEvent:embed(self)
|
||||
|
||||
self:RegisterEvent("PLAYER_LOGIN", "PLAYER_LOGIN", true)
|
||||
elseif major == "AceConsole-2.0" then
|
||||
AceConsole = instance
|
||||
|
||||
local slashCommands = { "/ace2" }
|
||||
local _,_,_,enabled,loadable = GetAddOnInfo("Ace")
|
||||
if not enabled or not loadable then
|
||||
table.insert(slashCommands, "/ace")
|
||||
end
|
||||
local function listAddon(addon, depth)
|
||||
if not depth then
|
||||
depth = 0
|
||||
end
|
||||
|
||||
local s = string.rep(" ", depth) .. " - " .. tostring(addon)
|
||||
if rawget(addon, 'version') then
|
||||
s = s .. " - |cffffff7f" .. tostring(addon.version) .. "|r"
|
||||
end
|
||||
if rawget(addon, 'slashCommand') then
|
||||
s = s .. " |cffffff7f(" .. tostring(addon.slashCommand) .. ")|r"
|
||||
end
|
||||
print(s)
|
||||
if type(rawget(addon, 'modules')) == "table" then
|
||||
local i = 0
|
||||
for k,v in pairs(addon.modules) do
|
||||
i = i + 1
|
||||
if i == 6 then
|
||||
print(string.rep(" ", depth + 1) .. " - more...")
|
||||
break
|
||||
else
|
||||
listAddon(v, depth + 1)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
local function listNormalAddon(i)
|
||||
local name,_,_,enabled,loadable = GetAddOnInfo(i)
|
||||
if not loadable then
|
||||
enabled = false
|
||||
end
|
||||
if self.addons[name] then
|
||||
local addon = self.addons[name]
|
||||
if not AceCoreAddon or not AceCoreAddon:IsModule(addon) then
|
||||
listAddon(addon)
|
||||
end
|
||||
else
|
||||
local s = " - " .. tostring(GetAddOnMetadata(i, "Title") or name)
|
||||
local version = GetAddOnMetadata(i, "Version")
|
||||
if version then
|
||||
if string.find(version, "%$Revision: (%d+) %$") then
|
||||
version = string.gsub(version, "%$Revision: (%d+) %$", "%1")
|
||||
elseif string.find(version, "%$Rev: (%d+) %$") then
|
||||
version = string.gsub(version, "%$Rev: (%d+) %$", "%1")
|
||||
elseif string.find(version, "%$LastChangedRevision: (%d+) %$") then
|
||||
version = string.gsub(version, "%$LastChangedRevision: (%d+) %$", "%1")
|
||||
end
|
||||
s = s .. " - |cffffff7f" .. version .. "|r"
|
||||
end
|
||||
if not enabled then
|
||||
s = s .. " |cffff0000(disabled)|r"
|
||||
end
|
||||
if IsAddOnLoadOnDemand(i) then
|
||||
s = s .. " |cff00ff00[LoD]|r"
|
||||
end
|
||||
print(s)
|
||||
end
|
||||
end
|
||||
local function mySort(alpha, bravo)
|
||||
return tostring(alpha) < tostring(bravo)
|
||||
end
|
||||
AceConsole.RegisterChatCommand(self, slashCommands, {
|
||||
desc = "AddOn development framework",
|
||||
name = "Ace2",
|
||||
type = "group",
|
||||
args = {
|
||||
about = {
|
||||
desc = "Get information about Ace2",
|
||||
name = "About",
|
||||
type = "execute",
|
||||
func = function()
|
||||
print("|cffffff7fAce2|r - |cffffff7f2.0." .. string.gsub(MINOR_VERSION, "%$Revision: (%d+) %$", "%1") .. "|r - AddOn development framework")
|
||||
print(" - |cffffff7f" .. AUTHOR .. ":|r Ace Development Team")
|
||||
print(" - |cffffff7f" .. WEBSITE .. ":|r http://www.wowace.com/")
|
||||
end
|
||||
},
|
||||
list = {
|
||||
desc = "List addons",
|
||||
name = "List",
|
||||
type = "group",
|
||||
args = {
|
||||
ace2 = {
|
||||
desc = "List addons using Ace2",
|
||||
name = "Ace2",
|
||||
type = "execute",
|
||||
func = function()
|
||||
print("|cffffff7fAddon list:|r")
|
||||
local AceCoreAddon = AceLibrary:HasInstance("AceCoreAddon-2.0") and AceLibrary("AceCoreAddon-2.0")
|
||||
table.sort(self.addons, mySort)
|
||||
for _,v in ipairs(self.addons) do
|
||||
if not AceCoreAddon or not AceCoreAddon:IsModule(v) then
|
||||
listAddon(v)
|
||||
end
|
||||
end
|
||||
end
|
||||
},
|
||||
all = {
|
||||
desc = "List all addons",
|
||||
name = "All",
|
||||
type = "execute",
|
||||
func = function()
|
||||
print("|cffffff7fAddon list:|r")
|
||||
local AceCoreAddon = AceLibrary:HasInstance("AceCoreAddon-2.0") and AceLibrary("AceCoreAddon-2.0")
|
||||
local count = GetNumAddOns()
|
||||
for i = 1, count do
|
||||
listNormalAddon(i)
|
||||
end
|
||||
end
|
||||
},
|
||||
enabled = {
|
||||
desc = "List all enabled addons",
|
||||
name = "Enabled",
|
||||
type = "execute",
|
||||
func = function()
|
||||
print("|cffffff7fAddon list:|r")
|
||||
local AceCoreAddon = AceLibrary:HasInstance("AceCoreAddon-2.0") and AceLibrary("AceCoreAddon-2.0")
|
||||
local count = GetNumAddOns()
|
||||
for i = 1, count do
|
||||
local _,_,_,enabled,loadable = GetAddOnInfo(i)
|
||||
if enabled and loadable then
|
||||
listNormalAddon(i)
|
||||
end
|
||||
end
|
||||
end
|
||||
},
|
||||
disabled = {
|
||||
desc = "List all disabled addons",
|
||||
name = "Disabled",
|
||||
type = "execute",
|
||||
func = function()
|
||||
print("|cffffff7fAddon list:|r")
|
||||
local AceCoreAddon = AceLibrary:HasInstance("AceCoreAddon-2.0") and AceLibrary("AceCoreAddon-2.0")
|
||||
local count = GetNumAddOns()
|
||||
for i = 1, count do
|
||||
local _,_,_,enabled,loadable = GetAddOnInfo(i)
|
||||
if not enabled or not loadable then
|
||||
listNormalAddon(i)
|
||||
end
|
||||
end
|
||||
end
|
||||
},
|
||||
lod = {
|
||||
desc = "List all LoadOnDemand addons",
|
||||
name = "LoadOnDemand",
|
||||
type = "execute",
|
||||
func = function()
|
||||
print("|cffffff7fAddon list:|r")
|
||||
local AceCoreAddon = AceLibrary:HasInstance("AceCoreAddon-2.0") and AceLibrary("AceCoreAddon-2.0")
|
||||
local count = GetNumAddOns()
|
||||
for i = 1, count do
|
||||
if IsAddOnLoadOnDemand(i) then
|
||||
listNormalAddon(i)
|
||||
end
|
||||
end
|
||||
end
|
||||
},
|
||||
ace1 = {
|
||||
desc = "List all addons using Ace1",
|
||||
name = "Ace 1.x",
|
||||
type = "execute",
|
||||
func = function()
|
||||
print("|cffffff7fAddon list:|r")
|
||||
local count = GetNumAddOns()
|
||||
for i = 1, count do
|
||||
local dep1, dep2, dep3, dep4 = GetAddOnDependencies(i)
|
||||
if dep1 == "Ace" or dep2 == "Ace" or dep3 == "Ace" or dep4 == "Ace" then
|
||||
listNormalAddon(i)
|
||||
end
|
||||
end
|
||||
end
|
||||
},
|
||||
libs = {
|
||||
desc = "List all libraries using AceLibrary",
|
||||
name = "Libraries",
|
||||
type = "execute",
|
||||
func = function()
|
||||
if type(AceLibrary) == "table" and type(AceLibrary.libs) == "table" then
|
||||
print("|cffffff7fLibrary list:|r")
|
||||
for name, data in pairs(AceLibrary.libs) do
|
||||
local s
|
||||
if data.minor then
|
||||
s = " - " .. tostring(name) .. "." .. tostring(data.minor)
|
||||
else
|
||||
s = " - " .. tostring(name)
|
||||
end
|
||||
if AceLibrary(name).slashCommand then
|
||||
s = s .. " |cffffff7f(" .. tostring(AceLibrary(name).slashCommand) .. "|cffffff7f)"
|
||||
end
|
||||
print(s)
|
||||
end
|
||||
end
|
||||
end
|
||||
},
|
||||
search = {
|
||||
desc = "Search by name",
|
||||
name = "Search",
|
||||
type = "text",
|
||||
usage = "<keyword>",
|
||||
input = true,
|
||||
get = false,
|
||||
set = function(...)
|
||||
for i,v in ipairs(arg) do
|
||||
arg[i] = string.lower(string.gsub(string.gsub(v, '%*', '.*'), '%%', '%%%%'))
|
||||
end
|
||||
local count = GetNumAddOns()
|
||||
for i = 1, count do
|
||||
local name = GetAddOnInfo(i)
|
||||
local good = true
|
||||
for _,v in ipairs(arg) do
|
||||
if not string.find(string.lower(name), v) then
|
||||
good = false
|
||||
break
|
||||
end
|
||||
end
|
||||
if good then
|
||||
listNormalAddon(i)
|
||||
end
|
||||
end
|
||||
end
|
||||
}
|
||||
},
|
||||
},
|
||||
enable = {
|
||||
desc = "Enable addon",
|
||||
name = "Enable",
|
||||
type = "text",
|
||||
usage = "<addon>",
|
||||
get = false,
|
||||
set = function(text)
|
||||
local name,title,_,_,_,reason = GetAddOnInfo(text)
|
||||
if reason == "MISSING" then
|
||||
print(string.format("|cffffff7fAce2:|r AddOn %q does not exist", text))
|
||||
else
|
||||
EnableAddOn(text)
|
||||
print(string.format("|cffffff7fAce2:|r %s is now enabled", title or name))
|
||||
end
|
||||
end,
|
||||
},
|
||||
disable = {
|
||||
desc = "Disable addon",
|
||||
name = "Disable",
|
||||
type = "text",
|
||||
usage = "<addon>",
|
||||
get = false,
|
||||
set = function(text)
|
||||
local name,title,_,_,_,reason = GetAddOnInfo(text)
|
||||
if reason == "MISSING" then
|
||||
print(string.format("|cffffff7fAce2:|r AddOn %q does not exist", text))
|
||||
else
|
||||
DisableAddOn(text)
|
||||
print(string.format("|cffffff7fAce2:|r %s is now disabled", title or name))
|
||||
end
|
||||
end,
|
||||
},
|
||||
load = {
|
||||
desc = "Load addon",
|
||||
name = "Load",
|
||||
type = "text",
|
||||
usage = "<addon>",
|
||||
get = false,
|
||||
set = function(text)
|
||||
local name,title,_,_,loadable,reason = GetAddOnInfo(text)
|
||||
if reason == "MISSING" then
|
||||
print(string.format("|cffffff7fAce2:|r AddOn %q does not exist.", text))
|
||||
elseif not loadable then
|
||||
print(string.format("|cffffff7fAce2:|r AddOn %q is not loadable. Reason: %s", text, reason))
|
||||
else
|
||||
LoadAddOn(text)
|
||||
print(string.format("|cffffff7fAce2:|r %s is now loaded", title or name))
|
||||
end
|
||||
end
|
||||
},
|
||||
info = {
|
||||
desc = "Display information",
|
||||
name = "Information",
|
||||
type = "execute",
|
||||
func = function()
|
||||
local mem, threshold = gcinfo()
|
||||
print(string.format(" - |cffffff7fMemory usage [|r%.3f MiB|cffffff7f]|r", mem / 1024))
|
||||
print(string.format(" - |cffffff7fThreshold [|r%.3f MiB|cffffff7f]|r", threshold / 1024))
|
||||
print(string.format(" - |cffffff7fFramerate [|r%.0f fps|cffffff7f]|r", GetFramerate()))
|
||||
local bandwidthIn, bandwidthOut, latency = GetNetStats()
|
||||
bandwidthIn, bandwidthOut = floor(bandwidthIn * 1024), floor(bandwidthOut * 1024)
|
||||
print(string.format(" - |cffffff7fLatency [|r%.0f ms|cffffff7f]|r", latency))
|
||||
print(string.format(" - |cffffff7fBandwidth in [|r%.0f B/s|cffffff7f]|r", bandwidthIn))
|
||||
print(string.format(" - |cffffff7fBandwidth out [|r%.0f B/s|cffffff7f]|r", bandwidthOut))
|
||||
print(string.format(" - |cffffff7fTotal addons [|r%d|cffffff7f]|r", GetNumAddOns()))
|
||||
print(string.format(" - |cffffff7fAce2 addons [|r%d|cffffff7f]|r", table.getn(self.addons)))
|
||||
local ace = 0
|
||||
local enabled = 0
|
||||
local disabled = 0
|
||||
local lod = 0
|
||||
for i = 1, GetNumAddOns() do
|
||||
local dep1, dep2, dep3, dep4 = GetAddOnDependencies(i)
|
||||
if dep1 == "Ace" or dep2 == "Ace" or dep3 == "Ace" or dep4 == "Ace" then
|
||||
ace = ace + 1
|
||||
end
|
||||
if IsAddOnLoadOnDemand(i) then
|
||||
lod = lod + 1
|
||||
end
|
||||
local _,_,_,IsActive,loadable = GetAddOnInfo(i)
|
||||
if not IsActive or not loadable then
|
||||
disabled = disabled + 1
|
||||
else
|
||||
enabled = enabled + 1
|
||||
end
|
||||
end
|
||||
print(string.format(" - |cffffff7fAce 1.x addons [|r%d|cffffff7f]|r", ace))
|
||||
print(string.format(" - |cffffff7fLoadOnDemand addons [|r%d|cffffff7f]|r", lod))
|
||||
print(string.format(" - |cffffff7fenabled addons [|r%d|cffffff7f]|r", enabled))
|
||||
print(string.format(" - |cffffff7fdisabled addons [|r%d|cffffff7f]|r", disabled))
|
||||
local libs = 0
|
||||
if type(AceLibrary) == "table" and type(AceLibrary.libs) == "table" then
|
||||
for _ in pairs(AceLibrary.libs) do
|
||||
libs = libs + 1
|
||||
end
|
||||
end
|
||||
print(string.format(" - |cffffff7fAceLibrary instances [|r%d|cffffff7f]|r", libs))
|
||||
end
|
||||
}
|
||||
}
|
||||
})
|
||||
elseif major == "AceModuleCore-2.0" then
|
||||
AceModuleCore = instance
|
||||
end
|
||||
end
|
||||
|
||||
local function activate(self, oldLib, oldDeactivate)
|
||||
AceAddon = self
|
||||
|
||||
if oldLib then
|
||||
self.playerLoginFired = oldLib.playerLoginFired or DEFAULT_CHAT_FRAME and DEFAULT_CHAT_FRAME.defaultLanguage
|
||||
self.addonsToOnEnable = oldLib.addonsToOnEnable
|
||||
self.addons = oldLib.addons
|
||||
self.nextAddon = oldLib.nextAddon
|
||||
self.addonsStarted = oldLib.addonsStarted
|
||||
end
|
||||
if not self.addons then
|
||||
self.addons = {}
|
||||
end
|
||||
if not self.nextAddon then
|
||||
self.nextAddon = {}
|
||||
end
|
||||
if not self.addonsStarted then
|
||||
self.addonsStarted = {}
|
||||
end
|
||||
if oldDeactivate then
|
||||
oldDeactivate(oldLib)
|
||||
end
|
||||
end
|
||||
|
||||
AceLibrary:Register(AceAddon, MAJOR_VERSION, MINOR_VERSION, activate, nil, external)
|
||||
AceAddon = AceLibrary(MAJOR_VERSION)
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,238 @@
|
||||
--[[
|
||||
Name: AceDebug-2.0
|
||||
Revision: $Rev: 15024 $
|
||||
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/AceDebug-2.0
|
||||
SVN: http://svn.wowace.com/root/trunk/Ace2/AceDebug-2.0
|
||||
Description: Mixin to allow for simple debugging capabilities.
|
||||
Dependencies: AceLibrary, AceOO-2.0
|
||||
]]
|
||||
|
||||
local MAJOR_VERSION = "AceDebug-2.0"
|
||||
local MINOR_VERSION = "$Revision: 15024 $"
|
||||
|
||||
if not AceLibrary then error(MAJOR_VERSION .. " requires AceLibrary") end
|
||||
if not AceLibrary:IsNewVersion(MAJOR_VERSION, MINOR_VERSION) then return end
|
||||
|
||||
if not AceLibrary:HasInstance("AceOO-2.0") then error(MAJOR_VERSION .. " requires AceOO-2.0") end
|
||||
|
||||
local DEBUGGING, TOGGLE_DEBUGGING
|
||||
|
||||
if GetLocale() == "frFR" then
|
||||
DEBUGGING = "D\195\169boguage"
|
||||
TOGGLE_DEBUGGING = "Activer/d\195\169sactiver le d\195\169boguage"
|
||||
elseif GetLocale() == "deDE" then
|
||||
DEBUGGING = "Debuggen"
|
||||
TOGGLE_DEBUGGING = "Aktiviert/Deaktiviert Debugging"
|
||||
elseif GetLocale() == "koKR" then
|
||||
DEBUGGING = "디버깅"
|
||||
TOGGLE_DEBUGGING = "디버깅 기능 사용함/사용안함"
|
||||
elseif GetLocale() == "zhTW" then
|
||||
DEBUGGING = "除錯"
|
||||
TOGGLE_DEBUGGING = "啟用/停用除錯功能"
|
||||
elseif GetLocale() == "zhCN" then
|
||||
DEBUGGING = "\232\176\131\232\175\149"
|
||||
TOGGLE_DEBUGGING = "\229\144\175\231\148\168/\231\166\129\231\148\168 \232\176\131\232\175\149"
|
||||
else -- enUS
|
||||
DEBUGGING = "Debugging"
|
||||
TOGGLE_DEBUGGING = "Enable/disable debugging"
|
||||
end
|
||||
|
||||
local table_setn
|
||||
do
|
||||
local version = GetBuildInfo()
|
||||
if string.find(version, "^2%.") then
|
||||
-- 2.0.0
|
||||
table_setn = function() end
|
||||
else
|
||||
table_setn = table.setn
|
||||
end
|
||||
end
|
||||
|
||||
local math_mod = math.mod or math.fmod
|
||||
|
||||
local AceOO = AceLibrary:GetInstance("AceOO-2.0")
|
||||
local AceDebug = AceOO.Mixin {"Debug", "CustomDebug", "IsDebugging", "SetDebugging", "SetDebugLevel", "LevelDebug", "CustomLevelDebug", "GetDebugLevel"}
|
||||
|
||||
local function print(text, r, g, b, frame, delay)
|
||||
(frame or DEFAULT_CHAT_FRAME):AddMessage(text, r, g, b, 1, delay or 5)
|
||||
end
|
||||
|
||||
local tmp
|
||||
|
||||
function AceDebug:CustomDebug(r, g, b, frame, delay, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20)
|
||||
if not self.debugging then return end
|
||||
|
||||
local output = string.format("|cff7fff7f(DEBUG) %s:[%s%3d]|r", tostring(self), date("%H:%M:%S"), math_mod(GetTime(), 1) * 1000)
|
||||
|
||||
if string.find(tostring(a1), "%%") then
|
||||
output = output .. " " .. string.format(tostring(a1), tostring(a2), tostring(a3), tostring(a4), tostring(a5), tostring(a6), tostring(a7), tostring(a8), tostring(a9), tostring(a10), tostring(a11), tostring(a12), tostring(a13), tostring(a14), tostring(a15), tostring(a16), tostring(a17), tostring(a18), tostring(a19), tostring(a20))
|
||||
else
|
||||
if not tmp then
|
||||
tmp = {}
|
||||
end
|
||||
|
||||
-- This block dynamically rebuilds the tmp array stopping on the first nil.
|
||||
table.insert(tmp, output)
|
||||
|
||||
table.insert(tmp, tostring(a1))
|
||||
table.insert(tmp, a2)
|
||||
table.insert(tmp, a3)
|
||||
table.insert(tmp, a4)
|
||||
table.insert(tmp, a5)
|
||||
table.insert(tmp, a6)
|
||||
table.insert(tmp, a7)
|
||||
table.insert(tmp, a8)
|
||||
table.insert(tmp, a9)
|
||||
table.insert(tmp, a10)
|
||||
table.insert(tmp, a11)
|
||||
table.insert(tmp, a12)
|
||||
table.insert(tmp, a13)
|
||||
table.insert(tmp, a14)
|
||||
table.insert(tmp, a15)
|
||||
table.insert(tmp, a16)
|
||||
table.insert(tmp, a17)
|
||||
table.insert(tmp, a18)
|
||||
table.insert(tmp, a19)
|
||||
table.insert(tmp, a20)
|
||||
while tmp[table.getn(tmp)] == nil do
|
||||
table.remove(tmp)
|
||||
end
|
||||
for k = 1, table.getn(tmp) do
|
||||
tmp[k] = tostring(tmp[k])
|
||||
end
|
||||
|
||||
output = table.concat(tmp, " ")
|
||||
|
||||
for k,v in pairs(tmp) do
|
||||
tmp[k] = nil
|
||||
end
|
||||
table_setn(tmp, 0)
|
||||
end
|
||||
|
||||
print(output, r, g, b, frame or self.debugFrame, delay)
|
||||
end
|
||||
|
||||
function AceDebug:Debug(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20)
|
||||
AceDebug.CustomDebug(self, nil, nil, nil, nil, nil, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20)
|
||||
end
|
||||
|
||||
function AceDebug:IsDebugging()
|
||||
return self.debugging
|
||||
end
|
||||
|
||||
function AceDebug:SetDebugging(debugging)
|
||||
self.debugging = debugging
|
||||
end
|
||||
|
||||
-- Takes a number 1-3
|
||||
-- Level 1: Critical messages that every user should receive
|
||||
-- Level 2: Should be used for local debugging (function calls, etc)
|
||||
-- Level 3: Very verbose debugging, will dump everything and anything
|
||||
-- If set to nil, you will receive no debug information
|
||||
function AceDebug:SetDebugLevel(level)
|
||||
AceDebug:argCheck(level, 1, "number", "nil")
|
||||
if not level then
|
||||
self.debuglevel = nil
|
||||
return
|
||||
end
|
||||
if level < 1 or level > 3 then
|
||||
AceDebug:error("Bad argument #1 to `SetDebugLevel`, must be a number 1-3")
|
||||
end
|
||||
self.debuglevel = level
|
||||
end
|
||||
|
||||
function AceDebug:GetDebugLevel()
|
||||
return self.debuglevel
|
||||
end
|
||||
|
||||
function AceDebug:CustomLevelDebug(level, r, g, b, frame, delay, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20)
|
||||
if not self.debugging or not self.debuglevel then return end
|
||||
AceDebug:argCheck(level, 1, "number")
|
||||
if level < 1 or level > 3 then
|
||||
AceDebug:error("Bad argument #1 to `LevelDebug`, must be a number 1-3")
|
||||
end
|
||||
if level > self.debuglevel then return end
|
||||
|
||||
local output = string.format("|cff7fff7f(DEBUG) %s:[%s.%3d]|r", tostring(self), date("%H:%M:%S"), math_mod(GetTime(), 1) * 1000)
|
||||
|
||||
if string.find(tostring(a1), "%%") then
|
||||
output = output .. " " .. string.format(tostring(a1), tostring(a2), tostring(a3), tostring(a4), tostring(a5), tostring(a6), tostring(a7), tostring(a8), tostring(a9), tostring(a10), tostring(a11), tostring(a12), tostring(a13), tostring(a14), tostring(a15), tostring(a16), tostring(a17), tostring(a18), tostring(a19), tostring(a20))
|
||||
else
|
||||
if not tmp then
|
||||
tmp = {}
|
||||
end
|
||||
|
||||
-- This block dynamically rebuilds the tmp array stopping on the first nil.
|
||||
table.insert(tmp, output)
|
||||
|
||||
table.insert(tmp, tostring(a1))
|
||||
table.insert(tmp, a2)
|
||||
table.insert(tmp, a3)
|
||||
table.insert(tmp, a4)
|
||||
table.insert(tmp, a5)
|
||||
table.insert(tmp, a6)
|
||||
table.insert(tmp, a7)
|
||||
table.insert(tmp, a8)
|
||||
table.insert(tmp, a9)
|
||||
table.insert(tmp, a10)
|
||||
table.insert(tmp, a11)
|
||||
table.insert(tmp, a12)
|
||||
table.insert(tmp, a13)
|
||||
table.insert(tmp, a14)
|
||||
table.insert(tmp, a15)
|
||||
table.insert(tmp, a16)
|
||||
table.insert(tmp, a17)
|
||||
table.insert(tmp, a18)
|
||||
table.insert(tmp, a19)
|
||||
table.insert(tmp, a20)
|
||||
while tmp[table.getn(tmp)] == nil do
|
||||
table.remove(tmp)
|
||||
end
|
||||
for k = 1, table.getn(tmp) do
|
||||
tmp[k] = tostring(tmp[k])
|
||||
end
|
||||
|
||||
output = table.concat(tmp, " ")
|
||||
|
||||
for k,v in pairs(tmp) do
|
||||
tmp[k] = nil
|
||||
end
|
||||
table_setn(tmp, 0)
|
||||
end
|
||||
|
||||
print(output, r, g, b, frame or self.debugFrame, delay)
|
||||
end
|
||||
|
||||
function AceDebug:LevelDebug(level, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20)
|
||||
if not self.debugging or not self.debuglevel then return end
|
||||
AceDebug:argCheck(level, 1, "number")
|
||||
if level < 1 or level > 3 then
|
||||
AceDebug:error("Bad argument #1 to `LevelDebug`, must be a number 1-3")
|
||||
end
|
||||
if level > self.debuglevel then return end
|
||||
|
||||
AceDebug.CustomLevelDebug(self, level, nil, nil, nil, nil, nil, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20)
|
||||
end
|
||||
|
||||
|
||||
local options
|
||||
function AceDebug:GetAceOptionsDataTable(target)
|
||||
if not options then
|
||||
options = {
|
||||
debug = {
|
||||
name = DEBUGGING,
|
||||
desc = TOGGLE_DEBUGGING,
|
||||
type = "toggle",
|
||||
get = "IsDebugging",
|
||||
set = "SetDebugging",
|
||||
order = -2,
|
||||
}
|
||||
}
|
||||
end
|
||||
return options
|
||||
end
|
||||
AceLibrary:Register(AceDebug, MAJOR_VERSION, MINOR_VERSION, AceDebug.activate)
|
||||
AceDebug = AceLibrary(MAJOR_VERSION)
|
||||
@@ -0,0 +1,962 @@
|
||||
--[[
|
||||
Name: AceEvent-2.0
|
||||
Revision: $Rev: 14125 $
|
||||
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/AceEvent-2.0
|
||||
SVN: http://svn.wowace.com/root/trunk/Ace2/AceEvent-2.0
|
||||
Description: Mixin to allow for event handling, scheduling, and inter-addon
|
||||
communication.
|
||||
Dependencies: AceLibrary, AceOO-2.0
|
||||
]]
|
||||
|
||||
local MAJOR_VERSION = "AceEvent-2.0"
|
||||
local MINOR_VERSION = "$Revision: 14125 $"
|
||||
|
||||
if not AceLibrary then error(MAJOR_VERSION .. " requires AceLibrary") end
|
||||
if not AceLibrary:IsNewVersion(MAJOR_VERSION, MINOR_VERSION) then return end
|
||||
|
||||
if not AceLibrary:HasInstance("AceOO-2.0") then error(MAJOR_VERSION .. " requires AceOO-2.0") end
|
||||
|
||||
local AceOO = AceLibrary:GetInstance("AceOO-2.0")
|
||||
local Mixin = AceOO.Mixin
|
||||
local AceEvent = Mixin {
|
||||
"RegisterEvent",
|
||||
"RegisterAllEvents",
|
||||
"UnregisterEvent",
|
||||
"UnregisterAllEvents",
|
||||
"TriggerEvent",
|
||||
"ScheduleEvent",
|
||||
"ScheduleRepeatingEvent",
|
||||
"CancelScheduledEvent",
|
||||
"CancelAllScheduledEvents",
|
||||
"IsEventRegistered",
|
||||
"IsEventScheduled",
|
||||
"RegisterBucketEvent",
|
||||
"UnregisterBucketEvent",
|
||||
"UnregisterAllBucketEvents",
|
||||
"IsBucketEventRegistered",
|
||||
}
|
||||
|
||||
local table_setn
|
||||
do
|
||||
local version = GetBuildInfo()
|
||||
if string.find(version, "^2%.") then
|
||||
-- 2.0.0
|
||||
table_setn = function() end
|
||||
else
|
||||
table_setn = table.setn
|
||||
end
|
||||
end
|
||||
|
||||
local weakKey = {__mode="k"}
|
||||
local new, del
|
||||
do
|
||||
local list = setmetatable({}, weakKey)
|
||||
function new()
|
||||
local t = next(list)
|
||||
if t then
|
||||
list[t] = nil
|
||||
return t
|
||||
else
|
||||
return {}
|
||||
end
|
||||
end
|
||||
|
||||
function del(t)
|
||||
setmetatable(t, nil)
|
||||
for k in pairs(t) do
|
||||
t[k] = nil
|
||||
end
|
||||
list[t] = true
|
||||
end
|
||||
end
|
||||
|
||||
local FAKE_NIL
|
||||
local RATE
|
||||
|
||||
local eventsWhichHappenOnce = {
|
||||
PLAYER_LOGIN = true,
|
||||
AceEvent_FullyInitialized = true,
|
||||
VARIABLES_LOADED = true,
|
||||
PLAYER_LOGOUT = true,
|
||||
}
|
||||
|
||||
local registeringFromAceEvent
|
||||
function AceEvent:RegisterEvent(event, method, once)
|
||||
AceEvent:argCheck(event, 2, "string")
|
||||
if self == AceEvent and not registeringFromAceEvent then
|
||||
AceEvent:argCheck(method, 3, "function")
|
||||
self = method
|
||||
else
|
||||
AceEvent:argCheck(method, 3, "string", "function", "nil", "boolean", "number")
|
||||
if type(method) == "boolean" or type(method) == "number" then
|
||||
AceEvent:argCheck(once, 4, "nil")
|
||||
once, method = method, event
|
||||
end
|
||||
end
|
||||
AceEvent:argCheck(once, 4, "number", "boolean", "nil")
|
||||
if eventsWhichHappenOnce[event] then
|
||||
once = true
|
||||
end
|
||||
local throttleRate
|
||||
if type(once) == "number" then
|
||||
throttleRate, once = once
|
||||
end
|
||||
if not method then
|
||||
method = event
|
||||
end
|
||||
if type(method) == "string" and type(self[method]) ~= "function" then
|
||||
AceEvent:error("Cannot register event %q to method %q, it does not exist", event, method)
|
||||
else
|
||||
assert(type(method) == "function" or type(method) == "string")
|
||||
end
|
||||
|
||||
local AceEvent_registry = AceEvent.registry
|
||||
if not AceEvent_registry[event] then
|
||||
AceEvent_registry[event] = new()
|
||||
AceEvent.frame:RegisterEvent(event)
|
||||
end
|
||||
|
||||
local remember = true
|
||||
if AceEvent_registry[event][self] then
|
||||
remember = false
|
||||
end
|
||||
AceEvent_registry[event][self] = method
|
||||
|
||||
local AceEvent_onceRegistry = AceEvent.onceRegistry
|
||||
if once then
|
||||
if not AceEvent_onceRegistry then
|
||||
AceEvent.onceRegistry = new()
|
||||
AceEvent_onceRegistry = AceEvent.onceRegistry
|
||||
end
|
||||
if not AceEvent_onceRegistry[event] then
|
||||
AceEvent_onceRegistry[event] = new()
|
||||
end
|
||||
AceEvent_onceRegistry[event][self] = true
|
||||
else
|
||||
if AceEvent_onceRegistry and AceEvent_onceRegistry[event] then
|
||||
AceEvent_onceRegistry[event][self] = nil
|
||||
if not next(AceEvent_onceRegistry[event]) then
|
||||
AceEvent_onceRegistry[event] = del(AceEvent_onceRegistry[event])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local AceEvent_throttleRegistry = AceEvent.throttleRegistry
|
||||
if throttleRate then
|
||||
if not AceEvent_throttleRegistry then
|
||||
AceEvent.throttleRegistry = new()
|
||||
AceEvent_throttleRegistry = AceEvent.throttleRegistry
|
||||
end
|
||||
if not AceEvent_throttleRegistry[event] then
|
||||
AceEvent_throttleRegistry[event] = new()
|
||||
end
|
||||
if AceEvent_throttleRegistry[event][self] then
|
||||
AceEvent_throttleRegistry[event][self] = del(AceEvent_throttleRegistry[event][self])
|
||||
end
|
||||
AceEvent_throttleRegistry[event][self] = setmetatable(new(), weakKey)
|
||||
local t = AceEvent_throttleRegistry[event][self]
|
||||
t[RATE] = throttleRate
|
||||
else
|
||||
if AceEvent_throttleRegistry and AceEvent_throttleRegistry[event] then
|
||||
if AceEvent_throttleRegistry[event][self] then
|
||||
AceEvent_throttleRegistry[event][self] = del(AceEvent_throttleRegistry[event][self])
|
||||
end
|
||||
if not next(AceEvent_throttleRegistry[event]) then
|
||||
AceEvent_throttleRegistry[event] = del(AceEvent_throttleRegistry[event])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if remember then
|
||||
AceEvent:TriggerEvent("AceEvent_EventRegistered", self, event)
|
||||
end
|
||||
end
|
||||
|
||||
local ALL_EVENTS
|
||||
|
||||
function AceEvent:RegisterAllEvents(method)
|
||||
if self == AceEvent then
|
||||
AceEvent:argCheck(method, 1, "function")
|
||||
self = method
|
||||
else
|
||||
AceEvent:argCheck(method, 1, "string", "function")
|
||||
if type(method) == "string" and type(self[method]) ~= "function" then
|
||||
AceEvent:error("Cannot register all events to method %q, it does not exist", method)
|
||||
end
|
||||
end
|
||||
|
||||
local AceEvent_registry = AceEvent.registry
|
||||
if not AceEvent_registry[ALL_EVENTS] then
|
||||
AceEvent_registry[ALL_EVENTS] = new()
|
||||
AceEvent.frame:RegisterAllEvents()
|
||||
end
|
||||
|
||||
AceEvent_registry[ALL_EVENTS][self] = method
|
||||
end
|
||||
|
||||
local _G = getfenv(0)
|
||||
local memstack, timestack = {}, {}
|
||||
local memdiff, timediff
|
||||
function AceEvent:TriggerEvent(event, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20)
|
||||
AceEvent:argCheck(event, 2, "string")
|
||||
local AceEvent_registry = AceEvent.registry
|
||||
if (not AceEvent_registry[event] or not next(AceEvent_registry[event])) and (not AceEvent_registry[ALL_EVENTS] or not next(AceEvent_registry[ALL_EVENTS])) then
|
||||
return
|
||||
end
|
||||
local _G_event = _G.event
|
||||
_G.event = event
|
||||
|
||||
local AceEvent_onceRegistry = AceEvent.onceRegistry
|
||||
local AceEvent_debugTable = AceEvent.debugTable
|
||||
if AceEvent_onceRegistry and AceEvent_onceRegistry[event] then
|
||||
local tmp = new()
|
||||
for obj, method in pairs(AceEvent_onceRegistry[event]) do
|
||||
tmp[obj] = AceEvent_registry[event] and AceEvent_registry[event][obj] or nil
|
||||
end
|
||||
local obj = next(tmp)
|
||||
while obj do
|
||||
local mem, time
|
||||
if AceEvent_debugTable then
|
||||
if not AceEvent_debugTable[event] then
|
||||
AceEvent_debugTable[event] = new()
|
||||
end
|
||||
if not AceEvent_debugTable[event][obj] then
|
||||
AceEvent_debugTable[event][obj] = new()
|
||||
AceEvent_debugTable[event][obj].mem = 0
|
||||
AceEvent_debugTable[event][obj].time = 0
|
||||
AceEvent_debugTable[event][obj].count = 0
|
||||
end
|
||||
if memdiff then
|
||||
table.insert(memstack, memdiff)
|
||||
table.insert(timestack, timediff)
|
||||
end
|
||||
memdiff, timediff = 0, 0
|
||||
mem, time = gcinfo(), GetTime()
|
||||
end
|
||||
local method = tmp[obj]
|
||||
AceEvent.UnregisterEvent(obj, event)
|
||||
if type(method) == "string" then
|
||||
local obj_method = obj[method]
|
||||
if obj_method then
|
||||
obj_method(obj, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20)
|
||||
end
|
||||
elseif method then -- function
|
||||
method(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20)
|
||||
end
|
||||
if AceEvent_debugTable then
|
||||
local dmem, dtime = memdiff, timediff
|
||||
mem, time = gcinfo() - mem - memdiff, GetTime() - time - timediff
|
||||
AceEvent_debugTable[event][obj].mem = AceEvent_debugTable[event][obj].mem + mem
|
||||
AceEvent_debugTable[event][obj].time = AceEvent_debugTable[event][obj].time + time
|
||||
AceEvent_debugTable[event][obj].count = AceEvent_debugTable[event][obj].count + 1
|
||||
|
||||
memdiff, timediff = table.remove(memstack), table.remove(timestack)
|
||||
if memdiff then
|
||||
memdiff = memdiff + mem + dmem
|
||||
timediff = timediff + time + dtime
|
||||
end
|
||||
end
|
||||
tmp[obj] = nil
|
||||
obj = next(tmp)
|
||||
end
|
||||
del(tmp)
|
||||
end
|
||||
|
||||
local AceEvent_throttleRegistry = AceEvent.throttleRegistry
|
||||
local throttleTable = AceEvent_throttleRegistry and AceEvent_throttleRegistry[event]
|
||||
if AceEvent_registry[event] then
|
||||
local tmp = new()
|
||||
for obj, method in pairs(AceEvent_registry[event]) do
|
||||
tmp[obj] = method
|
||||
end
|
||||
local obj = next(tmp)
|
||||
while obj do
|
||||
local method = tmp[obj]
|
||||
local continue = false
|
||||
if throttleTable and throttleTable[obj] then
|
||||
local a1 = a1
|
||||
if a1 == nil then
|
||||
a1 = FAKE_NIL
|
||||
end
|
||||
if not throttleTable[obj][a1] or GetTime() - throttleTable[obj][a1] >= throttleTable[obj][RATE] then
|
||||
throttleTable[obj][a1] = GetTime()
|
||||
else
|
||||
continue = true
|
||||
end
|
||||
end
|
||||
if not continue then
|
||||
local mem, time
|
||||
if AceEvent_debugTable then
|
||||
if not AceEvent_debugTable[event] then
|
||||
AceEvent_debugTable[event] = new()
|
||||
end
|
||||
if not AceEvent_debugTable[event][obj] then
|
||||
AceEvent_debugTable[event][obj] = new()
|
||||
AceEvent_debugTable[event][obj].mem = 0
|
||||
AceEvent_debugTable[event][obj].time = 0
|
||||
AceEvent_debugTable[event][obj].count = 0
|
||||
end
|
||||
if memdiff then
|
||||
table.insert(memstack, memdiff)
|
||||
table.insert(timestack, timediff)
|
||||
end
|
||||
memdiff, timediff = 0, 0
|
||||
mem, time = gcinfo(), GetTime()
|
||||
end
|
||||
if type(method) == "string" then
|
||||
local obj_method = obj[method]
|
||||
if obj_method then
|
||||
obj_method(obj, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20)
|
||||
end
|
||||
elseif method then -- function
|
||||
method(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20)
|
||||
end
|
||||
if AceEvent_debugTable then
|
||||
local dmem, dtime = memdiff, timediff
|
||||
mem, time = gcinfo() - mem - memdiff, GetTime() - time - timediff
|
||||
AceEvent_debugTable[event][obj].mem = AceEvent_debugTable[event][obj].mem + mem
|
||||
AceEvent_debugTable[event][obj].time = AceEvent_debugTable[event][obj].time + time
|
||||
AceEvent_debugTable[event][obj].count = AceEvent_debugTable[event][obj].count + 1
|
||||
|
||||
memdiff, timediff = table.remove(memstack), table.remove(timestack)
|
||||
if memdiff then
|
||||
memdiff = memdiff + mem + dmem
|
||||
timediff = timediff + time + dtime
|
||||
end
|
||||
end
|
||||
end
|
||||
tmp[obj] = nil
|
||||
obj = next(tmp)
|
||||
end
|
||||
del(tmp)
|
||||
end
|
||||
if AceEvent_registry[ALL_EVENTS] then
|
||||
local tmp = new()
|
||||
for obj, method in pairs(AceEvent_registry[ALL_EVENTS]) do
|
||||
tmp[obj] = method
|
||||
end
|
||||
local obj = next(tmp)
|
||||
while obj do
|
||||
local method = tmp[obj]
|
||||
local mem, time
|
||||
if AceEvent_debugTable then
|
||||
if not AceEvent_debugTable[event] then
|
||||
AceEvent_debugTable[event] = new()
|
||||
end
|
||||
if not AceEvent_debugTable[event][obj] then
|
||||
AceEvent_debugTable[event][obj] = new()
|
||||
AceEvent_debugTable[event][obj].mem = 0
|
||||
AceEvent_debugTable[event][obj].time = 0
|
||||
AceEvent_debugTable[event][obj].count = 0
|
||||
end
|
||||
if memdiff then
|
||||
table.insert(memstack, memdiff)
|
||||
table.insert(timestack, timediff)
|
||||
end
|
||||
memdiff, timediff = 0, 0
|
||||
mem, time = gcinfo(), GetTime()
|
||||
end
|
||||
if type(method) == "string" then
|
||||
local obj_method = obj[method]
|
||||
if obj_method then
|
||||
obj_method(obj, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20)
|
||||
end
|
||||
elseif method then -- function
|
||||
method(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20)
|
||||
end
|
||||
if AceEvent_debugTable then
|
||||
local dmem, dtime = memdiff, timediff
|
||||
mem, time = gcinfo() - mem - memdiff, GetTime() - time - timediff
|
||||
AceEvent_debugTable[event][obj].mem = AceEvent_debugTable[event][obj].mem + mem
|
||||
AceEvent_debugTable[event][obj].time = AceEvent_debugTable[event][obj].time + time
|
||||
AceEvent_debugTable[event][obj].count = AceEvent_debugTable[event][obj].count + 1
|
||||
|
||||
memdiff, timediff = table.remove(memstack), table.remove(timestack)
|
||||
if memdiff then
|
||||
memdiff = memdiff + mem + dmem
|
||||
timediff = timediff + time + dtime
|
||||
end
|
||||
end
|
||||
tmp[obj] = nil
|
||||
obj = next(tmp)
|
||||
end
|
||||
del(tmp)
|
||||
end
|
||||
_G.event = _G_event
|
||||
end
|
||||
|
||||
-- local accessors
|
||||
local getn = table.getn
|
||||
local tinsert = table.insert
|
||||
local tremove = table.remove
|
||||
local floor = math.floor
|
||||
local GetTime = GetTime
|
||||
local next = next
|
||||
local pairs = pairs
|
||||
local unpack = unpack
|
||||
|
||||
local delayRegistry
|
||||
local function OnUpdate()
|
||||
local t = GetTime()
|
||||
local k,v = next(delayRegistry)
|
||||
local last = nil
|
||||
while k do
|
||||
local v_time = v.time
|
||||
if not v_time then
|
||||
delayRegistry[k] = del(v)
|
||||
elseif v_time <= t then
|
||||
local v_repeatDelay = v.repeatDelay
|
||||
if v_repeatDelay then
|
||||
-- use the event time, not the current time, else timing inaccuracies add up over time
|
||||
v.time = v_time + v_repeatDelay
|
||||
end
|
||||
local event = v.event
|
||||
local mem, time
|
||||
if AceEvent_debugTable then
|
||||
mem, time = gcinfo(), GetTime()
|
||||
end
|
||||
if type(event) == "function" then
|
||||
event(unpack(v))
|
||||
else
|
||||
AceEvent:TriggerEvent(event, unpack(v))
|
||||
end
|
||||
if AceEvent_debugTable then
|
||||
mem, time = gcinfo() - mem, GetTime() - time
|
||||
v.mem = v.mem + mem
|
||||
v.timeSpent = v.timeSpent + time
|
||||
v.count = v.count + 1
|
||||
end
|
||||
if not v_repeatDelay then
|
||||
local x = delayRegistry[k]
|
||||
if x and x.time == v_time then -- check if it was manually reset
|
||||
delayRegistry[k] = del(v)
|
||||
end
|
||||
end
|
||||
end
|
||||
if delayRegistry[k] then
|
||||
last = k
|
||||
end
|
||||
k,v = next(delayRegistry, last)
|
||||
end
|
||||
if not next(delayRegistry) then
|
||||
AceEvent.frame:Hide()
|
||||
end
|
||||
end
|
||||
|
||||
local function ScheduleEvent(self, repeating, event, delay, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20)
|
||||
local id
|
||||
if type(event) == "string" or type(event) == "table" then
|
||||
if type(event) == "table" then
|
||||
if not delayRegistry or not delayRegistry[event] then
|
||||
AceEvent:error("Bad argument #2 to `ScheduleEvent'. Improper id table fed in.")
|
||||
end
|
||||
end
|
||||
if type(delay) ~= "number" then
|
||||
id, event, delay, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20 = event, delay, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20
|
||||
AceEvent:argCheck(event, 3, "string", "function", --[[ so message is right ]] "number")
|
||||
AceEvent:argCheck(delay, 4, "number")
|
||||
self:CancelScheduledEvent(id)
|
||||
end
|
||||
else
|
||||
AceEvent:argCheck(event, 2, "string", "function")
|
||||
AceEvent:argCheck(delay, 3, "number")
|
||||
end
|
||||
|
||||
if not delayRegistry then
|
||||
AceEvent.delayRegistry = new()
|
||||
delayRegistry = AceEvent.delayRegistry
|
||||
AceEvent.frame:SetScript("OnUpdate", OnUpdate)
|
||||
end
|
||||
local t
|
||||
if type(id) == "table" then
|
||||
for k in pairs(id) do
|
||||
id[k] = nil
|
||||
end
|
||||
t = id
|
||||
else
|
||||
t = new()
|
||||
end
|
||||
t[1] = a1
|
||||
t[2] = a2
|
||||
t[3] = a3
|
||||
t[4] = a4
|
||||
t[5] = a5
|
||||
t[6] = a6
|
||||
t[7] = a7
|
||||
t[8] = a8
|
||||
t[9] = a9
|
||||
t[10] = a10
|
||||
t[11] = a11
|
||||
t[12] = a12
|
||||
t[13] = a13
|
||||
t[14] = a14
|
||||
t[15] = a15
|
||||
t[16] = a16
|
||||
t[17] = a17
|
||||
t[18] = a18
|
||||
t[19] = a19
|
||||
t[20] = a20
|
||||
table_setn(t, 20)
|
||||
t.event = event
|
||||
t.time = GetTime() + delay
|
||||
t.self = self
|
||||
t.id = id or t
|
||||
t.repeatDelay = repeating and delay
|
||||
if AceEvent_debugTable then
|
||||
t.mem = 0
|
||||
t.count = 0
|
||||
t.timeSpent = 0
|
||||
end
|
||||
delayRegistry[t.id] = t
|
||||
AceEvent.frame:Show()
|
||||
return t.id
|
||||
end
|
||||
|
||||
function AceEvent:ScheduleEvent(event, delay, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20)
|
||||
if type(event) == "string" or type(event) == "table" then
|
||||
if type(event) == "table" then
|
||||
if not delayRegistry or not delayRegistry[event] then
|
||||
AceEvent:error("Bad argument #2 to `ScheduleEvent'. Improper id table fed in.")
|
||||
end
|
||||
end
|
||||
if type(delay) ~= "number" then
|
||||
AceEvent:argCheck(delay, 3, "string", "function", --[[ so message is right ]] "number")
|
||||
AceEvent:argCheck(a1, 4, "number")
|
||||
end
|
||||
else
|
||||
AceEvent:argCheck(event, 2, "string", "function")
|
||||
AceEvent:argCheck(delay, 3, "number")
|
||||
end
|
||||
|
||||
return ScheduleEvent(self, false, event, delay, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20)
|
||||
end
|
||||
|
||||
function AceEvent:ScheduleRepeatingEvent(event, delay, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20)
|
||||
if type(event) == "string" or type(event) == "table" then
|
||||
if type(event) == "table" then
|
||||
if not delayRegistry or not delayRegistry[event] then
|
||||
AceEvent:error("Bad argument #2 to `ScheduleEvent'. Improper id table fed in.")
|
||||
end
|
||||
end
|
||||
if type(delay) ~= "number" then
|
||||
AceEvent:argCheck(delay, 3, "string", "function", --[[ so message is right ]] "number")
|
||||
AceEvent:argCheck(a1, 4, "number")
|
||||
end
|
||||
else
|
||||
AceEvent:argCheck(event, 2, "string", "function")
|
||||
AceEvent:argCheck(delay, 3, "number")
|
||||
end
|
||||
|
||||
return ScheduleEvent(self, true, event, delay, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20)
|
||||
end
|
||||
|
||||
function AceEvent:CancelScheduledEvent(t)
|
||||
AceEvent:argCheck(t, 2, "string", "table")
|
||||
if delayRegistry then
|
||||
local v = delayRegistry[t]
|
||||
if v then
|
||||
delayRegistry[t] = del(v)
|
||||
if not next(delayRegistry) then
|
||||
AceEvent.frame:Hide()
|
||||
end
|
||||
return true
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
function AceEvent:IsEventScheduled(t)
|
||||
AceEvent:argCheck(t, 2, "string", "table")
|
||||
if delayRegistry then
|
||||
local v = delayRegistry[t]
|
||||
if v then
|
||||
return true, v.time - GetTime()
|
||||
end
|
||||
end
|
||||
return false, nil
|
||||
end
|
||||
|
||||
function AceEvent:UnregisterEvent(event)
|
||||
AceEvent:argCheck(event, 2, "string")
|
||||
local AceEvent_registry = AceEvent.registry
|
||||
if AceEvent_registry[event] and AceEvent_registry[event][self] then
|
||||
AceEvent_registry[event][self] = nil
|
||||
local AceEvent_onceRegistry = AceEvent.onceRegistry
|
||||
if AceEvent_onceRegistry and AceEvent_onceRegistry[event] and AceEvent_onceRegistry[event][self] then
|
||||
AceEvent_onceRegistry[event][self] = nil
|
||||
if not next(AceEvent_onceRegistry[event]) then
|
||||
AceEvent_onceRegistry[event] = del(AceEvent_onceRegistry[event])
|
||||
end
|
||||
end
|
||||
local AceEvent_throttleRegistry = AceEvent.throttleRegistry
|
||||
if AceEvent_throttleRegistry and AceEvent_throttleRegistry[event] and AceEvent_throttleRegistry[event][self] then
|
||||
AceEvent_throttleRegistry[event][self] = del(AceEvent_throttleRegistry[event][self])
|
||||
if not next(AceEvent_throttleRegistry[event]) then
|
||||
AceEvent_throttleRegistry[event] = del(AceEvent_throttleRegistry[event])
|
||||
end
|
||||
end
|
||||
if not next(AceEvent_registry[event]) then
|
||||
AceEvent_registry[event] = del(AceEvent_registry[event])
|
||||
if not AceEvent_registry[ALL_EVENTS] or not next(AceEvent_registry[ALL_EVENTS]) then
|
||||
AceEvent.frame:UnregisterEvent(event)
|
||||
end
|
||||
end
|
||||
else
|
||||
if self == AceEvent then
|
||||
error(string.format("Cannot unregister event %q. Improperly unregistering from AceEvent-2.0.", event), 2)
|
||||
else
|
||||
AceEvent:error("Cannot unregister event %q. %q is not registered with it.", event, self)
|
||||
end
|
||||
end
|
||||
AceEvent:TriggerEvent("AceEvent_EventUnregistered", self, event)
|
||||
end
|
||||
|
||||
function AceEvent:UnregisterAllEvents()
|
||||
local AceEvent_registry = AceEvent.registry
|
||||
if AceEvent_registry[ALL_EVENTS] and AceEvent_registry[ALL_EVENTS][self] then
|
||||
AceEvent_registry[ALL_EVENTS][self] = nil
|
||||
if not next(AceEvent_registry[ALL_EVENTS]) then
|
||||
del(AceEvent_registry[ALL_EVENTS])
|
||||
AceEvent.frame:UnregisterAllEvents()
|
||||
for k,v in pairs(AceEvent_registry) do
|
||||
if k ~= ALL_EVENTS then
|
||||
AceEvent.frame:RegisterEvent(k)
|
||||
end
|
||||
end
|
||||
AceEvent_registry[event] = nil
|
||||
end
|
||||
end
|
||||
local first = true
|
||||
for event, data in pairs(AceEvent_registry) do
|
||||
if first then
|
||||
if AceEvent_registry.AceEvent_EventUnregistered then
|
||||
event = "AceEvent_EventUnregistered"
|
||||
else
|
||||
first = false
|
||||
end
|
||||
end
|
||||
local x = data[self]
|
||||
data[self] = nil
|
||||
if x and event ~= ALL_EVENTS then
|
||||
if not next(data) then
|
||||
del(data)
|
||||
if not AceEvent_registry[ALL_EVENTS] or not next(AceEvent_registry[ALL_EVENTS]) then
|
||||
AceEvent.frame:UnregisterEvent(event)
|
||||
end
|
||||
AceEvent_registry[event] = nil
|
||||
end
|
||||
AceEvent:TriggerEvent("AceEvent_EventUnregistered", self, event)
|
||||
end
|
||||
if first then
|
||||
event = nil
|
||||
end
|
||||
end
|
||||
if AceEvent.onceRegistry then
|
||||
for event, data in pairs(AceEvent.onceRegistry) do
|
||||
data[self] = nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function AceEvent:CancelAllScheduledEvents()
|
||||
if delayRegistry then
|
||||
for k,v in pairs(delayRegistry) do
|
||||
if v.self == self then
|
||||
delayRegistry[k] = del(v)
|
||||
end
|
||||
end
|
||||
if not next(delayRegistry) then
|
||||
AceEvent.frame:Hide()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function AceEvent:IsEventRegistered(event)
|
||||
AceEvent:argCheck(event, 2, "string")
|
||||
local AceEvent_registry = AceEvent.registry
|
||||
if self == AceEvent then
|
||||
return AceEvent_registry[event] and next(AceEvent_registry[event]) and true or false
|
||||
end
|
||||
if AceEvent_registry[event] and AceEvent_registry[event][self] then
|
||||
return true, AceEvent_registry[event][self]
|
||||
end
|
||||
return false, nil
|
||||
end
|
||||
|
||||
local bucketfunc
|
||||
function AceEvent:RegisterBucketEvent(event, delay, method)
|
||||
AceEvent:argCheck(event, 2, "string", "table")
|
||||
if type(event) == "table" then
|
||||
for k,v in pairs(event) do
|
||||
if type(k) ~= "number" then
|
||||
AceEvent:error("All keys to argument #2 to `RegisterBucketEvent' must be numbers.")
|
||||
elseif type(v) ~= "string" then
|
||||
AceEvent:error("All values to argument #2 to `RegisterBucketEvent' must be strings.")
|
||||
end
|
||||
end
|
||||
end
|
||||
AceEvent:argCheck(delay, 3, "number")
|
||||
if AceEvent == self then
|
||||
AceEvent:argCheck(method, 4, "function")
|
||||
self = method
|
||||
else
|
||||
if type(event) == "string" then
|
||||
AceEvent:argCheck(method, 4, "string", "function", "nil")
|
||||
if not method then
|
||||
method = event
|
||||
end
|
||||
else
|
||||
AceEvent:argCheck(method, 4, "string", "function")
|
||||
end
|
||||
|
||||
if type(method) == "string" and type(self[method]) ~= "function" then
|
||||
AceEvent:error("Cannot register event %q to method %q, it does not exist", event, method)
|
||||
end
|
||||
end
|
||||
if not AceEvent.buckets then
|
||||
AceEvent.buckets = new()
|
||||
end
|
||||
if not AceEvent.buckets[event] then
|
||||
AceEvent.buckets[event] = new()
|
||||
end
|
||||
if not AceEvent.buckets[event][self] then
|
||||
AceEvent.buckets[event][self] = new()
|
||||
AceEvent.buckets[event][self].current = new()
|
||||
AceEvent.buckets[event][self].self = self
|
||||
else
|
||||
AceEvent.CancelScheduledEvent(self, AceEvent.buckets[event][self].id)
|
||||
end
|
||||
local bucket = AceEvent.buckets[event][self]
|
||||
bucket.method = method
|
||||
|
||||
local func = function(arg1)
|
||||
bucket.run = true
|
||||
if arg1 then
|
||||
bucket.current[arg1] = true
|
||||
end
|
||||
end
|
||||
AceEvent.buckets[event][self].func = func
|
||||
if type(event) == "string" then
|
||||
AceEvent.RegisterEvent(self, event, func)
|
||||
else
|
||||
for _,v in ipairs(event) do
|
||||
AceEvent.RegisterEvent(self, v, func)
|
||||
end
|
||||
end
|
||||
if not bucketfunc then
|
||||
bucketfunc = function(bucket)
|
||||
local current = bucket.current
|
||||
local method = bucket.method
|
||||
local self = bucket.self
|
||||
if bucket.run then
|
||||
if type(method) == "string" then
|
||||
self[method](self, current)
|
||||
elseif method then -- function
|
||||
method(current)
|
||||
end
|
||||
for k in pairs(current) do
|
||||
current[k] = nil
|
||||
k = nil
|
||||
end
|
||||
bucket.run = false
|
||||
end
|
||||
end
|
||||
end
|
||||
bucket.id = AceEvent.ScheduleRepeatingEvent(self, bucketfunc, delay, bucket)
|
||||
end
|
||||
|
||||
function AceEvent:IsBucketEventRegistered(event)
|
||||
AceEvent:argCheck(event, 2, "string", "table")
|
||||
return AceEvent.buckets and AceEvent.buckets[event] and AceEvent.buckets[event][self]
|
||||
end
|
||||
|
||||
function AceEvent:UnregisterBucketEvent(event)
|
||||
AceEvent:argCheck(event, 2, "string", "table")
|
||||
if not AceEvent.buckets or not AceEvent.buckets[event] or not AceEvent.buckets[event][self] then
|
||||
AceEvent:error("Cannot unregister bucket event %q. %q is not registered with it.", event, self)
|
||||
end
|
||||
|
||||
local bucket = AceEvent.buckets[event][self]
|
||||
|
||||
if type(event) == "string" then
|
||||
AceEvent.UnregisterEvent(self, event)
|
||||
else
|
||||
for _,v in ipairs(event) do
|
||||
AceEvent.UnregisterEvent(self, v)
|
||||
end
|
||||
end
|
||||
AceEvent:CancelScheduledEvent(bucket.id)
|
||||
|
||||
del(bucket.current)
|
||||
AceEvent.buckets[event][self] = del(AceEvent.buckets[event][self])
|
||||
if not next(AceEvent.buckets[event]) then
|
||||
AceEvent.buckets[event] = del(AceEvent.buckets[event])
|
||||
end
|
||||
end
|
||||
|
||||
function AceEvent:UnregisterAllBucketEvents()
|
||||
if not AceEvent.buckets or not next(AceEvent.buckets) then
|
||||
return
|
||||
end
|
||||
for k,v in pairs(AceEvent.buckets) do
|
||||
if v == self then
|
||||
AceEvent.UnregisterBucketEvent(self, k)
|
||||
k = nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function AceEvent:OnEmbedDisable(target)
|
||||
self.UnregisterAllEvents(target)
|
||||
|
||||
self.CancelAllScheduledEvents(target)
|
||||
|
||||
self.UnregisterAllBucketEvents(target)
|
||||
end
|
||||
|
||||
function AceEvent:EnableDebugging()
|
||||
if not self.debugTable then
|
||||
self.debugTable = new()
|
||||
|
||||
if delayRegistry then
|
||||
for k,v in pairs(self.delayRegistry) do
|
||||
if not v.mem then
|
||||
v.mem = 0
|
||||
v.count = 0
|
||||
v.timeSpent = 0
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function AceEvent:IsFullyInitialized()
|
||||
return self.postInit or false
|
||||
end
|
||||
|
||||
function AceEvent:IsPostPlayerLogin()
|
||||
return self.playerLogin or false
|
||||
end
|
||||
|
||||
function AceEvent:activate(oldLib, oldDeactivate)
|
||||
AceEvent = self
|
||||
|
||||
if oldLib then
|
||||
self.onceRegistry = oldLib.onceRegistry
|
||||
self.throttleRegistry = oldLib.throttleRegistry
|
||||
self.delayRegistry = oldLib.delayRegistry
|
||||
self.buckets = oldLib.buckets
|
||||
self.registry = oldLib.registry
|
||||
self.frame = oldLib.frame
|
||||
self.debugTable = oldLib.debugTable
|
||||
self.playerLogin = oldLib.pew or DEFAULT_CHAT_FRAME and DEFAULT_CHAT_FRAME.defaultLanguage and true
|
||||
self.postInit = oldLib.postInit or self.playerLogin and ChatTypeInfo and ChatTypeInfo.WHISPER and ChatTypeInfo.WHISPER.r and true
|
||||
self.ALL_EVENTS = oldLib.ALL_EVENTS
|
||||
self.FAKE_NIL = oldLib.FAKE_NIL
|
||||
self.RATE = oldLib.RATE
|
||||
end
|
||||
if not self.registry then
|
||||
self.registry = {}
|
||||
end
|
||||
if not self.frame then
|
||||
self.frame = CreateFrame("Frame", "AceEvent20Frame")
|
||||
end
|
||||
if not self.ALL_EVENTS then
|
||||
self.ALL_EVENTS = {}
|
||||
end
|
||||
if not self.FAKE_NIL then
|
||||
self.FAKE_NIL = {}
|
||||
end
|
||||
if not self.RATE then
|
||||
self.RATE = {}
|
||||
end
|
||||
ALL_EVENTS = self.ALL_EVENTS
|
||||
FAKE_NIL = self.FAKE_NIL
|
||||
RATE = self.RATE
|
||||
local inPlw = false
|
||||
local blacklist = {
|
||||
UNIT_INVENTORY_CHANGED = true,
|
||||
BAG_UPDATE = true,
|
||||
ITEM_LOCK_CHANGED = true,
|
||||
ACTIONBAR_SLOT_CHANGED = true,
|
||||
}
|
||||
self.frame:SetScript("OnEvent", function()
|
||||
local event = event
|
||||
if event == "PLAYER_ENTERING_WORLD" then
|
||||
inPlw = false
|
||||
elseif event == "PLAYER_LEAVING_WORLD" then
|
||||
inPlw = true
|
||||
end
|
||||
if event and (not inPlw or not blacklist[event]) then
|
||||
self:TriggerEvent(event, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9)
|
||||
end
|
||||
end)
|
||||
if self.delayRegistry then
|
||||
delayRegistry = self.delayRegistry
|
||||
self.frame:SetScript("OnUpdate", OnUpdate)
|
||||
end
|
||||
|
||||
self:UnregisterAllEvents()
|
||||
self:CancelAllScheduledEvents()
|
||||
|
||||
registeringFromAceEvent = true
|
||||
self:RegisterEvent("LOOT_OPENED", function()
|
||||
SendAddonMessage("LOOT_OPENED", "", "RAID")
|
||||
end)
|
||||
registeringFromAceEvent = nil
|
||||
|
||||
if not self.playerLogin then
|
||||
registeringFromAceEvent = true
|
||||
self:RegisterEvent("PLAYER_LOGIN", function()
|
||||
self.playerLogin = true
|
||||
end, true)
|
||||
registeringFromAceEvent = nil
|
||||
end
|
||||
|
||||
if not self.postInit then
|
||||
local isReload = true
|
||||
local function func()
|
||||
self.postInit = true
|
||||
self:TriggerEvent("AceEvent_FullyInitialized")
|
||||
if self.registry["CHAT_MSG_CHANNEL_NOTICE"] and self.registry["CHAT_MSG_CHANNEL_NOTICE"][self] then
|
||||
self:UnregisterEvent("CHAT_MSG_CHANNEL_NOTICE")
|
||||
end
|
||||
if self.registry["MEETINGSTONE_CHANGED"] and self.registry["MEETINGSTONE_CHANGED"][self] then
|
||||
self:UnregisterEvent("MEETINGSTONE_CHANGED")
|
||||
end
|
||||
if self.registry["MINIMAP_ZONE_CHANGED"] and self.registry["MINIMAP_ZONE_CHANGED"][self] then
|
||||
self:UnregisterEvent("MINIMAP_ZONE_CHANGED")
|
||||
end
|
||||
if self.registry["LANGUAGE_LIST_CHANGED"] and self.registry["LANGUAGE_LIST_CHANGED"][self] then
|
||||
self:UnregisterEvent("LANGUAGE_LIST_CHANGED")
|
||||
end
|
||||
end
|
||||
registeringFromAceEvent = true
|
||||
local f = function()
|
||||
self.playerLogin = true
|
||||
self:ScheduleEvent("AceEvent_FullyInitialized", func, 1)
|
||||
end
|
||||
self:RegisterEvent("MEETINGSTONE_CHANGED", f, true)
|
||||
self:RegisterEvent("CHAT_MSG_CHANNEL_NOTICE", function()
|
||||
self:ScheduleEvent("AceEvent_FullyInitialized", func, 0.05)
|
||||
end)
|
||||
self:RegisterEvent("LANGUAGE_LIST_CHANGED", function()
|
||||
if self.registry["MEETINGSTONE_CHANGED"] and self.registry["MEETINGSTONE_CHANGED"][self] then
|
||||
self:UnregisterEvent("MEETINGSTONE_CHANGED")
|
||||
self:RegisterEvent("MINIMAP_ZONE_CHANGED", f, true)
|
||||
end
|
||||
end)
|
||||
registeringFromAceEvent = nil
|
||||
end
|
||||
|
||||
self.super.activate(self, oldLib, oldDeactivate)
|
||||
if oldLib then
|
||||
oldDeactivate(oldLib)
|
||||
end
|
||||
end
|
||||
|
||||
AceLibrary:Register(AceEvent, MAJOR_VERSION, MINOR_VERSION, AceEvent.activate)
|
||||
AceEvent = AceLibrary(MAJOR_VERSION)
|
||||
@@ -0,0 +1,561 @@
|
||||
--[[
|
||||
Name: AceHook-2.0
|
||||
Revision: $Rev: 10447 $
|
||||
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/AceHook-2.0
|
||||
SVN: http://svn.wowace.com/root/trunk/Ace2/AceHook-2.0
|
||||
Description: Mixin to allow for safe hooking of functions, methods, and scripts.
|
||||
Dependencies: AceLibrary, AceOO-2.0
|
||||
]]
|
||||
|
||||
local MAJOR_VERSION = "AceHook-2.0"
|
||||
local MINOR_VERSION = "$Revision: 10447 $"
|
||||
|
||||
-- This ensures the code is only executed if the libary doesn't already exist, or is a newer version
|
||||
if not AceLibrary then error(MAJOR_VERSION .. " requires AceLibrary.") end
|
||||
if not AceLibrary:IsNewVersion(MAJOR_VERSION, MINOR_VERSION) then return end
|
||||
|
||||
if not AceLibrary:HasInstance("AceOO-2.0") then error(MAJOR_VERSION .. " requires AceOO-2.0") end
|
||||
|
||||
--[[---------------------------------------------------------------------------------
|
||||
Create the library object
|
||||
----------------------------------------------------------------------------------]]
|
||||
|
||||
local AceOO = AceLibrary:GetInstance("AceOO-2.0")
|
||||
local AceHook = AceOO.Mixin {
|
||||
"Hook",
|
||||
"Unhook",
|
||||
"UnhookAll",
|
||||
"HookReport",
|
||||
"IsHooked",
|
||||
"HookScript",
|
||||
}
|
||||
|
||||
--[[---------------------------------------------------------------------------------
|
||||
Library Definitions
|
||||
----------------------------------------------------------------------------------]]
|
||||
|
||||
local protFuncs = {
|
||||
CameraOrSelectOrMoveStart = true, CameraOrSelectOrMoveStop = true,
|
||||
TurnOrActionStart = true, TurnOrActionStop = true,
|
||||
PitchUpStart = true, PitchUpStop = true,
|
||||
PitchDownStart = true, PitchDownStop = true,
|
||||
MoveBackwardStart = true, MoveBackwardStop = true,
|
||||
MoveForwardStart = true, MoveForwardStop = true,
|
||||
Jump = true, StrafeLeftStart = true,
|
||||
StrafeLeftStop = true, StrafeRightStart = true,
|
||||
StrafeRightStop = true, ToggleMouseMove = true,
|
||||
ToggleRun = true, TurnLeftStart = true,
|
||||
TurnLeftStop = true, TurnRightStart = true,
|
||||
TurnRightStop = true,
|
||||
}
|
||||
|
||||
local _G = getfenv(0)
|
||||
|
||||
local handlers, funcs, scripts, actives
|
||||
|
||||
--[[---------------------------------------------------------------------------------
|
||||
Private definitions (Not exposed)
|
||||
----------------------------------------------------------------------------------]]
|
||||
|
||||
--[[----------------------------------------------------------------------
|
||||
_debug - Internal Method
|
||||
-------------------------------------------------------------------------]]
|
||||
local function print(text)
|
||||
DEFAULT_CHAT_FRAME:AddMessage(text)
|
||||
end
|
||||
|
||||
local function _debug(self, msg)
|
||||
local name = self.hooks.name
|
||||
if name then
|
||||
print(string.format("[%s]: %s", name, msg))
|
||||
else
|
||||
print(msg)
|
||||
end
|
||||
end
|
||||
|
||||
local new, del
|
||||
do
|
||||
local list = setmetatable({}, {__mode = "k"})
|
||||
function new()
|
||||
local t = next(list)
|
||||
if not t then
|
||||
return {}
|
||||
end
|
||||
list[t] = nil
|
||||
return t
|
||||
end
|
||||
|
||||
function del(t)
|
||||
setmetatable(t, nil)
|
||||
table.setn(t, 0)
|
||||
for k in pairs(t) do
|
||||
t[k] = nil
|
||||
end
|
||||
list[t] = true
|
||||
end
|
||||
end
|
||||
|
||||
local origMetatable = {
|
||||
__call = function(self, a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15,a16,a17,a18,a19,a20)
|
||||
return self.orig(a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15,a16,a17,a18,a19,a20)
|
||||
end
|
||||
}
|
||||
|
||||
--[[----------------------------------------------------------------------
|
||||
AceHook:_getFunctionHook- internal method
|
||||
-------------------------------------------------------------------------]]
|
||||
|
||||
local function _getFunctionHook(self, func, handler, orig)
|
||||
if type(handler) == "string" then
|
||||
-- The handler is a method, need to self it
|
||||
return function(a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15,a16,a17,a18,a19,a20)
|
||||
if actives[orig] then
|
||||
return self[handler](self, a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15,a16,a17,a18,a19,a20)
|
||||
else
|
||||
return orig(a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15,a16,a17,a18,a19,a20)
|
||||
end
|
||||
end
|
||||
else
|
||||
-- The handler is a function, just call it
|
||||
return function(a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15,a16,a17,a18,a19,a20)
|
||||
if actives[orig] then
|
||||
return handler(a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15,a16,a17,a18,a19,a20)
|
||||
else
|
||||
return orig(a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15,a16,a17,a18,a19,a20)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--[[----------------------------------------------------------------------
|
||||
AceHook:_getMethodHook - Internal Method
|
||||
-------------------------------------------------------------------------]]
|
||||
local function _getMethodHook(self, object, method, handler, orig, script)
|
||||
if type(handler) == "string" then
|
||||
-- The handler is a method, need to self it
|
||||
if script then
|
||||
return function()
|
||||
if actives[orig] then
|
||||
return self[handler](self, object)
|
||||
else
|
||||
return orig()
|
||||
end
|
||||
end
|
||||
else
|
||||
return function(obj,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15,a16,a17,a18,a19,a20)
|
||||
if actives[orig] then
|
||||
return self[handler](self, obj, a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15,a16,a17,a18,a19,a20)
|
||||
else
|
||||
return orig(obj, a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15,a16,a17,a18,a19,a20)
|
||||
end
|
||||
end
|
||||
end
|
||||
else
|
||||
-- The handler is a function, just call it
|
||||
if script then
|
||||
return function()
|
||||
if actives[orig] then
|
||||
return handler(object)
|
||||
else
|
||||
return orig()
|
||||
end
|
||||
end
|
||||
else
|
||||
return function(obj,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15,a16,a17,a18,a19,a20)
|
||||
if actives[orig] then
|
||||
return handler(obj,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15,a16,a17,a18,a19,a20)
|
||||
else
|
||||
return orig(obj, a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15,a16,a17,a18,a19,a20)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--[[----------------------------------------------------------------------
|
||||
AceHook:HookFunc - internal method.
|
||||
o You can only hook each function once from each source.
|
||||
o If there is an inactive hook for this func/handler pair, we reactivate it
|
||||
o If there is an inactive hook for another handler, we error out.
|
||||
o Looks for handler as a method of the calling class, error if not available
|
||||
o If handler is a function, it just uses it directly through the wrapper
|
||||
-------------------------------------------------------------------------]]
|
||||
local function _hookFunc(self, func, handler)
|
||||
local orig = _G[func]
|
||||
|
||||
if not orig or type(orig) ~= "function" then
|
||||
_debug(self, string.format("Attempt to hook a non-existant function %q", func),3)
|
||||
return
|
||||
end
|
||||
|
||||
if not handler then handler = func end
|
||||
|
||||
if self.hooks[func] then
|
||||
local orig = self.hooks[func].orig
|
||||
-- We have an active hook from this source. Don't multi-hook
|
||||
if actives[orig] then
|
||||
_debug(self, string.format("%q already has an active hook from this source.", func))
|
||||
return
|
||||
end
|
||||
-- The hook is inactive, so reactivate it
|
||||
if handlers[orig] == handler then
|
||||
actives[orig] = true
|
||||
return
|
||||
else
|
||||
AceHook:error("There is a stale hook for %q can't hook or reactivate.", func)
|
||||
end
|
||||
end
|
||||
|
||||
if type(handler) == "string" then
|
||||
if type(self[handler]) ~= "function" then
|
||||
AceHook:error("Could not find the the handler %q when hooking function %q", handler, func)
|
||||
end
|
||||
elseif type(handler) ~= "function" then
|
||||
AceHook:error("Could not find the handler you supplied when hooking %q", func)
|
||||
end
|
||||
|
||||
local t = setmetatable(new(), origMetatable)
|
||||
self.hooks[func] = t
|
||||
t.orig = orig
|
||||
|
||||
actives[orig] = true
|
||||
handlers[orig] = handler
|
||||
local newFunc = _getFunctionHook(self, func, handler, orig)
|
||||
funcs[orig] = newFunc
|
||||
|
||||
_G[func] = newFunc
|
||||
end
|
||||
|
||||
--[[----------------------------------------------------------------------
|
||||
AceHook:UnhookFunc - internal method
|
||||
o If you attempt to unhook a function that has never been hooked, or to unhook in a
|
||||
system that has never had a hook before, the system will error with a stack trace
|
||||
o If we own the global function, then put the original back in its place and remove
|
||||
all references to the Hooks[func] structure.
|
||||
o If we don't own the global function (we've been hooked) we deactivate the hook,
|
||||
forcing the handler to passthrough.
|
||||
-------------------------------------------------------------------------]]
|
||||
local function _unhookFunc(self, func)
|
||||
if not self.hooks[func] or not funcs[self.hooks[func].orig] then
|
||||
_debug(self, string.format("Tried to unhook %q which is not currently hooked.", func))
|
||||
return
|
||||
end
|
||||
|
||||
local orig = self.hooks[func].orig
|
||||
|
||||
if actives[orig] then
|
||||
-- See if we own the global function
|
||||
if _G[func] == funcs[orig] then
|
||||
_G[func] = orig
|
||||
self.hooks[func] = del(self.hooks[func])
|
||||
handlers[orig] = nil
|
||||
funcs[orig] = nil
|
||||
scripts[orig] = nil
|
||||
actives[orig] = nil
|
||||
-- Magically all-done
|
||||
else
|
||||
actives[orig] = nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--[[----------------------------------------------------------------------
|
||||
AceHook:HookMeth - Takes an optional fourth argument
|
||||
o script - Signifies whether this is a script hook or not
|
||||
-------------------------------------------------------------------------]]
|
||||
|
||||
local function _hookMeth(self, obj, method, handler, script)
|
||||
if not handler then handler = method end
|
||||
if (not obj or type(obj) ~= "table") then
|
||||
AceHook:error("The object you supplied could not be found, or isn't a table.")
|
||||
end
|
||||
|
||||
if self.hooks[obj] and self.hooks[obj][method] then
|
||||
local orig = self.hooks[obj][method].orig
|
||||
-- We have an active hook from this source. Don't multi-hook
|
||||
if actives[orig] then
|
||||
_debug(self, string.format("%q already has an active hook from this source.", method))
|
||||
return
|
||||
end
|
||||
-- The hook is inactive, so reactivate it.
|
||||
if handlers[orig] == handler then
|
||||
actives[orig] = true
|
||||
return
|
||||
else
|
||||
AceHook:error("There is a stale hook for %q can't hook or reactivate.", method)
|
||||
end
|
||||
end
|
||||
-- We're clear to try the hook, let's make some checks first
|
||||
if type(handler) == "string" then
|
||||
if type(self[handler]) ~= "function" then
|
||||
AceHook:error("Could not find the handler %q you supplied when hooking method %q", handler, method)
|
||||
end
|
||||
elseif type(handler) ~= "function" then
|
||||
AceHook:error("Could not find the handler you supplied when hooking method %q", method)
|
||||
end
|
||||
-- Handler has been found, so now try to find the method we're trying to hook
|
||||
local orig
|
||||
-- Script
|
||||
if script then
|
||||
if not obj.GetScript then
|
||||
AceHook:error("The object you supplied does not have a GetScript method.")
|
||||
end
|
||||
if not obj:HasScript(method) then
|
||||
AceHook:error("The object you supplied doesn't allow the %q method.", method)
|
||||
end
|
||||
-- Sometimes there is not a original function for a script.
|
||||
orig = obj:GetScript(method)
|
||||
if not orig then
|
||||
orig = function() end
|
||||
end
|
||||
-- Method
|
||||
else
|
||||
orig = obj[method]
|
||||
end
|
||||
if not orig then
|
||||
AceHook:error("Could not find the method or script %q you are trying to hook.", method)
|
||||
end
|
||||
if not self.hooks[obj] then
|
||||
self.hooks[obj] = new()
|
||||
end
|
||||
local t = setmetatable(new(), origMetatable)
|
||||
self.hooks[obj][method] = t
|
||||
t.orig = orig
|
||||
|
||||
actives[orig] = true
|
||||
handlers[orig] = handler
|
||||
scripts[orig] = script and true or nil
|
||||
local newFunc = _getMethodHook(self, obj, method, handler, orig, script)
|
||||
funcs[orig] = newFunc
|
||||
|
||||
if script then
|
||||
obj:SetScript(method, newFunc)
|
||||
else
|
||||
obj[method] = newFunc
|
||||
end
|
||||
end
|
||||
|
||||
--[[----------------------------------------------------------------------
|
||||
AceHook:UnhookMeth - Internal method
|
||||
o If you attempt to unhook a method that has never been hooked, or to unhook in a
|
||||
system that has never had a hook before, the system will error with a stack trace
|
||||
o If we own the global method, then put the original back in its place and remove
|
||||
all references to the Hooks[obj][method] structure.
|
||||
o If we don't own the global method (we've been hooked) we deactivate the hook,
|
||||
forcing the handler to passthrough.
|
||||
-------------------------------------------------------------------------]]
|
||||
local function _unhookMeth(self, obj, method)
|
||||
if not self.hooks[obj] or not self.hooks[obj][method] or not funcs[self.hooks[obj][method].orig] then
|
||||
_debug(self, string.format("Attempt to unhook a method %q that is not currently hooked.", method))
|
||||
return
|
||||
end
|
||||
|
||||
local orig = self.hooks[obj][method].orig
|
||||
|
||||
if actives[orig] then
|
||||
-- If this is a script
|
||||
if scripts[orig] then
|
||||
if obj:GetScript(method) == funcs[orig] then
|
||||
-- We own the script. Kill it.
|
||||
obj:SetScript(method, orig)
|
||||
self.hooks[obj][method] = del(self.hooks[obj][method])
|
||||
handlers[orig] = nil
|
||||
funcs[orig] = nil
|
||||
scripts[orig] = nil
|
||||
actives[orig] = nil
|
||||
else
|
||||
actives[orig] = nil
|
||||
end
|
||||
else
|
||||
if obj[method] == funcs[orig] then
|
||||
-- We own the method. Kill it.
|
||||
obj[method] = orig
|
||||
self.hooks[obj][method] = del(self.hooks[obj][method])
|
||||
handlers[orig] = nil
|
||||
funcs[orig] = nil
|
||||
scripts[orig] = nil
|
||||
actives[orig] = nil
|
||||
else
|
||||
actives[orig] = nil
|
||||
end
|
||||
end
|
||||
end
|
||||
if not next(self.hooks[obj]) then
|
||||
-- Spank the table
|
||||
self.hooks[obj] = del(self.hooks[obj])
|
||||
end
|
||||
end
|
||||
|
||||
function AceHook:OnInstanceInit(object)
|
||||
if not object.hooks then
|
||||
object.hooks = new()
|
||||
end
|
||||
|
||||
local name
|
||||
|
||||
if type(rawget(object, 'GetLibraryVersion')) == "function" then
|
||||
name = object:GetLibraryVersion()
|
||||
end
|
||||
if not name and type(object.GetName) == "function" then
|
||||
name = object:GetName()
|
||||
end
|
||||
if not name and type(object.name) == "string" then
|
||||
name = object.name
|
||||
end
|
||||
if not name then
|
||||
for k,v in pairs(_G) do
|
||||
if v == object then
|
||||
name = tostring(k)
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
object.hooks.name = name
|
||||
end
|
||||
|
||||
AceHook.OnManualEmbed = AceHook.OnInstanceInit
|
||||
|
||||
--[[----------------------------------------------------------------------
|
||||
AceHook:Hook
|
||||
self:Hook("functionName", ["handlerName" | handler])
|
||||
self:Hook(ObjectName, "Method", ["Handler" | handler])
|
||||
-------------------------------------------------------------------------]]
|
||||
function AceHook:Hook(arg1, arg2, arg3)
|
||||
if type(arg1)== "string" then
|
||||
if protFuncs[arg1] then
|
||||
if self.hooks.name then
|
||||
AceHook:error("%s tried to hook %q, which is a Blizzard protected function.", self.hooks.name, arg1)
|
||||
else
|
||||
_debug(self, string.format("An Addon tried to hook %q, which is a Blizzard protected function.", arg1))
|
||||
end
|
||||
else
|
||||
_hookFunc(self, arg1, arg2)
|
||||
end
|
||||
else
|
||||
_hookMeth(self, arg1, arg2, arg3)
|
||||
end
|
||||
end
|
||||
|
||||
function AceHook:HookScript(arg1, arg2, arg3)
|
||||
_hookMeth(self, arg1, arg2, arg3, true)
|
||||
end
|
||||
|
||||
--[[----------------------------------------------------------------------
|
||||
AceHook:IsHooked()
|
||||
self:Hook("functionName")
|
||||
self:Hook(ObjectName, "Method")
|
||||
|
||||
Returns whether or not the given function is hooked in the current
|
||||
namespace. A hooked, but inactive function is considered NOT
|
||||
hooked in this context.
|
||||
-------------------------------------------------------------------------]]
|
||||
function AceHook:IsHooked(obj, method)
|
||||
if method and obj then
|
||||
if self.hooks and self.hooks[obj] and self.hooks[obj][method] and actives[self.hooks[obj][method].orig] then
|
||||
return true, handlers[self.hooks[obj][method].orig]
|
||||
end
|
||||
else
|
||||
if self.hooks and self.hooks[obj] and actives[self.hooks[obj].orig] then
|
||||
return true, handlers[self.hooks[obj].orig]
|
||||
end
|
||||
end
|
||||
|
||||
return false, nil
|
||||
end
|
||||
|
||||
--[[----------------------------------------------------------------------
|
||||
AceHook:Unhook
|
||||
self:Unhook("functionName")
|
||||
self:Unhook(ObjectName, "Method")
|
||||
-------------------------------------------------------------------------]]
|
||||
function AceHook:Unhook(arg1, arg2)
|
||||
if type(arg1) == "string" then
|
||||
_unhookFunc(self, arg1)
|
||||
else
|
||||
_unhookMeth(self, arg1, arg2)
|
||||
end
|
||||
end
|
||||
|
||||
--[[----------------------------------------------------------------------
|
||||
AceHook:UnhookAll - Unhooks all active hooks from the calling source
|
||||
-------------------------------------------------------------------------]]
|
||||
function AceHook:UnhookAll()
|
||||
for key, value in pairs(self.hooks) do
|
||||
if type(key) == "table" then
|
||||
for method in pairs(value) do
|
||||
self:Unhook(key, method)
|
||||
end
|
||||
else
|
||||
self:Unhook(key)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function AceHook:OnEmbedDisable(target)
|
||||
self.UnhookAll(target)
|
||||
end
|
||||
|
||||
--[[----------------------------------------------------------------------
|
||||
AceHook:HookReport - Lists registered hooks from this source
|
||||
-------------------------------------------------------------------------]]
|
||||
|
||||
function AceHook:HookReport()
|
||||
_debug(self, "This is a list of all active hooks for this object:")
|
||||
if not self.hooks then _debug(self, "No registered hooks.") return end
|
||||
|
||||
for key, value in pairs(self.hooks) do
|
||||
if type(value) == "table" then
|
||||
for method in pairs(value) do
|
||||
_debug(self, string.format("key: %s method: %q |cff%s|r", tostring(key), method, self.hooks[key][method].active and "00ff00Active" or "ffff00Inactive"))
|
||||
end
|
||||
else
|
||||
_debug(self, string.format("key: %s value: %q |cff%s|r", tostring(key), tostring(value), self.hooks[key].active and "00ff00Active" or "ffff00Inactive"))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--[[---------------------------------------------------------------------------------
|
||||
Stub and Library registration
|
||||
----------------------------------------------------------------------------------]]
|
||||
|
||||
local function activate(self, oldLib, oldDeactivate)
|
||||
AceHook = self
|
||||
|
||||
AceHook.super.activate(self, oldLib, oldDeactivate)
|
||||
|
||||
if oldLib then
|
||||
self.handlers = oldLib.handlers
|
||||
self.funcs = oldLib.funcs
|
||||
self.scripts = oldLib.scripts
|
||||
self.actives = oldLib.actives
|
||||
end
|
||||
|
||||
if not self.handlers then
|
||||
self.handlers = {}
|
||||
end
|
||||
if not self.funcs then
|
||||
self.funcs = {}
|
||||
end
|
||||
if not self.scripts then
|
||||
self.scripts = {}
|
||||
end
|
||||
if not self.actives then
|
||||
self.actives = {}
|
||||
end
|
||||
|
||||
handlers = self.handlers
|
||||
funcs = self.funcs
|
||||
scripts = self.scripts
|
||||
actives = self.actives
|
||||
|
||||
if oldDeactivate then
|
||||
oldDeactivate(oldLib)
|
||||
end
|
||||
end
|
||||
|
||||
AceLibrary:Register(AceHook, MAJOR_VERSION, MINOR_VERSION, activate)
|
||||
@@ -0,0 +1,751 @@
|
||||
--[[
|
||||
Name: AceLibrary
|
||||
Revision: $Rev: 14130 $
|
||||
Developed by: The Ace Development Team (http://www.wowace.com/index.php/The_Ace_Development_Team)
|
||||
Inspired By: Iriel (iriel@vigilance-committee.org)
|
||||
Tekkub (tekkub@gmail.com)
|
||||
Revision: $Rev: 14130 $
|
||||
Website: http://www.wowace.com/
|
||||
Documentation: http://www.wowace.com/index.php/AceLibrary
|
||||
SVN: http://svn.wowace.com/root/trunk/Ace2/AceLibrary
|
||||
Description: Versioning library to handle other library instances, upgrading,
|
||||
and proper access.
|
||||
It also provides a base for libraries to work off of, providing
|
||||
proper error tools. It is handy because all the errors occur in the
|
||||
file that called it, not in the library file itself.
|
||||
Dependencies: None
|
||||
]]
|
||||
|
||||
local ACELIBRARY_MAJOR = "AceLibrary"
|
||||
local ACELIBRARY_MINOR = "$Revision: 14130 $"
|
||||
|
||||
local table_setn
|
||||
do
|
||||
local version = GetBuildInfo()
|
||||
if string.find(version, "^2%.") then
|
||||
-- 2.0.0
|
||||
table_setn = function() end
|
||||
else
|
||||
table_setn = table.setn
|
||||
end
|
||||
end
|
||||
|
||||
local string_gfind = string.gmatch or string.gfind
|
||||
|
||||
local _G = getfenv(0)
|
||||
local previous = _G[ACELIBRARY_MAJOR]
|
||||
if previous and not previous:IsNewVersion(ACELIBRARY_MAJOR, ACELIBRARY_MINOR) then return end
|
||||
|
||||
-- @table AceLibrary
|
||||
-- @brief System to handle all versioning of libraries.
|
||||
local AceLibrary = {}
|
||||
local AceLibrary_mt = {}
|
||||
setmetatable(AceLibrary, AceLibrary_mt)
|
||||
|
||||
local tmp
|
||||
local function error(self, message, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20)
|
||||
if type(self) ~= "table" then
|
||||
_G.error(string.format("Bad argument #1 to `error' (table expected, got %s)", type(self)), 2)
|
||||
end
|
||||
if not tmp then
|
||||
tmp = {}
|
||||
else
|
||||
for k in pairs(tmp) do tmp[k] = nil end
|
||||
table_setn(tmp, 0)
|
||||
end
|
||||
|
||||
table.insert(tmp, a1)
|
||||
table.insert(tmp, a2)
|
||||
table.insert(tmp, a3)
|
||||
table.insert(tmp, a4)
|
||||
table.insert(tmp, a5)
|
||||
table.insert(tmp, a6)
|
||||
table.insert(tmp, a7)
|
||||
table.insert(tmp, a8)
|
||||
table.insert(tmp, a9)
|
||||
table.insert(tmp, a10)
|
||||
table.insert(tmp, a11)
|
||||
table.insert(tmp, a12)
|
||||
table.insert(tmp, a13)
|
||||
table.insert(tmp, a14)
|
||||
table.insert(tmp, a15)
|
||||
table.insert(tmp, a16)
|
||||
table.insert(tmp, a17)
|
||||
table.insert(tmp, a18)
|
||||
table.insert(tmp, a19)
|
||||
table.insert(tmp, a20)
|
||||
|
||||
local stack = debugstack()
|
||||
if not message then
|
||||
local _,_,second = string.find(stack, "\n(.-)\n")
|
||||
message = "error raised! " .. second
|
||||
else
|
||||
for i = 1,table.getn(tmp) do
|
||||
tmp[i] = tostring(tmp[i])
|
||||
end
|
||||
for i = 1,10 do
|
||||
table.insert(tmp, "nil")
|
||||
end
|
||||
message = string.format(message, unpack(tmp))
|
||||
end
|
||||
|
||||
if getmetatable(self) and getmetatable(self).__tostring then
|
||||
message = string.format("%s: %s", tostring(self), message)
|
||||
elseif type(rawget(self, 'GetLibraryVersion')) == "function" and AceLibrary:HasInstance(self:GetLibraryVersion()) then
|
||||
message = string.format("%s: %s", self:GetLibraryVersion(), message)
|
||||
elseif type(rawget(self, 'class')) == "table" and type(rawget(self.class, 'GetLibraryVersion')) == "function" and AceLibrary:HasInstance(self.class:GetLibraryVersion()) then
|
||||
message = string.format("%s: %s", self.class:GetLibraryVersion(), message)
|
||||
end
|
||||
|
||||
local first = string.gsub(stack, "\n.*", "")
|
||||
local file = string.gsub(first, ".*\\(.*).lua:%d+: .*", "%1")
|
||||
file = string.gsub(file, "([%(%)%.%*%+%-%[%]%?%^%$%%])", "%%%1")
|
||||
|
||||
local i = 0
|
||||
for s in string_gfind(stack, "\n([^\n]*)") do
|
||||
i = i + 1
|
||||
if not string.find(s, file .. "%.lua:%d+:") then
|
||||
file = string.gsub(s, "^.*\\(.*).lua:%d+: .*", "%1")
|
||||
file = string.gsub(file, "([%(%)%.%*%+%-%[%]%?%^%$%%])", "%%%1")
|
||||
break
|
||||
end
|
||||
end
|
||||
local j = 0
|
||||
for s in string_gfind(stack, "\n([^\n]*)") do
|
||||
j = j + 1
|
||||
if j > i and not string.find(s, file .. "%.lua:%d+:") then
|
||||
_G.error(message, j + 1)
|
||||
return
|
||||
end
|
||||
end
|
||||
_G.error(message, 2)
|
||||
return
|
||||
end
|
||||
|
||||
local function assert(self, condition, message, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20)
|
||||
if not condition then
|
||||
if not message then
|
||||
local stack = debugstack()
|
||||
local _,_,second = string.find(stack, "\n(.-)\n")
|
||||
message = "assertion failed! " .. second
|
||||
end
|
||||
error(self, message, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20)
|
||||
return
|
||||
end
|
||||
return condition
|
||||
end
|
||||
|
||||
local function argCheck(self, arg, num, kind, kind2, kind3, kind4, kind5)
|
||||
if type(num) ~= "number" then
|
||||
error(self, "Bad argument #3 to `argCheck' (number expected, got %s)", type(num))
|
||||
elseif type(kind) ~= "string" then
|
||||
error(self, "Bad argument #4 to `argCheck' (string expected, got %s)", type(kind))
|
||||
end
|
||||
local errored = false
|
||||
arg = type(arg)
|
||||
if arg ~= kind and arg ~= kind2 and arg ~= kind3 and arg ~= kind4 and arg ~= kind5 then
|
||||
local _,_,func = string.find(debugstack(), "`argCheck'.-([`<].-['>])")
|
||||
if not func then
|
||||
_,_,func = string.find(debugstack(), "([`<].-['>])")
|
||||
end
|
||||
if kind5 then
|
||||
error(self, "Bad argument #%s to %s (%s, %s, %s, %s, or %s expected, got %s)", tonumber(num) or 0/0, func, kind, kind2, kind3, kind4, kind5, arg)
|
||||
elseif kind4 then
|
||||
error(self, "Bad argument #%s to %s (%s, %s, %s, or %s expected, got %s)", tonumber(num) or 0/0, func, kind, kind2, kind3, kind4, arg)
|
||||
elseif kind3 then
|
||||
error(self, "Bad argument #%s to %s (%s, %s, or %s expected, got %s)", tonumber(num) or 0/0, func, kind, kind2, kind3, arg)
|
||||
elseif kind2 then
|
||||
error(self, "Bad argument #%s to %s (%s or %s expected, got %s)", tonumber(num) or 0/0, func, kind, kind2, arg)
|
||||
else
|
||||
error(self, "Bad argument #%s to %s (%s expected, got %s)", tonumber(num) or 0/0, func, kind, arg)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function pcall(self, func, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20)
|
||||
a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20 = _G.pcall(func, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20)
|
||||
if not a1 then
|
||||
error(self, string.gsub(a2, ".-%.lua:%d-: ", ""))
|
||||
else
|
||||
return a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20
|
||||
end
|
||||
end
|
||||
|
||||
local recurse = {}
|
||||
local function addToPositions(t, major)
|
||||
if not AceLibrary.positions[t] or AceLibrary.positions[t] == major then
|
||||
rawset(t, recurse, true)
|
||||
AceLibrary.positions[t] = major
|
||||
for k,v in pairs(t) do
|
||||
if type(v) == "table" and not rawget(v, recurse) then
|
||||
addToPositions(v, major)
|
||||
end
|
||||
if type(k) == "table" and not rawget(k, recurse) then
|
||||
addToPositions(k, major)
|
||||
end
|
||||
end
|
||||
local mt = getmetatable(t)
|
||||
if mt and not rawget(mt, recurse) then
|
||||
addToPositions(mt, major)
|
||||
end
|
||||
rawset(t, recurse, nil)
|
||||
end
|
||||
end
|
||||
|
||||
local function svnRevisionToNumber(text)
|
||||
if type(text) == "string" then
|
||||
if string.find(text, "^%$Revision: (%d+) %$$") then
|
||||
return tonumber((string.gsub(text, "^%$Revision: (%d+) %$$", "%1")))
|
||||
elseif string.find(text, "^%$Rev: (%d+) %$$") then
|
||||
return tonumber((string.gsub(text, "^%$Rev: (%d+) %$$", "%1")))
|
||||
elseif string.find(text, "^%$LastChangedRevision: (%d+) %$$") then
|
||||
return tonumber((string.gsub(text, "^%$LastChangedRevision: (%d+) %$$", "%1")))
|
||||
end
|
||||
elseif type(text) == "number" then
|
||||
return text
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
local crawlReplace
|
||||
do
|
||||
local recurse = {}
|
||||
local function func(t, to, from)
|
||||
if recurse[t] then
|
||||
return
|
||||
end
|
||||
recurse[t] = true
|
||||
local mt = getmetatable(t)
|
||||
setmetatable(t, nil)
|
||||
rawset(t, to, rawget(t, from))
|
||||
rawset(t, from, nil)
|
||||
for k,v in pairs(t) do
|
||||
if v == from then
|
||||
t[k] = to
|
||||
elseif type(v) == "table" then
|
||||
if not recurse[v] then
|
||||
func(v, to, from)
|
||||
end
|
||||
end
|
||||
|
||||
if type(k) == "table" then
|
||||
if not recurse[k] then
|
||||
func(k, to, from)
|
||||
end
|
||||
end
|
||||
end
|
||||
setmetatable(t, mt)
|
||||
if mt then
|
||||
if mt == from then
|
||||
setmetatable(t, to)
|
||||
elseif not recurse[mt] then
|
||||
func(mt, to, from)
|
||||
end
|
||||
end
|
||||
end
|
||||
function crawlReplace(t, to, from)
|
||||
func(t, to, from)
|
||||
for k in pairs(recurse) do
|
||||
recurse[k] = nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- @function destroyTable
|
||||
-- @brief remove all the contents of a table
|
||||
-- @param t table to destroy
|
||||
local function destroyTable(t)
|
||||
setmetatable(t, nil)
|
||||
for k,v in pairs(t) do t[k] = nil end
|
||||
table_setn(t, 0)
|
||||
end
|
||||
|
||||
local function isFrame(frame)
|
||||
return type(frame) == "table" and type(rawget(frame, 0)) == "userdata" and type(rawget(frame, 'IsFrameType')) == "function" and getmetatable(frame) and type(rawget(getmetatable(frame), '__index')) == "function"
|
||||
end
|
||||
|
||||
local new, del
|
||||
do
|
||||
local tables = setmetatable({}, {__mode = "k"})
|
||||
|
||||
function new()
|
||||
local t = next(tables)
|
||||
if t then
|
||||
tables[t] = nil
|
||||
return t
|
||||
else
|
||||
return {}
|
||||
end
|
||||
end
|
||||
|
||||
function del(t, depth)
|
||||
if depth and depth > 0 then
|
||||
for k,v in pairs(t) do
|
||||
if type(v) == "table" and not isFrame(v) then
|
||||
del(v, depth - 1)
|
||||
end
|
||||
end
|
||||
end
|
||||
destroyTable(t)
|
||||
tables[t] = true
|
||||
end
|
||||
end
|
||||
|
||||
-- @function copyTable
|
||||
-- @brief Create a shallow copy of a table and return it.
|
||||
-- @param from The table to copy from
|
||||
-- @return A shallow copy of the table
|
||||
local function copyTable(from)
|
||||
local to = new()
|
||||
for k,v in pairs(from) do to[k] = v end
|
||||
table_setn(to, table.getn(from))
|
||||
setmetatable(to, getmetatable(from))
|
||||
return to
|
||||
end
|
||||
|
||||
-- @function deepTransfer
|
||||
-- @brief Fully transfer all data, keeping proper previous table
|
||||
-- backreferences stable.
|
||||
-- @param to The table with which data is to be injected into
|
||||
-- @param from The table whose data will be injected into the first
|
||||
-- @param saveFields If available, a shallow copy of the basic data is saved
|
||||
-- in here.
|
||||
-- @param list The account of table references
|
||||
-- @param list2 The current status on which tables have been traversed.
|
||||
local deepTransfer
|
||||
do
|
||||
-- @function examine
|
||||
-- @brief Take account of all the table references to be shared
|
||||
-- between the to and from tables.
|
||||
-- @param to The table with which data is to be injected into
|
||||
-- @param from The table whose data will be injected into the first
|
||||
-- @param list An account of the table references
|
||||
local function examine(to, from, list, major)
|
||||
list[from] = to
|
||||
for k,v in pairs(from) do
|
||||
if rawget(to, k) and type(from[k]) == "table" and type(to[k]) == "table" and not list[from[k]] then
|
||||
if from[k] == to[k] then
|
||||
list[from[k]] = to[k]
|
||||
elseif AceLibrary.positions[from[v]] ~= major and AceLibrary.positions[from[v]] then
|
||||
list[from[k]] = from[k]
|
||||
elseif not list[from[k]] then
|
||||
examine(to[k], from[k], list, major)
|
||||
end
|
||||
end
|
||||
end
|
||||
return list
|
||||
end
|
||||
|
||||
function deepTransfer(to, from, saveFields, major, list, list2)
|
||||
setmetatable(to, nil)
|
||||
local createdList
|
||||
if not list then
|
||||
createdList = true
|
||||
list = new()
|
||||
list2 = new()
|
||||
examine(to, from, list, major)
|
||||
end
|
||||
list2[to] = to
|
||||
for k,v in pairs(to) do
|
||||
if type(rawget(from, k)) ~= "table" or type(v) ~= "table" or isFrame(v) then
|
||||
if saveFields then
|
||||
saveFields[k] = v
|
||||
end
|
||||
to[k] = nil
|
||||
elseif v ~= _G then
|
||||
if saveFields then
|
||||
saveFields[k] = copyTable(v)
|
||||
end
|
||||
end
|
||||
end
|
||||
for k in pairs(from) do
|
||||
if rawget(to, k) and to[k] ~= from[k] and AceLibrary.positions[to[k]] == major and from[k] ~= _G then
|
||||
if not list2[to[k]] then
|
||||
deepTransfer(to[k], from[k], nil, major, list, list2)
|
||||
end
|
||||
to[k] = list[to[k]] or list2[to[k]]
|
||||
else
|
||||
rawset(to, k, from[k])
|
||||
end
|
||||
end
|
||||
table_setn(to, table.getn(from))
|
||||
setmetatable(to, getmetatable(from))
|
||||
local mt = getmetatable(to)
|
||||
if mt then
|
||||
if list[mt] then
|
||||
setmetatable(to, list[mt])
|
||||
elseif mt.__index and list[mt.__index] then
|
||||
mt.__index = list[mt.__index]
|
||||
end
|
||||
end
|
||||
destroyTable(from)
|
||||
if createdList then
|
||||
del(list)
|
||||
del(list2)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- @method TryToLoadStandalone
|
||||
-- @brief Attempt to find and load a standalone version of the requested library
|
||||
-- @param major A string representing the major version
|
||||
-- @return If library is found, return values from the call to LoadAddOn are returned
|
||||
-- If the library has been requested previously, nil is returned.
|
||||
local function TryToLoadStandalone(major)
|
||||
if not AceLibrary.scannedlibs then AceLibrary.scannedlibs = {} end
|
||||
if AceLibrary.scannedlibs[major] then return end
|
||||
|
||||
AceLibrary.scannedlibs[major] = true
|
||||
|
||||
local name, _, _, enabled, loadable = GetAddOnInfo(major)
|
||||
if loadable then
|
||||
return LoadAddOn(name)
|
||||
end
|
||||
|
||||
for i=1,GetNumAddOns() do
|
||||
if GetAddOnMetadata(i, "X-AceLibrary-"..major) then
|
||||
local name, _, _, enabled, loadable = GetAddOnInfo(i)
|
||||
if loadable then
|
||||
return LoadAddOn(name)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- @method IsNewVersion
|
||||
-- @brief Obtain whether the supplied version would be an upgrade to the
|
||||
-- current version. This allows for bypass code in library
|
||||
-- declaration.
|
||||
-- @param major A string representing the major version
|
||||
-- @param minor An integer or an svn revision string representing the minor version
|
||||
-- @return whether the supplied version would be newer than what is
|
||||
-- currently available.
|
||||
function AceLibrary:IsNewVersion(major, minor)
|
||||
argCheck(self, major, 2, "string")
|
||||
TryToLoadStandalone(major)
|
||||
|
||||
if type(minor) == "string" then
|
||||
local m = svnRevisionToNumber(minor)
|
||||
if m then
|
||||
minor = m
|
||||
else
|
||||
_G.error(string.format("Bad argument #3 to `IsNewVersion'. Must be a number or SVN revision string. %q is not appropriate", minor), 2)
|
||||
end
|
||||
end
|
||||
argCheck(self, minor, 3, "number")
|
||||
local data = self.libs[major]
|
||||
if not data then
|
||||
return true
|
||||
end
|
||||
return data.minor < minor
|
||||
end
|
||||
|
||||
-- @method HasInstance
|
||||
-- @brief Returns whether an instance exists. This allows for optional support of a library.
|
||||
-- @param major A string representing the major version.
|
||||
-- @param minor (optional) An integer or an svn revision string representing the minor version.
|
||||
-- @return Whether an instance exists.
|
||||
function AceLibrary:HasInstance(major, minor)
|
||||
argCheck(self, major, 2, "string")
|
||||
TryToLoadStandalone(major)
|
||||
|
||||
if minor then
|
||||
if type(minor) == "string" then
|
||||
local m = svnRevisionToNumber(minor)
|
||||
if m then
|
||||
minor = m
|
||||
else
|
||||
_G.error(string.format("Bad argument #3 to `HasInstance'. Must be a number or SVN revision string. %q is not appropriate", minor), 2)
|
||||
end
|
||||
end
|
||||
argCheck(self, minor, 3, "number")
|
||||
if not self.libs[major] then
|
||||
return
|
||||
end
|
||||
return self.libs[major].minor == minor
|
||||
end
|
||||
return self.libs[major] and true
|
||||
end
|
||||
|
||||
-- @method GetInstance
|
||||
-- @brief Returns the library with the given major/minor version.
|
||||
-- @param major A string representing the major version.
|
||||
-- @param minor (optional) An integer or an svn revision string representing the minor version.
|
||||
-- @return The library with the given major/minor version.
|
||||
function AceLibrary:GetInstance(major, minor)
|
||||
argCheck(self, major, 2, "string")
|
||||
TryToLoadStandalone(major)
|
||||
|
||||
local data = self.libs[major]
|
||||
if not data then
|
||||
_G.error(string.format("Cannot find a library instance of %s.", major), 2)
|
||||
return
|
||||
end
|
||||
if minor then
|
||||
if type(minor) == "string" then
|
||||
local m = svnRevisionToNumber(minor)
|
||||
if m then
|
||||
minor = m
|
||||
else
|
||||
_G.error(string.format("Bad argument #3 to `GetInstance'. Must be a number or SVN revision string. %q is not appropriate", minor), 2)
|
||||
end
|
||||
end
|
||||
argCheck(self, minor, 2, "number")
|
||||
if data.minor ~= minor then
|
||||
_G.error(string.format("Cannot find a library instance of %s, minor version %d.", major, minor), 2)
|
||||
return
|
||||
end
|
||||
end
|
||||
return data.instance
|
||||
end
|
||||
|
||||
-- Syntax sugar. AceLibrary("FooBar-1.0")
|
||||
AceLibrary_mt.__call = AceLibrary.GetInstance
|
||||
|
||||
local donothing
|
||||
|
||||
local AceEvent
|
||||
|
||||
-- @method Register
|
||||
-- @brief Registers a new version of a given library.
|
||||
-- @param newInstance the library to register
|
||||
-- @param major the major version of the library
|
||||
-- @param minor the minor version of the library
|
||||
-- @param activateFunc (optional) A function to be called when the library is
|
||||
-- fully activated. Takes the arguments
|
||||
-- (newInstance [, oldInstance, oldDeactivateFunc]). If
|
||||
-- oldInstance is given, you should probably call
|
||||
-- oldDeactivateFunc(oldInstance).
|
||||
-- @param deactivateFunc (optional) A function to be called by a newer library's
|
||||
-- activateFunc.
|
||||
-- @param externalFunc (optional) A function to be called whenever a new
|
||||
-- library is registered.
|
||||
function AceLibrary:Register(newInstance, major, minor, activateFunc, deactivateFunc, externalFunc)
|
||||
argCheck(self, newInstance, 2, "table")
|
||||
argCheck(self, major, 3, "string")
|
||||
if type(minor) == "string" then
|
||||
local m = svnRevisionToNumber(minor)
|
||||
if m then
|
||||
minor = m
|
||||
else
|
||||
_G.error(string.format("Bad argument #4 to `Register'. Must be a number or SVN revision string. %q is not appropriate", minor), 2)
|
||||
end
|
||||
end
|
||||
argCheck(self, minor, 4, "number")
|
||||
if math.floor(minor) ~= minor or minor < 0 then
|
||||
error(self, "Bad argument #4 to `Register' (integer >= 0 expected, got %s)", minor)
|
||||
end
|
||||
argCheck(self, activateFunc, 5, "function", "nil")
|
||||
argCheck(self, deactivateFunc, 6, "function", "nil")
|
||||
argCheck(self, externalFunc, 7, "function", "nil")
|
||||
if not deactivateFunc then
|
||||
if not donothing then
|
||||
donothing = function() end
|
||||
end
|
||||
deactivateFunc = donothing
|
||||
end
|
||||
local data = self.libs[major]
|
||||
if not data then
|
||||
-- This is new
|
||||
local instance = copyTable(newInstance)
|
||||
crawlReplace(instance, instance, newInstance)
|
||||
destroyTable(newInstance)
|
||||
if AceLibrary == newInstance then
|
||||
self = instance
|
||||
AceLibrary = instance
|
||||
end
|
||||
self.libs[major] = {
|
||||
instance = instance,
|
||||
minor = minor,
|
||||
deactivateFunc = deactivateFunc,
|
||||
externalFunc = externalFunc,
|
||||
}
|
||||
rawset(instance, 'GetLibraryVersion', function(self)
|
||||
return major, minor
|
||||
end)
|
||||
if not rawget(instance, 'error') then
|
||||
rawset(instance, 'error', error)
|
||||
end
|
||||
if not rawget(instance, 'assert') then
|
||||
rawset(instance, 'assert', assert)
|
||||
end
|
||||
if not rawget(instance, 'argCheck') then
|
||||
rawset(instance, 'argCheck', argCheck)
|
||||
end
|
||||
if not rawget(instance, 'pcall') then
|
||||
rawset(instance, 'pcall', pcall)
|
||||
end
|
||||
addToPositions(instance, major)
|
||||
if activateFunc then
|
||||
activateFunc(instance, nil, nil) -- no old version, so explicit nil
|
||||
end
|
||||
|
||||
if externalFunc then
|
||||
for k,data in pairs(self.libs) do
|
||||
if k ~= major then
|
||||
externalFunc(instance, k, data.instance)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
for k,data in pairs(self.libs) do
|
||||
if k ~= major and data.externalFunc then
|
||||
data.externalFunc(data.instance, major, instance)
|
||||
end
|
||||
end
|
||||
if major == "AceEvent-2.0" then
|
||||
AceEvent = instance
|
||||
end
|
||||
if AceEvent then
|
||||
AceEvent.TriggerEvent(self, "AceLibrary_Register", major, instance)
|
||||
end
|
||||
|
||||
return instance
|
||||
end
|
||||
local instance = data.instance
|
||||
if minor <= data.minor then
|
||||
-- This one is already obsolete, raise an error.
|
||||
_G.error(string.format("Obsolete library registered. %s is already registered at version %d. You are trying to register version %d. Hint: if not AceLibrary:IsNewVersion(%q, %d) then return end", major, data.minor, minor, major, minor), 2)
|
||||
return
|
||||
end
|
||||
-- This is an update
|
||||
local oldInstance = new()
|
||||
|
||||
addToPositions(newInstance, major)
|
||||
local isAceLibrary = (AceLibrary == newInstance)
|
||||
local old_error, old_assert, old_argCheck, old_pcall
|
||||
if isAceLibrary then
|
||||
self = instance
|
||||
AceLibrary = instance
|
||||
|
||||
old_error = instance.error
|
||||
old_assert = instance.assert
|
||||
old_argCheck = instance.argCheck
|
||||
old_pcall = instance.pcall
|
||||
|
||||
self.error = error
|
||||
self.assert = assert
|
||||
self.argCheck = argCheck
|
||||
self.pcall = pcall
|
||||
end
|
||||
deepTransfer(instance, newInstance, oldInstance, major)
|
||||
crawlReplace(instance, instance, newInstance)
|
||||
local oldDeactivateFunc = data.deactivateFunc
|
||||
data.minor = minor
|
||||
data.deactivateFunc = deactivateFunc
|
||||
data.externalFunc = externalFunc
|
||||
rawset(instance, 'GetLibraryVersion', function(self)
|
||||
return major, minor
|
||||
end)
|
||||
if not rawget(instance, 'error') then
|
||||
rawset(instance, 'error', error)
|
||||
end
|
||||
if not rawget(instance, 'assert') then
|
||||
rawset(instance, 'assert', assert)
|
||||
end
|
||||
if not rawget(instance, 'argCheck') then
|
||||
rawset(instance, 'argCheck', argCheck)
|
||||
end
|
||||
if not rawget(instance, 'pcall') then
|
||||
rawset(instance, 'pcall', pcall)
|
||||
end
|
||||
if isAceLibrary then
|
||||
for _,v in pairs(self.libs) do
|
||||
local i = type(v) == "table" and v.instance
|
||||
if type(i) == "table" then
|
||||
if not rawget(i, 'error') or i.error == old_error then
|
||||
rawset(i, 'error', error)
|
||||
end
|
||||
if not rawget(i, 'assert') or i.assert == old_assert then
|
||||
rawset(i, 'assert', assert)
|
||||
end
|
||||
if not rawget(i, 'argCheck') or i.argCheck == old_argCheck then
|
||||
rawset(i, 'argCheck', argCheck)
|
||||
end
|
||||
if not rawget(i, 'pcall') or i.pcall == old_pcall then
|
||||
rawset(i, 'pcall', pcall)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
if activateFunc then
|
||||
activateFunc(instance, oldInstance, oldDeactivateFunc)
|
||||
else
|
||||
oldDeactivateFunc(oldInstance)
|
||||
end
|
||||
del(oldInstance)
|
||||
|
||||
if externalFunc then
|
||||
for k,data in pairs(self.libs) do
|
||||
if k ~= major then
|
||||
externalFunc(instance, k, data.instance)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return instance
|
||||
end
|
||||
|
||||
local iter
|
||||
function AceLibrary:IterateLibraries()
|
||||
if not iter then
|
||||
local function iter(t, k)
|
||||
k = next(t, k)
|
||||
if not k then
|
||||
return nil
|
||||
else
|
||||
return k, t[k].instance
|
||||
end
|
||||
end
|
||||
end
|
||||
return iter, self.libs, nil
|
||||
end
|
||||
|
||||
-- @function Activate
|
||||
-- @brief The activateFunc for AceLibrary itself. Called when
|
||||
-- AceLibrary properly registers.
|
||||
-- @param self Reference to AceLibrary
|
||||
-- @param oldLib (optional) Reference to an old version of AceLibrary
|
||||
-- @param oldDeactivate (optional) Function to deactivate the old lib
|
||||
local function activate(self, oldLib, oldDeactivate)
|
||||
if not self.libs then
|
||||
if oldLib then
|
||||
self.libs = oldLib.libs
|
||||
self.scannedlibs = oldLib.scannedlibs
|
||||
end
|
||||
if not self.libs then
|
||||
self.libs = {}
|
||||
end
|
||||
if not self.scannedlibs then
|
||||
self.scannedlibs = {}
|
||||
end
|
||||
end
|
||||
if not self.positions then
|
||||
if oldLib then
|
||||
self.positions = oldLib.positions
|
||||
end
|
||||
if not self.positions then
|
||||
self.positions = setmetatable({}, { __mode = "k" })
|
||||
end
|
||||
end
|
||||
|
||||
-- Expose the library in the global environment
|
||||
_G[ACELIBRARY_MAJOR] = self
|
||||
|
||||
if oldDeactivate then
|
||||
oldDeactivate(oldLib)
|
||||
end
|
||||
end
|
||||
|
||||
if not previous then
|
||||
previous = AceLibrary
|
||||
end
|
||||
if not previous.libs then
|
||||
previous.libs = {}
|
||||
end
|
||||
AceLibrary.libs = previous.libs
|
||||
if not previous.positions then
|
||||
previous.positions = setmetatable({}, { __mode = "k" })
|
||||
end
|
||||
AceLibrary.positions = previous.positions
|
||||
AceLibrary:Register(AceLibrary, ACELIBRARY_MAJOR, ACELIBRARY_MINOR, activate)
|
||||
@@ -0,0 +1,537 @@
|
||||
--[[
|
||||
Name: AceLocale-2.2
|
||||
Revision: $Rev: 15291 $
|
||||
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/AceLocale-2.2
|
||||
SVN: http://svn.wowace.com/root/trunk/Ace2/AceLocale-2.2
|
||||
Description: Localization library for addons to use to handle proper
|
||||
localization and internationalization.
|
||||
Dependencies: AceLibrary
|
||||
]]
|
||||
|
||||
local MAJOR_VERSION = "AceLocale-2.2"
|
||||
local MINOR_VERSION = "$Revision: 15291 $"
|
||||
|
||||
if not AceLibrary then error(MAJOR_VERSION .. " requires AceLibrary.") end
|
||||
if not AceLibrary:IsNewVersion(MAJOR_VERSION, MINOR_VERSION) then return end
|
||||
|
||||
local AceLocale = {}
|
||||
|
||||
local DEFAULT_LOCALE = "enUS"
|
||||
local _G = getfenv(0)
|
||||
|
||||
local BASE_TRANSLATIONS, DEBUGGING, TRANSLATIONS, BASE_LOCALE, TRANSLATION_TABLES, REVERSE_TRANSLATIONS, STRICTNESS, DYNAMIC_LOCALES, CURRENT_LOCALE, NAME
|
||||
|
||||
local rawget = rawget
|
||||
local rawset = rawset
|
||||
local type = type
|
||||
|
||||
local newRegistries = {}
|
||||
local scheduleClear
|
||||
|
||||
local lastSelf
|
||||
local __index = function(self, key)
|
||||
lastSelf = self
|
||||
local value = (rawget(self, TRANSLATIONS) or AceLocale.prototype)[key]
|
||||
rawset(self, key, value)
|
||||
return value
|
||||
end
|
||||
|
||||
local __newindex = function(self, k, v)
|
||||
if type(v) ~= "function" and type(k) ~= "table" then
|
||||
AceLocale.error(self, "Cannot change the values of an AceLocale instance.")
|
||||
end
|
||||
rawset(self, k, v)
|
||||
end
|
||||
|
||||
local __tostring = function(self)
|
||||
if type(rawget(self, 'GetLibraryVersion')) == "function" then
|
||||
return self:GetLibraryVersion()
|
||||
else
|
||||
return "AceLocale(" .. self[NAME] .. ")"
|
||||
end
|
||||
end
|
||||
|
||||
local function clearCache(self)
|
||||
if not rawget(self, BASE_TRANSLATIONS) then
|
||||
return
|
||||
end
|
||||
|
||||
local cache = self[BASE_TRANSLATIONS]
|
||||
rawset(self, REVERSE_TRANSLATIONS, nil)
|
||||
|
||||
for k in pairs(self) do
|
||||
if rawget(cache, k) ~= nil then
|
||||
self[k] = nil
|
||||
end
|
||||
end
|
||||
rawset(self, 'tmp', true)
|
||||
self.tmp = nil
|
||||
end
|
||||
|
||||
local function refixInstance(instance)
|
||||
if getmetatable(instance) then
|
||||
setmetatable(instance, nil)
|
||||
end
|
||||
local translations = instance[TRANSLATIONS]
|
||||
if translations then
|
||||
if getmetatable(translations) then
|
||||
setmetatable(translations, nil)
|
||||
end
|
||||
local baseTranslations = instance[BASE_TRANSLATIONS]
|
||||
if getmetatable(baseTranslations) then
|
||||
setmetatable(baseTranslations, nil)
|
||||
end
|
||||
if translations == baseTranslations or instance[STRICTNESS] then
|
||||
setmetatable(instance, {
|
||||
__index = __index,
|
||||
__newindex = __newindex,
|
||||
__tostring = __tostring
|
||||
})
|
||||
|
||||
setmetatable(translations, {
|
||||
__index = AceLocale.prototype
|
||||
})
|
||||
else
|
||||
setmetatable(instance, {
|
||||
__index = __index,
|
||||
__newindex = __newindex,
|
||||
__tostring = __tostring
|
||||
})
|
||||
|
||||
setmetatable(translations, {
|
||||
__index = baseTranslations,
|
||||
})
|
||||
|
||||
setmetatable(baseTranslations, {
|
||||
__index = AceLocale.prototype,
|
||||
})
|
||||
end
|
||||
else
|
||||
setmetatable(instance, {
|
||||
__index = __index,
|
||||
__newindex = __newindex,
|
||||
__tostring = __tostring,
|
||||
})
|
||||
end
|
||||
clearCache(instance)
|
||||
newRegistries[instance] = true
|
||||
scheduleClear()
|
||||
return instance
|
||||
end
|
||||
|
||||
function AceLocale:new(name)
|
||||
self:argCheck(name, 2, "string")
|
||||
|
||||
if self.registry[name] and type(rawget(self.registry[name], 'GetLibraryVersion')) ~= "function" then
|
||||
return self.registry[name]
|
||||
end
|
||||
|
||||
AceLocale.registry[name] = refixInstance({
|
||||
[STRICTNESS] = false,
|
||||
[NAME] = name,
|
||||
})
|
||||
newRegistries[AceLocale.registry[name]] = true
|
||||
return AceLocale.registry[name]
|
||||
end
|
||||
|
||||
AceLocale.prototype = { class = AceLocale }
|
||||
|
||||
function AceLocale.prototype:EnableDebugging()
|
||||
if rawget(self, BASE_TRANSLATIONS) then
|
||||
AceLocale.error(self, "Cannot enable debugging after a translation has been registered.")
|
||||
end
|
||||
rawset(self, DEBUGGING, true)
|
||||
end
|
||||
|
||||
function AceLocale.prototype:EnableDynamicLocales(override)
|
||||
AceLocale.argCheck(self, override, 2, "boolean", "nil")
|
||||
if not override and rawget(self, BASE_TRANSLATIONS) then
|
||||
AceLocale.error(self, "Cannot enable dynamic locales after a translation has been registered.")
|
||||
end
|
||||
if not rawget(self, DYNAMIC_LOCALES) then
|
||||
rawset(self, DYNAMIC_LOCALES, true)
|
||||
if rawget(self, BASE_LOCALE) then
|
||||
if not rawget(self, TRANSLATION_TABLES) then
|
||||
rawset(self, TRANSLATION_TABLES, {})
|
||||
end
|
||||
self[TRANSLATION_TABLES][self[BASE_LOCALE]] = self[BASE_TRANSLATIONS]
|
||||
self[TRANSLATION_TABLES][self[CURRENT_LOCALE]] = self[TRANSLATIONS]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function AceLocale.prototype:RegisterTranslations(locale, func)
|
||||
AceLocale.argCheck(self, locale, 2, "string")
|
||||
AceLocale.argCheck(self, func, 3, "function")
|
||||
|
||||
if locale == rawget(self, BASE_LOCALE) then
|
||||
AceLocale.error(self, "Cannot provide the same locale more than once. %q provided twice.", locale)
|
||||
end
|
||||
|
||||
if rawget(self, BASE_TRANSLATIONS) and GetLocale() ~= locale then
|
||||
if rawget(self, DEBUGGING) or rawget(self, DYNAMIC_LOCALES) then
|
||||
if not rawget(self, TRANSLATION_TABLES) then
|
||||
rawset(self, TRANSLATION_TABLES, {})
|
||||
end
|
||||
if self[TRANSLATION_TABLES][locale] then
|
||||
AceLocale.error(self, "Cannot provide the same locale more than once. %q provided twice.", locale)
|
||||
end
|
||||
local t = func()
|
||||
func = nil
|
||||
if type(t) ~= "table" then
|
||||
AceLocale.error(self, "Bad argument #3 to `RegisterTranslations'. function did not return a table. (expected table, got %s)", type(t))
|
||||
end
|
||||
self[TRANSLATION_TABLES][locale] = t
|
||||
t = nil
|
||||
end
|
||||
func = nil
|
||||
return
|
||||
end
|
||||
local t = func()
|
||||
func = nil
|
||||
if type(t) ~= "table" then
|
||||
AceLocale.error(self, "Bad argument #3 to `RegisterTranslations'. function did not return a table. (expected table, got %s)", type(t))
|
||||
end
|
||||
|
||||
rawset(self, TRANSLATIONS, t)
|
||||
if not rawget(self, BASE_TRANSLATIONS) then
|
||||
rawset(self, BASE_TRANSLATIONS, t)
|
||||
rawset(self, BASE_LOCALE, locale)
|
||||
for key,value in pairs(t) do
|
||||
if value == true then
|
||||
t[key] = key
|
||||
end
|
||||
end
|
||||
else
|
||||
for key, value in pairs(self[TRANSLATIONS]) do
|
||||
if not rawget(self[BASE_TRANSLATIONS], key) then
|
||||
AceLocale.error(self, "Improper translation exists. %q is likely misspelled for locale %s.", key, locale)
|
||||
end
|
||||
if value == true then
|
||||
AceLocale.error(self, "Can only accept true as a value on the base locale. %q is the base locale, %q is not.", rawget(self, BASE_LOCALE), locale)
|
||||
end
|
||||
end
|
||||
end
|
||||
rawset(self, CURRENT_LOCALE, locale)
|
||||
refixInstance(self)
|
||||
if rawget(self, DEBUGGING) or rawget(self, DYNAMIC_LOCALES) then
|
||||
if not rawget(self, TRANSLATION_TABLES) then
|
||||
rawset(self, TRANSLATION_TABLES, {})
|
||||
end
|
||||
self[TRANSLATION_TABLES][locale] = t
|
||||
end
|
||||
t = nil
|
||||
end
|
||||
|
||||
function AceLocale.prototype:SetLocale(locale)
|
||||
AceLocale.argCheck(self, locale, 2, "string", "boolean")
|
||||
if not rawget(self, DYNAMIC_LOCALES) then
|
||||
AceLocale.error(self, "Cannot call `SetLocale' without first calling `EnableDynamicLocales'.")
|
||||
end
|
||||
if not rawget(self, TRANSLATION_TABLES) then
|
||||
AceLocale.error(self, "Cannot call `SetLocale' without first calling `RegisterTranslations'.")
|
||||
end
|
||||
if locale == true then
|
||||
locale = GetLocale()
|
||||
if not self[TRANSLATION_TABLES][locale] then
|
||||
locale = self[BASE_LOCALE]
|
||||
end
|
||||
end
|
||||
|
||||
if self[CURRENT_LOCALE] == locale then
|
||||
return
|
||||
end
|
||||
|
||||
if not self[TRANSLATION_TABLES][locale] then
|
||||
AceLocale.error(self, "Locale %q not registered.", locale)
|
||||
end
|
||||
|
||||
self[TRANSLATIONS] = self[TRANSLATION_TABLES][locale]
|
||||
self[CURRENT_LOCALE] = locale
|
||||
refixInstance(self)
|
||||
end
|
||||
|
||||
function AceLocale.prototype:GetLocale()
|
||||
if not rawget(self, TRANSLATION_TABLES) then
|
||||
AceLocale.error(self, "Cannot call `GetLocale' without first calling `RegisterTranslations'.")
|
||||
end
|
||||
return self[CURRENT_LOCALE]
|
||||
end
|
||||
|
||||
local function iter(t, position)
|
||||
return (next(t, position))
|
||||
end
|
||||
|
||||
function AceLocale.prototype:IterateAvailableLocales()
|
||||
if not rawget(self, DYNAMIC_LOCALES) then
|
||||
AceLocale.error(self, "Cannot call `IterateAvailableLocales' without first calling `EnableDynamicLocales'.")
|
||||
end
|
||||
if not rawget(self, TRANSLATION_TABLES) then
|
||||
AceLocale.error(self, "Cannot call `IterateAvailableLocales' without first calling `RegisterTranslations'.")
|
||||
end
|
||||
return iter, self[TRANSLATION_TABLES], nil
|
||||
end
|
||||
|
||||
function AceLocale.prototype:HasLocale(locale)
|
||||
if not rawget(self, DYNAMIC_LOCALES) then
|
||||
AceLocale.error(self, "Cannot call `HasLocale' without first calling `EnableDynamicLocales'.")
|
||||
end
|
||||
AceLocale.argCheck(self, locale, 2, "string")
|
||||
return rawget(self, TRANSLATION_TABLES) and self[TRANSLATION_TABLES][locale] ~= nil
|
||||
end
|
||||
|
||||
function AceLocale.prototype:SetStrictness(strict)
|
||||
AceLocale.argCheck(self, strict, 2, "boolean")
|
||||
local mt = getmetatable(self)
|
||||
if not mt then
|
||||
AceLocale.error(self, "Cannot call `SetStrictness' without a metatable.")
|
||||
end
|
||||
if not rawget(self, TRANSLATIONS) then
|
||||
AceLocale.error(self, "No translations registered.")
|
||||
end
|
||||
rawset(self, STRICTNESS, strict)
|
||||
refixInstance(self)
|
||||
end
|
||||
|
||||
local function initReverse(self)
|
||||
rawset(self, REVERSE_TRANSLATIONS, {})
|
||||
local alpha = self[TRANSLATIONS]
|
||||
local bravo = self[REVERSE_TRANSLATIONS]
|
||||
for base, localized in pairs(alpha) do
|
||||
bravo[localized] = base
|
||||
end
|
||||
end
|
||||
|
||||
function AceLocale.prototype:GetTranslation(text)
|
||||
AceLocale.argCheck(self, text, 1, "string", "number")
|
||||
if not rawget(self, TRANSLATIONS) then
|
||||
AceLocale.error(self, "No translations registered")
|
||||
end
|
||||
return self[text]
|
||||
end
|
||||
|
||||
function AceLocale.prototype:GetStrictTranslation(text)
|
||||
AceLocale.argCheck(self, text, 1, "string", "number")
|
||||
local x = rawget(self, TRANSLATIONS)
|
||||
if not x then
|
||||
AceLocale.error(self, "No translations registered")
|
||||
end
|
||||
local value = rawget(x, text)
|
||||
if value == nil then
|
||||
AceLocale.error(self, "Translation %q does not exist for locale %s", text, self[CURRENT_LOCALE])
|
||||
end
|
||||
return value
|
||||
end
|
||||
|
||||
function AceLocale.prototype:GetReverseTranslation(text)
|
||||
local x = rawget(self, REVERSE_TRANSLATIONS)
|
||||
if not x then
|
||||
if not rawget(self, TRANSLATIONS) then
|
||||
AceLocale.error(self, "No translations registered")
|
||||
end
|
||||
initReverse(self)
|
||||
x = self[REVERSE_TRANSLATIONS]
|
||||
end
|
||||
local translation = x[text]
|
||||
if not translation then
|
||||
AceLocale.error(self, "Reverse translation for %q does not exist", text)
|
||||
end
|
||||
return translation
|
||||
end
|
||||
|
||||
function AceLocale.prototype:GetIterator()
|
||||
local x = rawget(self, TRANSLATIONS)
|
||||
if not x then
|
||||
AceLocale.error(self, "No translations registered")
|
||||
end
|
||||
return next, x, nil
|
||||
end
|
||||
|
||||
function AceLocale.prototype:GetReverseIterator()
|
||||
local x = rawget(self, REVERSE_TRANSLATIONS)
|
||||
if not x then
|
||||
if not rawget(self, TRANSLATIONS) then
|
||||
AceLocale.error(self, "No translations registered")
|
||||
end
|
||||
initReverse(self)
|
||||
x = self[REVERSE_TRANSLATIONS]
|
||||
end
|
||||
return next, x, nil
|
||||
end
|
||||
|
||||
function AceLocale.prototype:HasTranslation(text)
|
||||
AceLocale.argCheck(self, text, 1, "string", "number")
|
||||
local x = rawget(self, TRANSLATIONS)
|
||||
if not x then
|
||||
AceLocale.error(self, "No translations registered")
|
||||
end
|
||||
return rawget(x, text) and true
|
||||
end
|
||||
|
||||
function AceLocale.prototype:HasReverseTranslation(text)
|
||||
local x = rawget(self, REVERSE_TRANSLATIONS)
|
||||
if not x then
|
||||
if not rawget(self, TRANSLATIONS) then
|
||||
AceLocale.error(self, "No translations registered")
|
||||
end
|
||||
initReverse(self)
|
||||
x = self[REVERSE_TRANSLATIONS]
|
||||
end
|
||||
return x[text] and true
|
||||
end
|
||||
|
||||
function AceLocale.prototype:Debug()
|
||||
if not rawget(self, DEBUGGING) then
|
||||
return
|
||||
end
|
||||
local words = {}
|
||||
local locales = {"enUS", "deDE", "frFR", "koKR", "zhCN", "zhTW", "esES"}
|
||||
local localizations = {}
|
||||
DEFAULT_CHAT_FRAME:AddMessage("--- AceLocale Debug ---")
|
||||
for _,locale in ipairs(locales) do
|
||||
if not self[TRANSLATION_TABLES][locale] then
|
||||
DEFAULT_CHAT_FRAME:AddMessage(string.format("Locale %q not found", locale))
|
||||
else
|
||||
localizations[locale] = self[TRANSLATION_TABLES][locale]
|
||||
end
|
||||
end
|
||||
local localeDebug = {}
|
||||
for locale, localization in pairs(localizations) do
|
||||
localeDebug[locale] = {}
|
||||
for word in pairs(localization) do
|
||||
if type(localization[word]) == "table" then
|
||||
if type(words[word]) ~= "table" then
|
||||
words[word] = {}
|
||||
end
|
||||
for bit in pairs(localization[word]) do
|
||||
if type(localization[word][bit]) == "string" then
|
||||
words[word][bit] = true
|
||||
end
|
||||
end
|
||||
elseif type(localization[word]) == "string" then
|
||||
words[word] = true
|
||||
end
|
||||
end
|
||||
end
|
||||
for word in pairs(words) do
|
||||
if type(words[word]) == "table" then
|
||||
for bit in pairs(words[word]) do
|
||||
for locale, localization in pairs(localizations) do
|
||||
if not rawget(localization, word) or not localization[word][bit] then
|
||||
localeDebug[locale][word .. "::" .. bit] = true
|
||||
end
|
||||
end
|
||||
end
|
||||
else
|
||||
for locale, localization in pairs(localizations) do
|
||||
if not rawget(localization, word) then
|
||||
localeDebug[locale][word] = true
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
for locale, t in pairs(localeDebug) do
|
||||
if not next(t) then
|
||||
DEFAULT_CHAT_FRAME:AddMessage(string.format("Locale %q complete", locale))
|
||||
else
|
||||
DEFAULT_CHAT_FRAME:AddMessage(string.format("Locale %q missing:", locale))
|
||||
for word in pairs(t) do
|
||||
DEFAULT_CHAT_FRAME:AddMessage(string.format(" %q", word))
|
||||
end
|
||||
end
|
||||
end
|
||||
DEFAULT_CHAT_FRAME:AddMessage("--- End AceLocale Debug ---")
|
||||
end
|
||||
|
||||
setmetatable(AceLocale.prototype, {
|
||||
__index = function(self, k)
|
||||
if type(k) ~= "table" and k ~= 0 and k ~= "GetLibraryVersion" and k ~= "error" and k ~= "assert" and k ~= "argCheck" and k ~= "pcall" then -- HACK: remove "GetLibraryVersion" and such later.
|
||||
AceLocale.error(lastSelf or self, "Translation %q does not exist.", k)
|
||||
end
|
||||
return nil
|
||||
end
|
||||
})
|
||||
|
||||
local function activate(self, oldLib, oldDeactivate)
|
||||
AceLocale = self
|
||||
|
||||
self.frame = oldLib and oldLib.frame or CreateFrame("Frame")
|
||||
self.registry = oldLib and oldLib.registry or {}
|
||||
self.BASE_TRANSLATIONS = oldLib and oldLib.BASE_TRANSLATIONS or {}
|
||||
self.DEBUGGING = oldLib and oldLib.DEBUGGING or {}
|
||||
self.TRANSLATIONS = oldLib and oldLib.TRANSLATIONS or {}
|
||||
self.BASE_LOCALE = oldLib and oldLib.BASE_LOCALE or {}
|
||||
self.TRANSLATION_TABLES = oldLib and oldLib.TRANSLATION_TABLES or {}
|
||||
self.REVERSE_TRANSLATIONS = oldLib and oldLib.REVERSE_TRANSLATIONS or {}
|
||||
self.STRICTNESS = oldLib and oldLib.STRICTNESS or {}
|
||||
self.NAME = oldLib and oldLib.NAME or {}
|
||||
self.DYNAMIC_LOCALES = oldLib and oldLib.DYNAMIC_LOCALES or {}
|
||||
self.CURRENT_LOCALE = oldLib and oldLib.CURRENT_LOCALE or {}
|
||||
|
||||
BASE_TRANSLATIONS = self.BASE_TRANSLATIONS
|
||||
DEBUGGING = self.DEBUGGING
|
||||
TRANSLATIONS = self.TRANSLATIONS
|
||||
BASE_LOCALE = self.BASE_LOCALE
|
||||
TRANSLATION_TABLES = self.TRANSLATION_TABLES
|
||||
REVERSE_TRANSLATIONS = self.REVERSE_TRANSLATIONS
|
||||
STRICTNESS = self.STRICTNESS
|
||||
NAME = self.NAME
|
||||
DYNAMIC_LOCALES = self.DYNAMIC_LOCALES
|
||||
CURRENT_LOCALE = self.CURRENT_LOCALE
|
||||
|
||||
|
||||
local GetTime = GetTime
|
||||
local timeUntilClear = GetTime() + 5
|
||||
scheduleClear = function()
|
||||
if next(newRegistries) then
|
||||
self.frame:Show()
|
||||
timeUntilClear = GetTime() + 5
|
||||
end
|
||||
end
|
||||
|
||||
if not self.registry then
|
||||
self.registry = {}
|
||||
else
|
||||
for name, instance in pairs(self.registry) do
|
||||
local name = name
|
||||
local mt = getmetatable(instance)
|
||||
setmetatable(instance, nil)
|
||||
instance[NAME] = name
|
||||
local strict
|
||||
if instance[STRICTNESS] ~= nil then
|
||||
strict = instance[STRICTNESS]
|
||||
elseif instance[TRANSLATIONS] ~= instance[BASE_TRANSLATIONS] then
|
||||
if getmetatable(instance[TRANSLATIONS]).__index == oldLib.prototype then
|
||||
strict = true
|
||||
end
|
||||
end
|
||||
instance[STRICTNESS] = strict and true or false
|
||||
refixInstance(instance)
|
||||
end
|
||||
end
|
||||
|
||||
self.frame:SetScript("OnEvent", scheduleClear)
|
||||
self.frame:SetScript("OnUpdate", function() -- (this, elapsed)
|
||||
if timeUntilClear - GetTime() <= 0 then
|
||||
self.frame:Hide()
|
||||
for k in pairs(newRegistries) do
|
||||
clearCache(k)
|
||||
newRegistries[k] = nil
|
||||
k = nil
|
||||
end
|
||||
end
|
||||
end)
|
||||
self.frame:UnregisterAllEvents()
|
||||
self.frame:RegisterEvent("ADDON_LOADED")
|
||||
self.frame:RegisterEvent("PLAYER_ENTERING_WORLD")
|
||||
self.frame:Show()
|
||||
|
||||
if oldDeactivate then
|
||||
oldDeactivate(oldLib)
|
||||
end
|
||||
end
|
||||
|
||||
AceLibrary:Register(AceLocale, MAJOR_VERSION, MINOR_VERSION, activate)
|
||||
@@ -0,0 +1,404 @@
|
||||
--[[
|
||||
Name: AceModuleCore-2.0
|
||||
Revision: $Rev: 12441 $
|
||||
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/AceModuleCore-2.0
|
||||
SVN: http://svn.wowace.com/root/trunk/Ace2/AceModuleCore-2.0
|
||||
Description: Mixin to provide a module system so that modules or plugins can
|
||||
use an addon as its core.
|
||||
Dependencies: AceLibrary, AceOO-2.0, AceAddon-2.0, Compost-2.0 (optional)
|
||||
]]
|
||||
|
||||
local MAJOR_VERSION = "AceModuleCore-2.0"
|
||||
local MINOR_VERSION = "$Revision: 12441 $"
|
||||
|
||||
if not AceLibrary then error(MAJOR_VERSION .. " requires AceLibrary") end
|
||||
if not AceLibrary:IsNewVersion(MAJOR_VERSION, MINOR_VERSION) then return end
|
||||
|
||||
if not AceLibrary:HasInstance("AceOO-2.0") then error(MAJOR_VERSION .. " requires AceOO-2.0") end
|
||||
|
||||
local table_setn
|
||||
do
|
||||
local version = GetBuildInfo()
|
||||
if string.find(version, "^2%.") then
|
||||
-- 2.0.0
|
||||
table_setn = function() end
|
||||
else
|
||||
table_setn = table.setn
|
||||
end
|
||||
end
|
||||
|
||||
local new, del
|
||||
do
|
||||
local list = setmetatable({}, {__mode = 'k'})
|
||||
function new()
|
||||
local t = next(list)
|
||||
if t then
|
||||
list[t] = nil
|
||||
return t
|
||||
else
|
||||
return {}
|
||||
end
|
||||
end
|
||||
function del(t)
|
||||
for k in pairs(t) do
|
||||
t[k] = nil
|
||||
end
|
||||
table_setn(t, 0)
|
||||
list[t] = true
|
||||
return nil
|
||||
end
|
||||
end
|
||||
|
||||
local AceOO = AceLibrary:GetInstance("AceOO-2.0")
|
||||
local AceModuleCore = AceOO.Mixin {
|
||||
"NewModule",
|
||||
"HasModule",
|
||||
"GetModule",
|
||||
"IsModule",
|
||||
"IterateModules",
|
||||
"SetModuleMixins",
|
||||
"SetModuleClass",
|
||||
"IsModuleActive",
|
||||
"ToggleModuleActive"
|
||||
}
|
||||
|
||||
local Compost = AceLibrary:HasInstance("Compost-2.0") and AceLibrary("Compost-2.0")
|
||||
|
||||
local function getlibrary(lib)
|
||||
if type(lib) == "string" then
|
||||
return AceLibrary(lib)
|
||||
else
|
||||
return lib
|
||||
end
|
||||
end
|
||||
|
||||
local tmp
|
||||
function AceModuleCore:NewModule(name, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20)
|
||||
if not self.modules then
|
||||
AceModuleCore:error("CreatePrototype() must be called before attempting to create a new module.", 2)
|
||||
end
|
||||
AceModuleCore:argCheck(name, 2, "string")
|
||||
if string.len(name) == 0 then
|
||||
AceModuleCore:error("Bad argument #2 to `NewModule`, string must not be empty")
|
||||
end
|
||||
if self.modules[name] then
|
||||
AceModuleCore:error("The module %q has already been registered", name)
|
||||
end
|
||||
|
||||
if not tmp then
|
||||
tmp = {}
|
||||
end
|
||||
if a1 then table.insert(tmp, a1)
|
||||
if a2 then table.insert(tmp, a2)
|
||||
if a3 then table.insert(tmp, a3)
|
||||
if a4 then table.insert(tmp, a4)
|
||||
if a5 then table.insert(tmp, a5)
|
||||
if a6 then table.insert(tmp, a6)
|
||||
if a7 then table.insert(tmp, a7)
|
||||
if a8 then table.insert(tmp, a8)
|
||||
if a9 then table.insert(tmp, a9)
|
||||
if a10 then table.insert(tmp, a10)
|
||||
if a11 then table.insert(tmp, a11)
|
||||
if a12 then table.insert(tmp, a12)
|
||||
if a13 then table.insert(tmp, a13)
|
||||
if a14 then table.insert(tmp, a14)
|
||||
if a15 then table.insert(tmp, a15)
|
||||
if a16 then table.insert(tmp, a16)
|
||||
if a17 then table.insert(tmp, a17)
|
||||
if a18 then table.insert(tmp, a18)
|
||||
if a19 then table.insert(tmp, a19)
|
||||
if a20 then table.insert(tmp, a20)
|
||||
end end end end end end end end end end end end end end end end end end end end
|
||||
for k,v in ipairs(tmp) do
|
||||
tmp[k] = getlibrary(v)
|
||||
end
|
||||
|
||||
if self.moduleMixins then
|
||||
for _,mixin in ipairs(self.moduleMixins) do
|
||||
local exists = false
|
||||
for _,v in ipairs(tmp) do
|
||||
if mixin == v then
|
||||
exists = true
|
||||
break
|
||||
end
|
||||
end
|
||||
if not exists then
|
||||
table.insert(tmp, mixin)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local module = AceOO.Classpool(self.moduleClass, unpack(tmp)):new(name)
|
||||
self.modules[name] = module
|
||||
module.name = name
|
||||
module.title = name
|
||||
|
||||
AceModuleCore.totalModules[module] = self
|
||||
|
||||
for k in pairs(tmp) do
|
||||
tmp[k] = nil
|
||||
end
|
||||
table_setn(tmp, 0)
|
||||
return module
|
||||
end
|
||||
|
||||
function AceModuleCore:HasModule(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20)
|
||||
if a1 then if not self.modules[a1] then return false end
|
||||
if a2 then if not self.modules[a2] then return false end
|
||||
if a3 then if not self.modules[a3] then return false end
|
||||
if a4 then if not self.modules[a4] then return false end
|
||||
if a5 then if not self.modules[a5] then return false end
|
||||
if a6 then if not self.modules[a6] then return false end
|
||||
if a7 then if not self.modules[a7] then return false end
|
||||
if a8 then if not self.modules[a8] then return false end
|
||||
if a9 then if not self.modules[a9] then return false end
|
||||
if a10 then if not self.modules[a10] then return false end
|
||||
if a11 then if not self.modules[a11] then return false end
|
||||
if a12 then if not self.modules[a12] then return false end
|
||||
if a13 then if not self.modules[a13] then return false end
|
||||
if a14 then if not self.modules[a14] then return false end
|
||||
if a15 then if not self.modules[a15] then return false end
|
||||
if a16 then if not self.modules[a16] then return false end
|
||||
if a17 then if not self.modules[a17] then return false end
|
||||
if a18 then if not self.modules[a18] then return false end
|
||||
if a19 then if not self.modules[a19] then return false end
|
||||
if a20 then if not self.modules[a20] then return false end
|
||||
end end end end end end end end end end end end end end end end end end end end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
function AceModuleCore:GetModule(name)
|
||||
if not self.modules then
|
||||
AceModuleCore:error("Error initializing class. Please report error.")
|
||||
end
|
||||
if not self.modules[name] then
|
||||
AceModuleCore:error("Cannot find module %q.", name)
|
||||
end
|
||||
return self.modules[name]
|
||||
end
|
||||
|
||||
function AceModuleCore:IsModule(module)
|
||||
if self == AceModuleCore then
|
||||
return AceModuleCore.totalModules[module]
|
||||
else
|
||||
for k,v in pairs(self.modules) do
|
||||
if v == module then
|
||||
return true
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
function AceModuleCore:IterateModules()
|
||||
local t = new()
|
||||
for k in pairs(self.modules) do
|
||||
table.insert(t, k)
|
||||
end
|
||||
table.sort(t)
|
||||
local i = 0
|
||||
return function()
|
||||
i = i + 1
|
||||
local x = t[i]
|
||||
if x then
|
||||
return x, self.modules[x]
|
||||
else
|
||||
t = del(t)
|
||||
return nil
|
||||
end
|
||||
end, nil, nil
|
||||
end
|
||||
|
||||
function AceModuleCore:SetModuleMixins(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20)
|
||||
if self.moduleMixins then
|
||||
AceModuleCore:error('Cannot call "SetModuleMixins" twice')
|
||||
elseif not self.modules then
|
||||
AceModuleCore:error("Error initializing class. Please report error.")
|
||||
elseif next(self.modules) then
|
||||
AceModuleCore:error('Cannot call "SetModuleMixins" after "NewModule" has been called.')
|
||||
end
|
||||
|
||||
self.moduleMixins = Compost and Compost:Acquire(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20) or {a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20}
|
||||
for k,v in ipairs(self.moduleMixins) do
|
||||
self.moduleMixins[k] = getlibrary(v)
|
||||
end
|
||||
end
|
||||
|
||||
function AceModuleCore:SetModuleClass(class)
|
||||
class = getlibrary(class)
|
||||
AceModuleCore:assert(AceOO.inherits(class, AceOO.Class), "Bad argument #2 to `SetModuleClass' (Class expected)")
|
||||
if not self.modules then
|
||||
AceModuleCore:error("Error initializing class. Please report error.")
|
||||
end
|
||||
if self.customModuleClass then
|
||||
AceModuleCore:error("Cannot call `SetModuleClass' twice.")
|
||||
end
|
||||
self.customModuleClass = true
|
||||
self.moduleClass = class
|
||||
self.modulePrototype = class.prototype
|
||||
end
|
||||
|
||||
function AceModuleCore:ToggleModuleActive(module, state)
|
||||
AceModuleCore:argCheck(module, 2, "table", "string")
|
||||
AceModuleCore:argCheck(state, 3, "nil", "boolean")
|
||||
|
||||
if type(module) == "string" then
|
||||
if not self:HasModule(module) then
|
||||
AceModuleCore:error("Cannot find module %q", module)
|
||||
end
|
||||
module = self:GetModule(module)
|
||||
else
|
||||
if not self:IsModule(module) then
|
||||
AceModuleCore:error("%q is not a module", module)
|
||||
end
|
||||
end
|
||||
|
||||
local disable
|
||||
if state == nil then
|
||||
disable = self:IsModuleActive(module)
|
||||
else
|
||||
disable = not state
|
||||
if disable ~= self:IsModuleActive(module) then
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
if type(module.ToggleActive) == "function" then
|
||||
return module:ToggleActive(not disable)
|
||||
elseif AceOO.inherits(self, "AceDB-2.0") then
|
||||
if not self.db or not self.db.raw then
|
||||
AceModuleCore:error("Cannot toggle a module until `RegisterDB' has been called and `ADDON_LOADED' has been fireed.")
|
||||
end
|
||||
if type(self.db.raw.disabledModules) ~= "table" then
|
||||
self.db.raw.disabledModules = Compost and Compost:Acquire() or {}
|
||||
end
|
||||
local _,profile = self:GetProfile()
|
||||
if type(self.db.raw.disabledModules[profile]) ~= "table" then
|
||||
self.db.raw.disabledModules[profile] = Compost and Compost:Acquire() or {}
|
||||
end
|
||||
if type(self.db.raw.disabledModules[profile][module.name]) ~= "table" then
|
||||
self.db.raw.disabledModules[profile][module.name] = disable or nil
|
||||
end
|
||||
if not disable then
|
||||
if not next(self.db.raw.disabledModules[profile]) then
|
||||
if Compost then
|
||||
Compost:Reclaim(self.db.raw.disabledModules[profile])
|
||||
end
|
||||
self.db.raw.disabledModules[profile] = nil
|
||||
end
|
||||
if not next(self.db.raw.disabledModules) then
|
||||
if Compost then
|
||||
Compost:Reclaim(self.db.raw.disabledModules)
|
||||
end
|
||||
self.db.raw.disabledModules = nil
|
||||
end
|
||||
end
|
||||
else
|
||||
if type(self.disabledModules) ~= "table" then
|
||||
self.disabledModules = Compost and Compost:Acquire() or {}
|
||||
end
|
||||
self.disabledModules[module.name] = disable or nil
|
||||
end
|
||||
if AceOO.inherits(module, "AceAddon-2.0") then
|
||||
local AceAddon = AceLibrary("AceAddon-2.0")
|
||||
if not AceAddon.addonsStarted[module] then
|
||||
return
|
||||
end
|
||||
end
|
||||
if not disable then
|
||||
if type(module.OnEnable) == "function" then
|
||||
module:OnEnable()
|
||||
end
|
||||
else
|
||||
local current = module.class
|
||||
while true do
|
||||
if current == AceOO.Class then
|
||||
break
|
||||
end
|
||||
if current.mixins then
|
||||
for mixin in pairs(current.mixins) do
|
||||
if type(mixin.OnEmbedDisable) == "function" then
|
||||
mixin:OnEmbedDisable(module)
|
||||
end
|
||||
end
|
||||
end
|
||||
current = current.super
|
||||
end
|
||||
if type(module.OnDisable) == "function" then
|
||||
module:OnDisable()
|
||||
end
|
||||
end
|
||||
return not disable
|
||||
end
|
||||
|
||||
function AceModuleCore:IsModuleActive(module)
|
||||
AceModuleCore:argCheck(module, 2, "table", "string")
|
||||
|
||||
if AceModuleCore == self then
|
||||
self:argCheck(module, 2, "table")
|
||||
|
||||
local core = AceModuleCore.totalModules[module]
|
||||
if not core then
|
||||
self:error("Bad argument #2 to `IsModuleActive'. Not a module")
|
||||
end
|
||||
return core:IsModuleActive(module)
|
||||
end
|
||||
|
||||
if type(module) == "string" then
|
||||
if not self:HasModule(module) then
|
||||
AceModuleCore:error("Cannot find module %q", module)
|
||||
end
|
||||
module = self:GetModule(module)
|
||||
else
|
||||
if not self:IsModule(module) then
|
||||
AceModuleCore:error("%q is not a module", module)
|
||||
end
|
||||
end
|
||||
|
||||
if type(module.IsActive) == "function" then
|
||||
return module:IsActive()
|
||||
elseif AceOO.inherits(self, "AceDB-2.0") then
|
||||
local _,profile = self:GetProfile()
|
||||
return not self.db or not self.db.raw or not self.db.raw.disabledModules or not self.db.raw.disabledModules[profile] or not self.db.raw.disabledModules[profile][module.name]
|
||||
else
|
||||
return not self.disabledModules or not self.disabledModules[module.name]
|
||||
end
|
||||
end
|
||||
|
||||
function AceModuleCore:OnInstanceInit(target)
|
||||
if target.modules then
|
||||
AceModuleCore:error("OnInstanceInit cannot be called twice")
|
||||
end
|
||||
target.modules = Compost and Compost:Acquire() or {}
|
||||
|
||||
target.moduleClass = AceOO.Class("AceAddon-2.0")
|
||||
target.modulePrototype = target.moduleClass.prototype
|
||||
end
|
||||
|
||||
AceModuleCore.OnManualEmbed = AceModuleCore.OnInstanceInit
|
||||
|
||||
local function activate(self, oldLib, oldDeactivate)
|
||||
AceModuleCore = self
|
||||
|
||||
self.super.activate(self, oldLib, oldDeactivate)
|
||||
|
||||
if oldLib then
|
||||
self.totalModules = oldLib.totalModules
|
||||
end
|
||||
if not self.totalModules then
|
||||
self.totalModules = {}
|
||||
end
|
||||
end
|
||||
|
||||
local function external(self, major, instance)
|
||||
if major == "Compost-2.0" then
|
||||
Compost = instance
|
||||
end
|
||||
end
|
||||
|
||||
AceLibrary:Register(AceModuleCore, MAJOR_VERSION, MINOR_VERSION, activate)
|
||||
AceModuleCore = AceLibrary(MAJOR_VERSION)
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,136 @@
|
||||
--[[
|
||||
Name: Babble-Class-2.2
|
||||
Revision: $Rev: 14410 $
|
||||
Author(s): ckknight (ckknight@gmail.com)
|
||||
Website: http://ckknight.wowinterface.com/
|
||||
Documentation: http://wiki.wowace.com/index.php/Babble-Class-2.2
|
||||
SVN: http://svn.wowace.com/root/trunk/Babble-2.2/Babble-Class-2.2
|
||||
Description: A library to provide localizations for classes.
|
||||
Dependencies: AceLibrary, AceLocale-2.2
|
||||
]]
|
||||
|
||||
local MAJOR_VERSION = "Babble-Class-2.2"
|
||||
local MINOR_VERSION = tonumber(string.sub("$Revision: 14410 $", 12, -3))
|
||||
|
||||
if not AceLibrary then error(MAJOR_VERSION .. " requires AceLibrary") end
|
||||
|
||||
if not AceLibrary:HasInstance("AceLocale-2.2") then error(MAJOR_VERSION .. " requires AceLocale-2.2") end
|
||||
|
||||
local _, x = AceLibrary("AceLocale-2.2"):GetLibraryVersion()
|
||||
MINOR_VERSION = MINOR_VERSION * 100000 + x
|
||||
|
||||
if not AceLibrary:IsNewVersion(MAJOR_VERSION, MINOR_VERSION) then return end
|
||||
|
||||
local BabbleClass = AceLibrary("AceLocale-2.2"):new(MAJOR_VERSION)
|
||||
|
||||
-- uncomment below for debug information
|
||||
-- BabbleClass:EnableDebugging()
|
||||
|
||||
BabbleClass:RegisterTranslations("enUS", function()
|
||||
return {
|
||||
["Warlock"] = true,
|
||||
["Warrior"] = true,
|
||||
["Hunter"] = true,
|
||||
["Mage"] = true,
|
||||
["Priest"] = true,
|
||||
["Druid"] = true,
|
||||
["Paladin"] = true,
|
||||
["Shaman"] = true,
|
||||
["Rogue"] = true,
|
||||
}
|
||||
end)
|
||||
|
||||
BabbleClass:RegisterTranslations("deDE", function()
|
||||
return {
|
||||
["Warlock"] = "Hexenmeister",
|
||||
["Warrior"] = "Krieger",
|
||||
["Hunter"] = "Jäger",
|
||||
["Mage"] = "Magier",
|
||||
["Priest"] = "Priester",
|
||||
["Druid"] = "Druide",
|
||||
["Paladin"] = "Paladin",
|
||||
["Shaman"] = "Schamane",
|
||||
["Rogue"] = "Schurke",
|
||||
}
|
||||
end)
|
||||
|
||||
BabbleClass:RegisterTranslations("frFR", function()
|
||||
return {
|
||||
["Warlock"] = "D\195\169moniste",
|
||||
["Warrior"] = "Guerrier",
|
||||
["Hunter"] = "Chasseur",
|
||||
["Mage"] = "Mage",
|
||||
["Priest"] = "Pr\195\170tre",
|
||||
["Druid"] = "Druide",
|
||||
["Paladin"] = "Paladin",
|
||||
["Shaman"] = "Chaman",
|
||||
["Rogue"] = "Voleur",
|
||||
}
|
||||
end)
|
||||
|
||||
BabbleClass:RegisterTranslations("zhCN", function()
|
||||
return {
|
||||
["Warlock"] = "术士",
|
||||
["Warrior"] = "战士",
|
||||
["Hunter"] = "猎人",
|
||||
["Mage"] = "法师",
|
||||
["Priest"] = "牧师",
|
||||
["Druid"] = "德鲁伊",
|
||||
["Paladin"] = "圣骑士",
|
||||
["Shaman"] = "萨满祭司",
|
||||
["Rogue"] = "盗贼",
|
||||
}
|
||||
end)
|
||||
|
||||
BabbleClass:RegisterTranslations("zhTW", function()
|
||||
return {
|
||||
["Warlock"] = "術士",
|
||||
["Warrior"] = "戰士",
|
||||
["Hunter"] = "獵人",
|
||||
["Mage"] = "法師",
|
||||
["Priest"] = "牧師",
|
||||
["Druid"] = "德魯伊",
|
||||
["Paladin"] = "聖騎士",
|
||||
["Shaman"] = "薩滿",
|
||||
["Rogue"] = "盜賊",
|
||||
}
|
||||
end)
|
||||
|
||||
BabbleClass:RegisterTranslations("koKR", function()
|
||||
return {
|
||||
["Warlock"] = "흑마법사",
|
||||
["Warrior"] = "전사",
|
||||
["Hunter"] = "사냥꾼",
|
||||
["Mage"] = "마법사",
|
||||
["Priest"] = "사제",
|
||||
["Druid"] = "드루이드",
|
||||
["Paladin"] = "성기사",
|
||||
["Shaman"] = "주술사",
|
||||
["Rogue"] = "도적",
|
||||
}
|
||||
end)
|
||||
|
||||
BabbleClass:Debug()
|
||||
BabbleClass:SetStrictness(true)
|
||||
|
||||
function BabbleClass:GetColor(class)
|
||||
self:argCheck(class, 2, "string")
|
||||
if self:HasReverseTranslation(class) then
|
||||
class = string.upper(self:GetReverseTranslation(class))
|
||||
else
|
||||
class = string.upper(class)
|
||||
end
|
||||
if RAID_CLASS_COLORS and RAID_CLASS_COLORS[class] then
|
||||
return RAID_CLASS_COLORS[class].r, RAID_CLASS_COLORS[class].g, RAID_CLASS_COLORS[class].b
|
||||
end
|
||||
return 0.63, 0.63, 0.63
|
||||
end
|
||||
|
||||
function BabbleClass:GetHexColor(class)
|
||||
self:argCheck(class, 2, "string")
|
||||
local r, g, b = self:GetColor(class)
|
||||
return string.format("%02x%02x%02x", r * 255, g * 255, b * 255)
|
||||
end
|
||||
|
||||
AceLibrary:Register(BabbleClass, MAJOR_VERSION, MINOR_VERSION)
|
||||
BabbleClass = nil
|
||||
@@ -0,0 +1,277 @@
|
||||
|
||||
--[[
|
||||
Name: Compost-2.0
|
||||
Revision: $Rev: 11579 $
|
||||
Author: Tekkub Stoutwrithe (tekkub@gmail.com)
|
||||
Website: http://wiki.wowace.com/index.php/CompostLib
|
||||
Documentation: http://wiki.wowace.com/index.php/Compost-2.0_API_Documentation
|
||||
SVN: svn://svn.wowace.com/root/trunk/CompostLib/Compost-2.0
|
||||
Description: Recycle tables to reduce garbage generation
|
||||
Dependencies: AceLibrary
|
||||
]]
|
||||
|
||||
local vmajor, vminor = "Compost-2.0", "$Revision: 11579 $"
|
||||
|
||||
if not AceLibrary then error(vmajor .. " requires AceLibrary.") end
|
||||
if not AceLibrary:IsNewVersion(vmajor, vminor) then return end
|
||||
|
||||
local lib = {}
|
||||
|
||||
local table_setn
|
||||
do
|
||||
local version = GetBuildInfo()
|
||||
if string.find(version, "^2%.") then
|
||||
-- 2.0.0
|
||||
table_setn = function() end
|
||||
else
|
||||
table_setn = table.setn
|
||||
end
|
||||
end
|
||||
|
||||
-- Activate a new instance of this library
|
||||
local function activate(self, oldLib, oldDeactivate)
|
||||
if oldLib then -- if upgrading
|
||||
self.var, self.k = oldLib.var, oldLib.k
|
||||
else
|
||||
self.k = { -- Constants go here
|
||||
maxcache = 10, -- I think this is a good number, I'll change it later if necessary
|
||||
}
|
||||
self.var = { -- "Local" variables go here
|
||||
cache = {},
|
||||
secondarycache = {},
|
||||
}
|
||||
|
||||
-- This makes the secondary cache table a weak table, any values in it will be reclaimed
|
||||
-- during a GC if there are no other references to them
|
||||
setmetatable(self.var.secondarycache, {__mode = "v"})
|
||||
end
|
||||
if not self.var.tablechecks then
|
||||
self.var.tablechecks = {}
|
||||
setmetatable(self.var.tablechecks, {__mode = "kv"})
|
||||
for i,v in ipairs(self.var.cache) do self.var.tablechecks[v] = true end
|
||||
for i,v in ipairs(self.var.secondarycache) do self.var.tablechecks[v] = true end
|
||||
end
|
||||
if oldDeactivate then oldDeactivate(oldLib) end
|
||||
end
|
||||
|
||||
|
||||
-- Removes an empty table from the cache and returns it
|
||||
-- or generates a new table if none available
|
||||
function lib:GetTable()
|
||||
if self.var.disabled then return {} end
|
||||
|
||||
if table.getn(self.var.cache) > 0 then
|
||||
for i in pairs(self.var.cache) do
|
||||
local t = table.remove(self.var.cache, i)
|
||||
self.var.tablechecks[t] = nil
|
||||
if next(t) then -- Table has been modified, someone holds a ref still, discard it
|
||||
error("Someone is modifying tables reclaimed by Compost!")
|
||||
self:IncDec("numdiscarded", 1)
|
||||
else -- It's clean, we think... return it.
|
||||
self:IncDec("totn", -1)
|
||||
self:IncDec("numrecycled", 1)
|
||||
return t
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if next(self.var.secondarycache) then
|
||||
for i in pairs(self.var.secondarycache) do
|
||||
local t = table.remove(self.var.secondarycache, i)
|
||||
self.var.tablechecks[t] = nil
|
||||
if next(t) then -- Table has been modified, someone holds a ref still, discard it
|
||||
error("Someone is modifying tables reclaimed by Compost!")
|
||||
self:IncDec("numdiscarded", 1)
|
||||
else -- It's clean, we think... return it.
|
||||
self:IncDec("totn", -1)
|
||||
self:IncDec("numrecycled", 1)
|
||||
return t
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
self:IncDec("numnew", 1)
|
||||
return {}
|
||||
end
|
||||
|
||||
|
||||
-- Returns a table, populated with any variables passed
|
||||
-- basically: return {a1, a2, ... a20}
|
||||
function lib:Acquire(a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15,a16,a17,a18,a19,a20)
|
||||
local t = self:GetTable()
|
||||
return self:Populate(t,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15,a16,a17,a18,a19,a20)
|
||||
end
|
||||
|
||||
|
||||
-- Acquires a table and fills it with values, hash style
|
||||
-- basically: return {k1 = v1, k2 = v2, ... k10 = v10}
|
||||
function lib:AcquireHash(k1,v1,k2,v2,k3,v3,k4,v4,k5,v5,k6,v6,k7,v7,k8,v8,k9,v9,k10,v10)
|
||||
local t = self:GetTable()
|
||||
return self:PopulateHash(t,k1,v1,k2,v2,k3,v3,k4,v4,k5,v5,k6,v6,k7,v7,k8,v8,k9,v9,k10,v10)
|
||||
end
|
||||
|
||||
|
||||
-- Erases the table passed, fills it with the args passed, and returns it
|
||||
-- Essentially the same as doing Reclaim then Acquire, except the same table is reused
|
||||
function lib:Recycle(t,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15,a16,a17,a18,a19,a20)
|
||||
t = self:Erase(t)
|
||||
return self:Populate(t,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15,a16,a17,a18,a19,a20)
|
||||
end
|
||||
|
||||
|
||||
-- Erases the table passed, fills it with the args passed, and returns it
|
||||
-- Essentially the same as doing Reclaim then AcquireHash, except the same table is reused
|
||||
function lib:RecycleHash(t,k1,v1,k2,v2,k3,v3,k4,v4,k5,v5,k6,v6,k7,v7,k8,v8,k9,v9,k10,v10)
|
||||
t = self:Erase(t)
|
||||
return self:PopulateHash(t,k1,v1,k2,v2,k3,v3,k4,v4,k5,v5,k6,v6,k7,v7,k8,v8,k9,v9,k10,v10)
|
||||
end
|
||||
|
||||
|
||||
-- Returns a table to the cache
|
||||
-- All tables referenced inside the passed table will be reclaimed also
|
||||
-- If a depth is passed, Reclaim will call itsself recursivly
|
||||
-- to reclaim all tables contained in t to the depth specified
|
||||
function lib:Reclaim(t, depth)
|
||||
if type(t) ~= "table" or self.var.disabled then return end
|
||||
self:assert(not self.var.tablechecks[t], "Cannot reclaim a table twice")
|
||||
|
||||
if not self:ItemsInSecondaryCache() then self.var.totn = table.getn(self.var.cache) end
|
||||
|
||||
if depth and depth > 0 then
|
||||
for i in pairs(t) do
|
||||
if type(t[i]) == "table" then self:Reclaim(t[i], depth - 1) end
|
||||
end
|
||||
end
|
||||
self:Erase(t)
|
||||
if self.k.maxcache and table.getn(self.var.cache) >= self.k.maxcache then
|
||||
table.insert(self.var.secondarycache, t)
|
||||
else
|
||||
table.insert(self.var.cache, t)
|
||||
end
|
||||
self:IncDec("numreclaim", 1)
|
||||
self:IncDec("totn", 1)
|
||||
self.var.maxn = math.max(self.var.maxn or 0, self.var.totn)
|
||||
self.var.tablechecks[t] = true
|
||||
end
|
||||
|
||||
|
||||
-- Reclaims multiple tables, can take 10 recursive sets or 20 non-recursives,
|
||||
-- or any combination of the two. Pass args in the following manner:
|
||||
-- table1, depth1, tabl2, depth2, table3, table4, table5, depth5, ...
|
||||
function lib:ReclaimMulti(a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15,a16,a17,a18,a19,a20)
|
||||
if not a1 then return end
|
||||
if type(a2) == "number" then
|
||||
self:Reclaim(a1, a2)
|
||||
self:ReclaimMulti(a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15,a16,a17,a18,a19,a20)
|
||||
else
|
||||
self:Reclaim(a1)
|
||||
self:ReclaimMulti(a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15,a16,a17,a18,a19,a20)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
-- Erases the table passed, nothing more nothing less :)
|
||||
-- Tables referenced inside the passed table are NOT erased
|
||||
function lib:Erase(t)
|
||||
if type(t) ~= "table" then return end
|
||||
if self.var.disabled then return {} end
|
||||
local mem = gcinfo()
|
||||
setmetatable(t, nil)
|
||||
for i in pairs(t) do
|
||||
t[i] = nil
|
||||
end
|
||||
t.reset = 1
|
||||
t.reset = nil
|
||||
table_setn(t, 0)
|
||||
self:IncDec("memfreed", math.abs(gcinfo() - mem))
|
||||
self:IncDec("numerased", 1)
|
||||
return t
|
||||
end
|
||||
|
||||
|
||||
-- Fills the table passed with the args passed
|
||||
function lib:Populate(t,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15,a16,a17,a18,a19,a20)
|
||||
if not t then return end
|
||||
if a1 ~= nil then table.insert(t, a1) end
|
||||
if a2 ~= nil then table.insert(t, a2) end
|
||||
if a3 ~= nil then table.insert(t, a3) end
|
||||
if a4 ~= nil then table.insert(t, a4) end
|
||||
if a5 ~= nil then table.insert(t, a5) end
|
||||
if a6 ~= nil then table.insert(t, a6) end
|
||||
if a7 ~= nil then table.insert(t, a7) end
|
||||
if a8 ~= nil then table.insert(t, a8) end
|
||||
if a9 ~= nil then table.insert(t, a9) end
|
||||
if a10 ~= nil then table.insert(t, a10) end
|
||||
if a11 ~= nil then table.insert(t, a11) end
|
||||
if a12 ~= nil then table.insert(t, a12) end
|
||||
if a13 ~= nil then table.insert(t, a13) end
|
||||
if a14 ~= nil then table.insert(t, a14) end
|
||||
if a15 ~= nil then table.insert(t, a15) end
|
||||
if a16 ~= nil then table.insert(t, a16) end
|
||||
if a17 ~= nil then table.insert(t, a17) end
|
||||
if a18 ~= nil then table.insert(t, a18) end
|
||||
if a19 ~= nil then table.insert(t, a19) end
|
||||
if a20 ~= nil then table.insert(t, a20) end
|
||||
return t
|
||||
end
|
||||
|
||||
|
||||
-- Same as Populate, but takes 10 key-value pairs instead
|
||||
function lib:PopulateHash(t,k1,v1,k2,v2,k3,v3,k4,v4,k5,v5,k6,v6,k7,v7,k8,v8,k9,v9,k10,v10)
|
||||
if not t then return end
|
||||
if k1 ~= nil then t[k1] = v1 end
|
||||
if k2 ~= nil then t[k2] = v2 end
|
||||
if k3 ~= nil then t[k3] = v3 end
|
||||
if k4 ~= nil then t[k4] = v4 end
|
||||
if k5 ~= nil then t[k5] = v5 end
|
||||
if k6 ~= nil then t[k6] = v6 end
|
||||
if k7 ~= nil then t[k7] = v7 end
|
||||
if k8 ~= nil then t[k8] = v8 end
|
||||
if k9 ~= nil then t[k9] = v9 end
|
||||
if k10 ~= nil then t[k10] = v10 end
|
||||
return t
|
||||
end
|
||||
|
||||
|
||||
function lib:IncDec(variable, diff)
|
||||
self.var[variable] = (self.var[variable] or 0) + diff
|
||||
end
|
||||
|
||||
|
||||
function lib:ItemsInSecondaryCache()
|
||||
for i in pairs(self.var.secondarycache) do return true end
|
||||
end
|
||||
|
||||
|
||||
function lib:GetSecondaryCacheSize()
|
||||
local n = 0
|
||||
for i in pairs(self.var.secondarycache) do n = n + 1 end
|
||||
return n
|
||||
end
|
||||
|
||||
|
||||
-- Prints out statistics on table recycling
|
||||
-- /script CompostLib:GetInstance("compost-1"):Stats()
|
||||
function lib:Stats()
|
||||
if self.var.disabled then ChatFrame1:AddMessage("CompostLib is disabled!")
|
||||
else ChatFrame1:AddMessage(
|
||||
string.format(
|
||||
"|cff00ff00New: %d|r | |cffffff00Recycled: %d|r | |cff00ffffMain: %d|r | |cffff0000Secondary: %d|r | |cffff8800Max %d|r | |cff888888Erases: %d|r | |cffff00ffMem Saved: %d KiB|r | |cffff0088Lost to GC: %d",
|
||||
self.var.numnew or 0,
|
||||
self.var.numrecycled or 0,
|
||||
table.getn(self.var.cache),
|
||||
self:GetSecondaryCacheSize(),
|
||||
self.var.maxn or 0,
|
||||
(self.var.numerased or 0) - (self.var.numreclaim or 0),
|
||||
(self.var.memfreed or 0) + 32/1024*(self.var.numrecycled or 0),
|
||||
(self.var.numreclaim or 0) - (self.var.numrecycled or 0) - table.getn(self.var.cache)))
|
||||
end
|
||||
end
|
||||
|
||||
setmetatable(lib, { __call = lib.Acquire })
|
||||
|
||||
--------------------------------
|
||||
-- Load this bitch! --
|
||||
--------------------------------
|
||||
AceLibrary:Register(lib, vmajor, vminor, activate)
|
||||
lib = nil
|
||||
@@ -0,0 +1,156 @@
|
||||
--[[
|
||||
Name: Crayon-2.0
|
||||
Revision: $Rev: 7622 $
|
||||
Author(s): ckknight (ckknight@gmail.com)
|
||||
Website: http://ckknight.wowinterface.com/
|
||||
Documentation: http://wiki.wowace.com/index.php/Crayon-2.0
|
||||
SVN: http://svn.wowace.com/root/trunk/CrayonLib/Crayon-2.0
|
||||
Description: A library to provide coloring tools.
|
||||
Dependencies: AceLibrary
|
||||
]]
|
||||
|
||||
--Theondry (theondry@gmail.com) added the purple. yell at me if it's wrong, please
|
||||
|
||||
local MAJOR_VERSION = "Crayon-2.0"
|
||||
local MINOR_VERSION = "$Revision: 7622 $"
|
||||
|
||||
if not AceLibrary then error(MAJOR_VERSION .. " requires AceLibrary") end
|
||||
if not AceLibrary:IsNewVersion(MAJOR_VERSION, MINOR_VERSION) then return end
|
||||
|
||||
local Crayon = {}
|
||||
|
||||
Crayon.COLOR_HEX_RED = "ff0000"
|
||||
Crayon.COLOR_HEX_ORANGE = "ff7f00"
|
||||
Crayon.COLOR_HEX_YELLOW = "ffff00"
|
||||
Crayon.COLOR_HEX_GREEN = "00ff00"
|
||||
Crayon.COLOR_HEX_WHITE = "ffffff"
|
||||
Crayon.COLOR_HEX_COPPER = "eda55f"
|
||||
Crayon.COLOR_HEX_SILVER = "c7c7cf"
|
||||
Crayon.COLOR_HEX_GOLD = "ffd700"
|
||||
Crayon.COLOR_HEX_PURPLE = "9980CC"
|
||||
|
||||
function Crayon:Colorize(hexColor, text)
|
||||
return "|cff" .. tostring(hexColor or 'ffffff') .. tostring(text) .. "|r"
|
||||
end
|
||||
function Crayon:Red(text) return self:Colorize(self.COLOR_HEX_RED, text) end
|
||||
function Crayon:Orange(text) return self:Colorize(self.COLOR_HEX_ORANGE, text) end
|
||||
function Crayon:Yellow(text) return self:Colorize(self.COLOR_HEX_YELLOW, text) end
|
||||
function Crayon:Green(text) return self:Colorize(self.COLOR_HEX_GREEN, text) end
|
||||
function Crayon:White(text) return self:Colorize(self.COLOR_HEX_WHITE, text) end
|
||||
function Crayon:Copper(text) return self:Colorize(self.COLOR_HEX_COPPER, text) end
|
||||
function Crayon:Silver(text) return self:Colorize(self.COLOR_HEX_SILVER, text) end
|
||||
function Crayon:Gold(text) return self:Colorize(self.COLOR_HEX_GOLD, text) end
|
||||
function Crayon:Purple(text) return self:Colorize(self.COLOR_HEX_PURPLE, text) end
|
||||
|
||||
local inf = 1/0
|
||||
|
||||
function Crayon:GetThresholdColor(quality, worst, worse, normal, better, best)
|
||||
self:argCheck(quality, 2, "number")
|
||||
if quality ~= quality or quality == inf or quality == -inf then
|
||||
return 1, 1, 1
|
||||
end
|
||||
if not best then
|
||||
worst = 0
|
||||
worse = 0.25
|
||||
normal = 0.5
|
||||
better = 0.75
|
||||
best = 1
|
||||
end
|
||||
|
||||
if worst < best then
|
||||
if (worse == better and quality == worse) or (worst == best and quality == worst) then
|
||||
return 1, 1, 0
|
||||
elseif quality <= worst then
|
||||
return 1, 0, 0
|
||||
elseif quality <= worse then
|
||||
return 1, 0.5 * (quality - worst) / (worse - worst), 0
|
||||
elseif quality <= normal then
|
||||
return 1, 0.5 + 0.5 * (quality - worse) / (normal - worse), 0
|
||||
elseif quality <= better then
|
||||
return 1 - 0.5 * (quality - normal) / (better - normal), 1, 0
|
||||
elseif quality <= best then
|
||||
return 0.5 - 0.5 * (quality - better) / (best - better), 1, 0
|
||||
else
|
||||
return 0, 1, 0
|
||||
end
|
||||
else
|
||||
if (worse == better and quality == worse) or (worst == best and quality == worst) then
|
||||
return 1, 1, 0
|
||||
elseif quality >= worst then
|
||||
return 1, 0, 0
|
||||
elseif quality >= worse then
|
||||
return 1, 0.5 - 0.5 * (quality - worse) / (worst - worse), 0
|
||||
elseif quality >= normal then
|
||||
return 1, 1 - 0.5 * (quality - normal) / (worse - normal), 0
|
||||
elseif quality >= better then
|
||||
return 0.5 + 0.5 * (quality - better) / (normal - better), 1, 0
|
||||
elseif quality >= best then
|
||||
return 0.5 * (quality - best) / (better - best), 1, 0
|
||||
else
|
||||
return 0, 1, 0
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function Crayon:GetThresholdHexColor(quality, worst, worse, normal, better, best)
|
||||
local r, g, b = self:GetThresholdColor(quality, worst, worse, normal, better, best)
|
||||
return string.format("%02x%02x%02x", r*255, g*255, b*255)
|
||||
end
|
||||
|
||||
function Crayon:GetThresholdColorTrivial(quality, worst, worse, normal, better, best)
|
||||
self:argCheck(quality, 2, "number")
|
||||
if quality ~= quality or quality == inf or quality == -inf then
|
||||
return 1, 1, 1
|
||||
end
|
||||
if not best then
|
||||
worst = 0
|
||||
worse = 0.25
|
||||
normal = 0.5
|
||||
better = 0.75
|
||||
best = 1
|
||||
end
|
||||
|
||||
if worst < best then
|
||||
if worse == better and normal == worse then
|
||||
return 1, 1, 0
|
||||
elseif quality <= worst then
|
||||
return 1, 0, 0
|
||||
elseif quality <= worse then
|
||||
return 1, 0.5 * (quality - worst) / (worse - worst), 0
|
||||
elseif quality <= normal then
|
||||
return 1, 0.5 + 0.5 * (quality - worse) / (normal - worse), 0
|
||||
elseif quality <= better then
|
||||
return 1 - (quality - normal) / (better - normal), 1, 0
|
||||
elseif quality <= best then
|
||||
local x = 0.5 * (quality - better) / (best - better)
|
||||
return x, 1 - x, x
|
||||
else
|
||||
return 0.5, 0.5, 0.5
|
||||
end
|
||||
else
|
||||
if worse == better and normal == worse then
|
||||
return 1, 1, 0
|
||||
elseif quality >= worst then
|
||||
return 1, 0, 0
|
||||
elseif quality >= worse then
|
||||
return 1, 0.5 - 0.5 * (quality - worse) / (worst - worse), 0
|
||||
elseif quality >= normal then
|
||||
return 1, 1 - 0.5 * (quality - normal) / (worse - normal), 0
|
||||
elseif quality >= better then
|
||||
return (quality - better) / (normal - better), 1, 0
|
||||
elseif quality >= best then
|
||||
local x = 0.5 * (quality - best) / (better - best)
|
||||
return 0.5 - x, 0.5 + x, 0.5 - x
|
||||
else
|
||||
return 0.5, 0.5, 0.5
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function Crayon:GetThresholdHexColorTrivial(quality, worst, worse, normal, better, best)
|
||||
local r, g, b = self:GetThresholdColorTrivial(quality, worst, worse, normal, better, best)
|
||||
return string.format("%02x%02x%02x", r*255, g*255, b*255)
|
||||
end
|
||||
|
||||
AceLibrary:Register(Crayon, MAJOR_VERSION, MINOR_VERSION)
|
||||
Crayon = nil
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user