WoWInterface SVN RecapFu

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /trunk/FuBar_RecapFu/libs/AceLibrary
    from Rev 2 to Rev 3
    Reverse comparison

Rev 2 → Rev 3

AceLibrary.lua
1,13 → 1,13
--[[
Name: AceLibrary
Revision: $Rev: 29796 $
Revision: $Rev: 1091 $
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: 29796 $
Revision: $Rev: 1091 $
Website: http://www.wowace.com/
Documentation: http://www.wowace.com/index.php/AceLibrary
SVN: http://svn.wowace.com/root/trunk/Ace2/AceLibrary
SVN: http://svn.wowace.com/wowace/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
18,28 → 18,54
]]
 
local ACELIBRARY_MAJOR = "AceLibrary"
local ACELIBRARY_MINOR = "$Revision: 29796 $"
local ACELIBRARY_MINOR = 90000 + tonumber(("$Revision: 1091 $"):match("(%d+)"))
 
local _G = getfenv(0)
local previous = _G[ACELIBRARY_MAJOR]
if previous and not previous:IsNewVersion(ACELIBRARY_MAJOR, ACELIBRARY_MINOR) then return end
 
do
-- LibStub is a simple versioning stub meant for use in Libraries. http://www.wowace.com/wiki/LibStub for more info
-- LibStub is hereby placed in the Public Domain -- Credits: Kaelten, Cladhaire, ckknight, Mikk, Ammo, Nevcairiel, joshborke
local LIBSTUB_MAJOR, LIBSTUB_MINOR = "LibStub", 2 -- NEVER MAKE THIS AN SVN REVISION! IT NEEDS TO BE USABLE IN ALL REPOS!
local LibStub = _G[LIBSTUB_MAJOR]
 
if not LibStub or LibStub.minor < LIBSTUB_MINOR then
LibStub = LibStub or {libs = {}, minors = {} }
_G[LIBSTUB_MAJOR] = LibStub
LibStub.minor = LIBSTUB_MINOR
 
function LibStub:NewLibrary(major, minor)
assert(type(major) == "string", "Bad argument #2 to `NewLibrary' (string expected)")
minor = assert(tonumber(strmatch(minor, "%d+")), "Minor version must either be a number or contain a number.")
local oldminor = self.minors[major]
if oldminor and oldminor >= minor then return nil end
self.minors[major], self.libs[major] = minor, self.libs[major] or {}
return self.libs[major], oldminor
end
 
function LibStub:GetLibrary(major, silent)
if not self.libs[major] and not silent then
error(("Cannot find a library instance of %q."):format(tostring(major)), 2)
end
return self.libs[major], self.minors[major]
end
 
function LibStub:IterateLibraries() return pairs(self.libs) end
setmetatable(LibStub, { __call = LibStub.GetLibrary })
end
end
local LibStub = _G.LibStub
 
-- If you don't want AceLibrary to enable libraries that are LoadOnDemand but
-- disabled in the addon screen, set this to true.
local DONT_ENABLE_LIBRARIES = nil
 
local function safecall(func,...)
local success, err = pcall(func,...)
if not success then geterrorhandler()(err:find("%.lua:%d+:") and err or (debugstack():match("\n(.-: )in.-\n") or "") .. err) end
end
 
local WoW22 = false
if type(GetBuildInfo) == "function" then
local success, buildinfo = pcall(GetBuildInfo)
if success and type(buildinfo) == "string" then
local num = tonumber(buildinfo:match("^(%d+%.%d+)"))
if num and num >= 2.2 then
WoW22 = true
end
end
end
 
-- @table AceLibrary
-- @brief System to handle all versioning of libraries.
local AceLibrary = {}
53,7 → 79,7
 
local stack = debugstack()
if not message then
local _,_,second = stack:find("\n(.-)\n")
local second = stack:match("\n(.-)\n")
message = "error raised! " .. second
else
local arg = { ... } -- not worried about table creation, as errors don't happen often
99,34 → 125,19
return _G.error(message, 2)
end
 
local assert
if not WoW22 then
function assert(self, condition, message, ...)
if not condition then
if not message then
local stack = debugstack()
local _,_,second = stack:find("\n(.-)\n")
message = "assertion failed! " .. second
end
return error(self, message, ...)
end
return condition
end
end
 
