--[[--------------------------------------------------------------------------------- AceLibrary by Cladhaire <cladhaire@gmail.com> Based on the concept by Iriel <iriel@vigilance-committee.org> Design influenced by Tekkub <tekkub@gmail.com> This aims to be a standard for Ace embedded libraries, as the general stub they all use to register themselves. This concept of embedded libraries came as a result of a number of discussions in both #wowace and #wowi-lounge. See http://www.iriel.org/wow/addondev/embedlibrary1.html for more information----------------------------------------------------------------------------------]]-- DO NOT CHANGE THESE VALUES -----------------------------local ACELIBRARY_MAJOR = "AceLibrary"local ACELIBRARY_MINOR = 2-- DO NOT CHANGE THESE VALUES ------------------------------local genv = getfenv(0)local previous = genv[ACELIBRARY_MAJOR]if previous and not previous:NewVersion(ACELIBRARY_MAJOR, ACELIBRARY_MINOR) then returnendlocal mt = {}local AceLibrary = setmetatable({}, mt)-- Instance replacement method. Handles "upgrading" to a new versionfunction AceLibrary:ReplaceInstance(old,new) for k,v in pairs(old) do old[k]=nil end for k,v in pairs(new) do old[k]=v endend-- Returns a new stub. This allows multiple libraries to use the same stubfunction AceLibrary:NewStub(name) local newStub = {} self:ReplaceInstance(newStub, self) newStub.versions = {} newStub.libName = name return newStubend-- Returns true if the supplied version would be an upgrade to the current version-- This allows for bypass code in library declaration.function AceLibrary:NewVersion(version, minor) local versionData = self.versions[version] if not versionData or versionData.minor < minor then return true endend-- Returns the version of the given library with the highest minor revisionfunction AceLibrary:GetInstance(version) if not version then error("You must specify a version when requesting a library instance", 2) end local versionData = self.versions[version] if not versionData then error(string.format("Cannot find a library instance of %s.", version), 2) return end return versionData.instanceend-- Syntax sugar. AceLibrary("FooBar-1.0")mt.__call = AceLibrary.GetInstance-- Registers a new version of a given library. Takes the library object.function AceLibrary:Register(newInstance) if not newInstance.GetLibraryVersion then return end local version,minor = newInstance:GetLibraryVersion() local versionData = self.versions[version] if not versionData then -- This is new versionData = { instance=newInstance, minor=minor, old={}} self.versions[version] = versionData newInstance:LibActivate(self) return newInstance end if minor <= versionData.minor then -- This one is already obsolete if newInstance.LibDiscard then newInstance:LibDiscard() end return versionData.instance end -- This is an update local oldInstance = versionData.instance local oldList = versionData.old versionData.instance = newInstance versionData.minor = minor local skipCopy = newInstance:LibActivate(self, oldInstance, oldList) table.insert(oldList, oldInstance) if not skipCopy then for i,old in ipairs(oldList) do self:ReplaceInstance(old, newInstance) end end return newInstanceendfunction AceLibrary:GetLibraryVersion() return ACELIBRARY_MAJOR, ACELIBRARY_MINORendfunction AceLibrary:LibActivate(stub, oldInstance, oldList) if not self.versions then if oldInstance then self.versions = oldInstance.versions else self.versions = {} end end -- Expose the library in the global environment genv[ACELIBRARY_MAJOR] = selfendif previous then previous:Register(AceLibrary)else AceLibrary.versions = {} AceLibrary.libName = version AceLibrary:Register(AceLibrary)end