vanilla-wow-addons – Rev 1
?pathlinks?
--[[
Name: SpellCache-1.0
Revision: $Rev: 11059 $
Author(s): Nightdew (denzsolnightdew@gmail.com)
Website: http://www.wowace.com/index.php/SpellCache-1.0
Documentation: http://www.wowace.com/index.php/SpellCache-1.0
SVN: http://svn.wowace.com/root/trunk/SpellCache/SpellCache-1.0
Description: Library that caches spells to speed up look ups
Dependencies: AceLibrary, AceDebug-2.0, AceEvent-2.0, Deformat-2.0
]]
--, Gratuity-2.0
local MAJOR_VERSION = "SpellCache-1.0"
local MINOR_VERSION = "$Revision: 11059 $"
if (not AceLibrary) then
error(MAJOR_VERSION .. " requires AceLibrary.")
elseif (not AceLibrary:IsNewVersion(MAJOR_VERSION, MINOR_VERSION)) then
return
end
local function CheckDependencies(dependencies)
for index, value in ipairs(dependencies) do
if (not AceLibrary:HasInstance(value)) then
error(format("%s requires %s to function properly", MAJOR_VERSION, value))
end
end
end
local dependencyLibraries = {
"AceDebug-2.0",
"AceEvent-2.0",
"Deformat-2.0",
--"Gratuity-2.0"
}
CheckDependencies(dependencyLibraries)
local aceDebug = AceLibrary("AceDebug-2.0")
local aceEvent = AceLibrary("AceEvent-2.0")
local deformat = AceLibrary("Deformat-2.0")
--Create Library Object
local SpellCache = {}
--Embed all needed mixins into the Library Object SpellCache
aceDebug:embed(SpellCache)
aceEvent:embed(SpellCache)
--
-- Initialization methods.
--
local function GetSpellRankPattern(self, spellRank)
local rankPattern, changeCount = string.gsub(spellRank, "%d+", "%%d")
if (changeCount > 0) then
self.RankPattern = rankPattern;
self.FullPattern = format("%s(%s)", "%s", rankPattern)
self:LevelDebug(2, "DetectRankPattern", spellRank, self.RankPattern, self.FullPattern)
return rankPattern
end
end
local function GetSpellRankNumber(self, spellRank)
self:LevelDebug(3, "GetSpellRankNumber1", spellRank)
if (spellRank and (spellRank ~= "")) then
local rankPattern = self.RankPattern or GetSpellRankPattern(self, spellRank)
if (rankPattern) then
self:LevelDebug(3, "GetSpellRankNumber2", rankPattern, spellRank)
local spellRankNumber = self:GetRankNumber(spellRank)
return spellRankNumber
end
end
end
local function ResetVariables(self)
if (not self:IsInitialized()) then
return
end
--clear hash
setmetatable(self.hash, nil)
for k in pairs(self.hash) do
self.hash[k] = nil
end
table.setn(self.hash, 0);
local spellTabCount = GetNumSpellTabs()
local tabName, tabTexture, tabStart, tabOffset = GetSpellTabInfo(spellTabCount)
local spellCount = tabStart + tabOffset
self:LevelDebug(3, "ResetVariables", spellTabCount, tabName, tabTexture, tabStart, tabOffset, spellCount)
local spellData, spellName, spellRank, spellNamePrevious, spellNameNew = nil;
for i = 1, spellCount do
spellName, spellRank = GetSpellName(i, BOOKTYPE_SPELL)
spellNameNew = spellNamePrevious ~= spellName
spellNamePrevious = spellName
spellData = self.data[spellName] or {}
if (spellNameNew) then
self.hash[i] = spellName
self.data[spellName] = spellData
spellData.IdStart = i
else
self.hash[i] = spellData.IdStart
end
spellData.IdStop = i
spellData.Rank = GetSpellRankNumber(self, spellRank);
self:LevelDebug(3,
spellData.IdStart,
spellData.IdStop,
spellData.Rank
)
end
self:TriggerEvent("SpellCache_Updated")
end
local function InitializeVariables(self)
--will collect spells as they are being cast.
--SpellName -> Data
self.data = {}
--SpellId -> SpellName or SpellId
self.hash = {}
ResetVariables(self)
end
--
-- Event Registration
--
local function InitializeEventRegisters(self)
self:RegisterEvent("LEARNED_SPELL_IN_TAB")
self:RegisterEvent("PLAYER_ENTERING_WORLD", "LEARNED_SPELL_IN_TAB")
--Supposedly not needed, and will spam too much
--self:RegisterEvent("SPELLS_CHANGED", "LEARNED_SPELL_IN_TAB")
end
--update whatever spells are there!
function SpellCache:LEARNED_SPELL_IN_TAB()
self.isInitialized = true
ResetVariables(self)
end
function SpellCache:IsInitialized()
return self.isInitialized == true
end
--
-- Activate method
--
local function activate(self, oldLib, oldDeactivate)
--self:SetDebugLevel(3);
if (oldLib) then
oldLib:UnregisterAllEvents()
end
--Default code to clean up the oldlib
if (oldDeactivate) then
oldDeactivate(oldLib)
end
InitializeVariables(self)
InitializeEventRegisters(self)
end
--
-- Util Methods
--
--
-- External Methods
--
function SpellCache:GetRankNumber(spellRankText)
self:LevelDebug(3, "SpellCache:GetRankNumber1", spellRankText)
self:argCheck(spellRankText, 2, "string")
local spellRankNumber = deformat:Deformat(spellRankText, self.RankPattern)
self:LevelDebug(3, "SpellCache:GetRankNumber2", spellRankText, self.RankPattern, spellRankNumber)
return spellRankNumber
end
function SpellCache:GetRankText(spellRankNumber)
self:argCheck(spellRankNumber, 2, "number")
local spellRankText = format(self.RankPattern, spellRankNumber)
self:LevelDebug(2, "GetRankText", spellRankNumber, self.RankPattern, spellRankText)
return spellRankText
end
function SpellCache:GetRanklessSpellName(spellName)
self:argCheck(spellName, 2, "string")
--self:LevelDebug(2, "GetRanklessSpellName1", spellName)
--For those that like to cast spells with SpellName() lets take out the ()
spellName = string.gsub(spellName, "%(%)$", "")
--self:LevelDebug(2, "GetRanklessSpellName2", spellName)
local sName, sRank = deformat:Deformat(spellName, self.FullPattern)
self:LevelDebug(2, "GetRanklessSpellName", spellName, sName, sRank)
if (sName and sRank) then
return sName, sRank
end
return spellName
end
function SpellCache:GetSpellNameText(spellName, spellRankNumber)
self:argCheck(spellName, 2, "string")
self:argCheck(spellRankNumber, 3, "number", "nil")
local fullSpellName
if (not spellRankNumber) then
fullSpellName = spellName
else
fullSpellName = format(self.FullPattern, spellName, spellRankNumber)
end
self:LevelDebug(2, "GetSpellNameText", spellName, spellRankNumber, self.FullPattern, fullSpellName)
return fullSpellName
end
-- 24, ignore all
-- Arcane Intellect, nil
-- Arcane Intellect, 3
-- Arcane Intellect, Rank 3
-- Arcane Intellect(Rank 2), nil
-- Arcane Intellect(Rank 2), 3
-- Arcane Intellect(Rank 2), Rank 3
function SpellCache:GetSpellData(spellNameOrId, spellRankNumberOrText)
self:argCheck(spellNameOrId, 2, "string", "number")
self:argCheck(spellRank, 3, "string", "number", "nil")
self:LevelDebug(2, ">GetSpellData", spellNameOrId, spellRankNumberOrText)
local sId, sName, sRank
if (type(spellNameOrId) == "number") then
sId = tonumber(spellNameOrId)
sName = self.hash[sId]
--Doesnt exist
if (not sName) then
return
end
--sId > IdStart
if (type(sName) == "number") then
sName = self.hash[sName]
end
self:LevelDebug(2, "GetSpellData1", sId, sName)
else
sName, sRank = self:GetRanklessSpellName(spellNameOrId)
if (not sRank) then
sRank = spellRankNumberOrText;
if (type(sRank) == "string") then
self:LevelDebug(2, "GetSpellData2", sRank)
sRank = GetSpellRankNumber(self, sRank);
self:LevelDebug(2, "GetSpellData3", sRank)
end
end
end
--if we cant find any data
local spellData = self.data[sName]
if (not spellData) then
self:LevelDebug(1, "<GetSpellData", spellNameOrId)
return;
end;
if (sId) then
sRank = spellData.Rank and sId - spellData.IdStart + 1 or nil
else
if (not spellData.Rank) then
sRank = nil
elseif (not sRank) then
sRank = spellData.Rank
elseif ((sRank) and (sRank > spellData.Rank)) then
sRank = spellData.Rank
elseif ((sRank) and (sRank < 1)) then
sRank = 1
end
sId = sRank and spellData.IdStart + sRank -1 or spellData.IdStart
end
local sRankText, sFullText
if (sRank) then
sRankText = self:GetRankText(sRank)
end
sFullText = self:GetSpellNameText(sName, sRank)
self:LevelDebug(1, "<GetSpellData", sName, sRankText, sId, sFullText, sRank, spellData.IdStart, spellData.IdStop, spellData.Rank)
return sName, sRankText, sId, sFullText, sRank, spellData.IdStart, spellData.IdStop, spellData.Rank
end
--
-- Final Registration of the library.
--
AceLibrary:Register(SpellCache, MAJOR_VERSION, MINOR_VERSION, activate)
SpellCache = AceLibrary(MAJOR_VERSION)