local type = type
local function argCheck(self, arg, num, kind, kind2, kind3, kind4, kind5)
if type(num) ~= "number" then
return error(self, "Bad argument #3 to `argCheck' (number expected, got %s)", type(num))
elseif type(kind) ~= "string" then
return 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 stack = debugstack()
local _,_,func = stack:find("`argCheck'.-([`<].-['>])")
local func = stack:match("`argCheck'.-([`<].-['>])")
if not func then
_,_,func = stack:find("([`<].-['>])")
func = stack:match("([`<].-['>])")
end
if kind5 then
return 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)
180,16 → 191,17
end
 
local function svnRevisionToNumber(text)
if type(text) == "string" then
local kind = type(text)
if kind == "number" or tonumber(text) then
return tonumber(text)
elseif kind == "string" then
if text:find("^%$Revision: (%d+) %$$") then
return tonumber((text:gsub("^%$Revision: (%d+) %$$", "%1")))
return tonumber((text:match("^%$Revision: (%d+) %$$")))
elseif text:find("^%$Rev: (%d+) %$$") then
return tonumber((text:gsub("^%$Rev: (%d+) %$$", "%1")))
return tonumber((text:match("^%$Rev: (%d+) %$$")))
elseif text:find("^%$LastChangedRevision: (%d+) %$$") then
return tonumber((text:gsub("^%$LastChangedRevision: (%d+) %$$", "%1")))
return tonumber((text:match("^%$LastChangedRevision: (%d+) %$$")))
end
elseif type(text) == "number" then
return text
end
return nil
end
256,8 → 268,10
-- @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 = {}
local function copyTable(from, to)
if not to then
to = {}
end
for k,v in pairs(from) do
to[k] = v
end
341,10 → 355,25
end
end
 
local function TryToEnable(addon)
if DONT_ENABLE_LIBRARIES then return end
local isondemand = IsAddOnLoadOnDemand(addon)
if isondemand then
local _, _, _, enabled = GetAddOnInfo(addon)
EnableAddOn(addon)
local _, _, _, _, loadable = GetAddOnInfo(addon)
if not loadable and not enabled then
DisableAddOn(addon)
end
 
return loadable
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
-- @return If library is found and loaded, true is return. If not loadable, false is returned.
-- If the library has been requested previously, nil is returned.
local function TryToLoadStandalone(major)
if not AceLibrary.scannedlibs then AceLibrary.scannedlibs = {} end
353,18 → 382,28
AceLibrary.scannedlibs[major] = true
 
local name, _, _, enabled, loadable = GetAddOnInfo(major)
 
loadable = (enabled and loadable) or TryToEnable(name)
 
local loaded = false
if loadable then
return LoadAddOn(name)
loaded = true
LoadAddOn(name)
end
 
for i=1,GetNumAddOns() do
if GetAddOnMetadata(i, "X-AceLibrary-"..major) then
local name, _, _, enabled, loadable = GetAddOnInfo(i)
 
local field = "X-AceLibrary-" .. major
for i = 1, GetNumAddOns() do
if GetAddOnMetadata(i, field) then
name, _, _, enabled, loadable = GetAddOnInfo(i)
 
loadable = (enabled and loadable) or TryToEnable(name)
if loadable then
return LoadAddOn(name)
loaded = true
LoadAddOn(name)
end
end
end
return loaded
end
 
-- @method IsNewVersion
388,6 → 427,10
end
end
argCheck(self, minor, 3, "number")
local lib, oldMinor = LibStub:GetLibrary(major, true)
if lib then
return oldMinor < minor
end
local data = self.libs[major]
if not data then
return true
405,7 → 448,11
if minor ~= false then
TryToLoadStandalone(major)
end
 
 
local lib, ver = LibStub:GetLibrary(major, true)
if not lib and self.libs[major] then
lib, ver = self.libs[major].instance, self.libs[major].minor
end
if minor then
if type(minor) == "string" then
local m = svnRevisionToNumber(minor)
416,12 → 463,12
end
end
argCheck(self, minor, 3, "number")
if not self.libs[major] then
return
if not lib then
return false
end
return self.libs[major].minor == minor
return ver == minor
end
return self.libs[major] and true
return not not lib
end
 
