Import VanillaGuide 1.04.2 (mrmr) as upstream baseline

This commit is contained in:
2026-05-11 21:46:17 +02:00
commit 57f1a7e3b5
92 changed files with 23071 additions and 0 deletions
+995
View File
@@ -0,0 +1,995 @@
--[[
Name: AceAddon-2.0
Revision: $Rev: 16523 $
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: 16523 $"
-- 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, CREDITS, 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"
CREDITS = "Credits" -- fix
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"
CREDITS = "Credits" -- fix
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 = "웹사ì´íЏ"
CREDITS = "Credits" -- fix
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 = "網站"
CREDITS = "Credits" -- fix
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"
CREDITS = "Credits" -- fix
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"
CREDITS = "Credits"
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 pairs(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.credits == nil then
addon.credits = GetAddOnMetadata(name, "X-Credits")
addon.credits = stripSpaces(addon.credits)
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.credits then
print(" - |cffffff7f" .. CREDITS .. ":|r " .. tostring(self.credits))
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
+238
View File
@@ -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)
+969
View File
@@ -0,0 +1,969 @@
--[[
Name: AceEvent-2.0
Revision: $Rev: 17136 $
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: 17136 $"
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 lastEvent = AceEvent.currentEvent
AceEvent.currentEvent = 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
AceEvent.currentEvent = lastEvent
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 tmp = {}
local function OnUpdate()
local t = GetTime()
for k,v in pairs(delayRegistry) do
tmp[k] = true
end
for k in pairs(tmp) do
local v = delayRegistry[k]
if v then
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
end
end
for k in pairs(tmp) do
tmp[k] = nil
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)
+751
View File
@@ -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)
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
File diff suppressed because it is too large Load Diff