-- @method GetInstance
431,12 → 478,18
-- @return The library with the given major/minor version.
function AceLibrary:GetInstance(major, minor)
argCheck(self, major, 2, "string")
TryToLoadStandalone(major)
if minor ~= false then
TryToLoadStandalone(major)
end
 
local data = self.libs[major]
local data, ver = LibStub:GetLibrary(major, true)
if not data then
_G.error(("Cannot find a library instance of %s."):format(major), 2)
return
if self.libs[major] then
data, ver = self.libs[major].instance, self.libs[major].minor
else
_G.error(("Cannot find a library instance of %s."):format(major), 2)
return
end
end
if minor then
if type(minor) == "string" then
448,11 → 501,11
end
end
argCheck(self, minor, 2, "number")
if data.minor ~= minor then
if ver ~= minor then
_G.error(("Cannot find a library instance of %s, minor version %d."):format(major, minor), 2)
end
end
return data.instance
return data
end
 
-- Syntax sugar. AceLibrary("FooBar-1.0")
462,6 → 515,8
 
local AceEvent
 
local tmp = {}
 
-- @method Register
-- @brief Registers a new version of a given library.
-- @param newInstance the library to register
510,7 → 565,11
local data = self.libs[major]
if not data then
-- This is new
local instance = copyTable(newInstance)
if LibStub:GetLibrary(major, true) then
error(self, "Cannot register library %q. It is already registered with LibStub.", major)
end
local instance = LibStub:NewLibrary(major, minor)
copyTable(newInstance, instance)
crawlReplace(instance, instance, newInstance)
destroyTable(newInstance)
if AceLibrary == newInstance then
529,9 → 588,6
if not rawget(instance, 'error') then
rawset(instance, 'error', error)
end
if not WoW22 and not rawget(instance, 'assert') then
rawset(instance, 'assert', assert)
end
if not rawget(instance, 'argCheck') then
rawset(instance, 'argCheck', argCheck)
end
541,25 → 597,24
addToPositions(instance, major)
if activateFunc then
safecall(activateFunc, instance, nil, nil) -- no old version, so explicit nil
 
--[[ if major ~= ACELIBRARY_MAJOR then
for k,v in pairs(_G) do
if v == instance then
geterrorhandler()((debugstack():match("(.-: )in.-\n") or "") .. ("Cannot register library %q. It is part of the global table in _G[%q]."):format(major, k))
end
end
end]]
end
 
if externalFunc then
for k,data in pairs(self.libs) do
for k, data_instance in LibStub:IterateLibraries() do -- all libraries
tmp[k] = data_instance
end
for k, data in pairs(self.libs) do -- Ace libraries which may not have been registered with LibStub
tmp[k] = data.instance
end
for k, data_instance in pairs(tmp) do
if k ~= major then
safecall(externalFunc, instance, k, data.instance)
safecall(externalFunc, instance, k, data_instance)
end
tmp[k] = nil
end
end
 
for k,data in pairs(self.libs) do
for k,data in pairs(self.libs) do -- only Ace libraries
if k ~= major and data.externalFunc then
safecall(data.externalFunc, data.instance, major, instance)
end
573,33 → 628,36
 
return instance
end
local instance = data.instance
if minor <= data.minor then
-- This one is already obsolete, raise an error.
_G.error(("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"):format(major, data.minor, minor, major, minor), 2)
return
end
local instance = data.instance
-- This is an update
local oldInstance = {}
 
local libStubInstance = LibStub:GetLibrary(major, true)
if not libStubInstance then -- non-LibStub AceLibrary registered the library
-- pass
elseif libStubInstance ~= instance then
error(self, "Cannot register library %q. It is already registered with LibStub.", major)
else
LibStub:NewLibrary(major, minor) -- upgrade the minor version
end
 
addToPositions(newInstance, major)
local isAceLibrary = (AceLibrary == newInstance)
local old_error, old_assert, old_argCheck, old_pcall
local old_error, old_argCheck, old_pcall
if isAceLibrary then
self = instance
AceLibrary = instance
 
old_error = instance.error
if not WoW22 then
old_assert = instance.assert
end
old_argCheck = instance.argCheck
old_pcall = instance.pcall
 
self.error = error
if not WoW22 then
self.assert = assert
end
self.argCheck = argCheck
self.pcall = pcall
end
609,15 → 667,12
data.minor = minor
data.deactivateFunc = deactivateFunc
data.externalFunc = externalFunc
rawset(instance, 'GetLibraryVersion', function(self)
rawset(instance, 'GetLibraryVersion', function()
return major, minor
end)
if not rawget(instance, 'error') then
rawset(instance, 'error', error)
end
if not WoW22 and not rawget(instance, 'assert') then
rawset(instance, 'assert', assert)
end
if not rawget(instance, 'argCheck') then
rawset(instance, 'argCheck', argCheck)
end
631,9 → 686,6
if not rawget(i, 'error') or i.error == old_error then
rawset(i, 'error', error)
end
if not WoW22 and (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
644,44 → 696,57
end
end
if activateFunc then
safecall(activateFunc, instance, oldInstance, oldDeactivateFunc)
 
--[[ if major ~= ACELIBRARY_MAJOR then
for k,v in pairs(_G) do
if v == instance then
geterrorhandler()((debugstack():match("(.-: )in.-\n") or "") .. ("Cannot register library %q. It is part of the global table in _G[%q]."):format(major, k))
end
end
end]]
safecall(activateFunc, instance, oldInstance, oldDeactivateFunc)
else
safecall(oldDeactivateFunc, oldInstance)
end
oldInstance = nil
 
if externalFunc then
for k,data in pairs(self.libs) do
for k, data_instance in LibStub:IterateLibraries() do -- all libraries
tmp[k] = data_instance
end
for k, data in pairs(self.libs) do -- Ace libraries which may not have been registered with LibStub
tmp[k] = data.instance
end
for k, data_instance in pairs(tmp) do
if k ~= major then
safecall(externalFunc, instance, k, data.instance)
safecall(externalFunc, instance, k, data_instance)
end
tmp[k] = nil
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
local t = {}
for major, instance in LibStub:IterateLibraries() do
t[major] = instance
end
for major, data in pairs(self.libs) do
t[major] = data.instance
end
return pairs(t)
end
 
local function manuallyFinalize(major, instance)
if AceLibrary.libs[major] then
-- don't work on Ace libraries
return
end
local finalizedExternalLibs = AceLibrary.finalizedExternalLibs
if finalizedExternalLibs[major] then
return
end
finalizedExternalLibs[major] = true
 
for k,data in pairs(AceLibrary.libs) do -- only Ace libraries
if k ~= major and data.externalFunc then
safecall(data.externalFunc, data.instance, major, instance)
end
end
return iter, self.libs, nil
end
 
-- @function Activate
699,6 → 764,18
if not self.positions then
self.positions = oldLib and oldLib.positions or setmetatable({}, { __mode = "k" })
end
self.finalizedExternalLibs = oldLib and oldLib.finalizedExternalLibs or {}
self.frame = oldLib and oldLib.frame or CreateFrame("Frame")
self.frame:UnregisterAllEvents()
self.frame:RegisterEvent("ADDON_LOADED")
self.frame:SetScript("OnEvent", function()
for major, instance in LibStub:IterateLibraries() do
manuallyFinalize(major, instance)
end
end)
for major, instance in LibStub:IterateLibraries() do
manuallyFinalize(major, instance)
end
 
-- Expose the library in the global environment
_G[ACELIBRARY_MAJOR] = self
719,4 → 796,4
previous.positions = setmetatable({}, { __mode = "k" })
end
AceLibrary.positions = previous.positions
AceLibrary:Register(AceLibrary, ACELIBRARY_MAJOR, ACELIBRARY_MINOR, activate)
AceLibrary:Register(AceLibrary, ACELIBRARY_MAJOR, ACELIBRARY_MINOR, activate, nil)
AceLibrary.toc New file
0,0 → 1,14
## Interface: 30000
## X-Curse-Packaged-Version: r1096
## X-Curse-Project-Name: Ace2
## X-Curse-Project-ID: ace2
## X-Curse-Repository-ID: wow/ace2/mainline
 
## Title: Lib: AceLibrary
## Notes: AddOn development framework
## Author: Ace Development Team
## X-Website: http://www.wowace.com
## X-Category: Library
## X-License: LGPL v2.1 + MIT for AceOO-2.0
 
AceLibrary.lua
Property changes : Added: svn:eol-style + native