changeset 3:e75889a45130

Attempt to fix curse
author Adam tegen <adam.tegen@gmail.com>
date Tue, 20 May 2014 23:30:59 -0500
parents 165752e9b22a
children 6ef021bd17b2
files Libs/CallbackHandler-1.0/CallbackHandler-1.0.lua Libs/CallbackHandler-1.0/CallbackHandler-1.0.xml Libs/LibDBIcon-1.0/LibDBIcon-1.0.lua Libs/LibDataBroker-1.1/LibDataBroker-1.1.lua Libs/LibDataBroker-1.1/README.textile Libs/LibStub/LibStub.lua Libs/LibStub/LibStub.toc Libs/LibStub/tests/test.lua Libs/LibStub/tests/test2.lua Libs/LibStub/tests/test3.lua Libs/LibStub/tests/test4.lua
diffstat 11 files changed, 878 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Libs/CallbackHandler-1.0/CallbackHandler-1.0.lua	Tue May 20 23:30:59 2014 -0500
@@ -0,0 +1,240 @@
+--[[ $Id: CallbackHandler-1.0.lua 14 2010-08-09 00:43:38Z mikk $ ]]
+local MAJOR, MINOR = "CallbackHandler-1.0", 6
+local CallbackHandler = LibStub:NewLibrary(MAJOR, MINOR)
+
+if not CallbackHandler then return end -- No upgrade needed
+
+local meta = {__index = function(tbl, key) tbl[key] = {} return tbl[key] end}
+
+-- Lua APIs
+local tconcat = table.concat
+local assert, error, loadstring = assert, error, loadstring
+local setmetatable, rawset, rawget = setmetatable, rawset, rawget
+local next, select, pairs, type, tostring = next, select, pairs, type, tostring
+
+-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded
+-- List them here for Mikk's FindGlobals script
+-- GLOBALS: geterrorhandler
+
+local xpcall = xpcall
+
+local function errorhandler(err)
+	return geterrorhandler()(err)
+end
+
+local function CreateDispatcher(argCount)
+	local code = [[
+	local next, xpcall, eh = ...
+
+	local method, ARGS
+	local function call() method(ARGS) end
+
+	local function dispatch(handlers, ...)
+		local index
+		index, method = next(handlers)
+		if not method then return end
+		local OLD_ARGS = ARGS
+		ARGS = ...
+		repeat
+			xpcall(call, eh)
+			index, method = next(handlers, index)
+		until not method
+		ARGS = OLD_ARGS
+	end
+
+	return dispatch
+	]]
+
+	local ARGS, OLD_ARGS = {}, {}
+	for i = 1, argCount do ARGS[i], OLD_ARGS[i] = "arg"..i, "old_arg"..i end
+	code = code:gsub("OLD_ARGS", tconcat(OLD_ARGS, ", ")):gsub("ARGS", tconcat(ARGS, ", "))
+	return assert(loadstring(code, "safecall Dispatcher["..argCount.."]"))(next, xpcall, errorhandler)
+end
+
+local Dispatchers = setmetatable({}, {__index=function(self, argCount)
+	local dispatcher = CreateDispatcher(argCount)
+	rawset(self, argCount, dispatcher)
+	return dispatcher
+end})
+
+--------------------------------------------------------------------------
+-- CallbackHandler:New
+--
+--   target            - target object to embed public APIs in
+--   RegisterName      - name of the callback registration API, default "RegisterCallback"
+--   UnregisterName    - name of the callback unregistration API, default "UnregisterCallback"
+--   UnregisterAllName - name of the API to unregister all callbacks, default "UnregisterAllCallbacks". false == don't publish this API.
+
+function CallbackHandler:New(target, RegisterName, UnregisterName, UnregisterAllName, OnUsed, OnUnused)
+	-- TODO: Remove this after beta has gone out
+	assert(not OnUsed and not OnUnused, "ACE-80: OnUsed/OnUnused are deprecated. Callbacks are now done to registry.OnUsed and registry.OnUnused")
+
+	RegisterName = RegisterName or "RegisterCallback"
+	UnregisterName = UnregisterName or "UnregisterCallback"
+	if UnregisterAllName==nil then	-- false is used to indicate "don't want this method"
+		UnregisterAllName = "UnregisterAllCallbacks"
+	end
+
+	-- we declare all objects and exported APIs inside this closure to quickly gain access
+	-- to e.g. function names, the "target" parameter, etc
+
+
+	-- Create the registry object
+	local events = setmetatable({}, meta)
+	local registry = { recurse=0, events=events }
+
+	-- registry:Fire() - fires the given event/message into the registry
+	function registry:Fire(eventname, ...)
+		if not rawget(events, eventname) or not next(events[eventname]) then return end
+		local oldrecurse = registry.recurse
+		registry.recurse = oldrecurse + 1
+
+		Dispatchers[select('#', ...) + 1](events[eventname], eventname, ...)
+
+		registry.recurse = oldrecurse
+
+		if registry.insertQueue and oldrecurse==0 then
+			-- Something in one of our callbacks wanted to register more callbacks; they got queued
+			for eventname,callbacks in pairs(registry.insertQueue) do
+				local first = not rawget(events, eventname) or not next(events[eventname])	-- test for empty before. not test for one member after. that one member may have been overwritten.
+				for self,func in pairs(callbacks) do
+					events[eventname][self] = func
+					-- fire OnUsed callback?
+					if first and registry.OnUsed then
+						registry.OnUsed(registry, target, eventname)
+						first = nil
+					end
+				end
+			end
+			registry.insertQueue = nil
+		end
+	end
+
+	-- Registration of a callback, handles:
+	--   self["method"], leads to self["method"](self, ...)
+	--   self with function ref, leads to functionref(...)
+	--   "addonId" (instead of self) with function ref, leads to functionref(...)
+	-- all with an optional arg, which, if present, gets passed as first argument (after self if present)
+	target[RegisterName] = function(self, eventname, method, ... --[[actually just a single arg]])
+		if type(eventname) ~= "string" then
+			error("Usage: "..RegisterName.."(eventname, method[, arg]): 'eventname' - string expected.", 2)
+		end
+
+		method = method or eventname
+
+		local first = not rawget(events, eventname) or not next(events[eventname])	-- test for empty before. not test for one member after. that one member may have been overwritten.
+
+		if type(method) ~= "string" and type(method) ~= "function" then
+			error("Usage: "..RegisterName.."(\"eventname\", \"methodname\"): 'methodname' - string or function expected.", 2)
+		end
+
+		local regfunc
+
+		if type(method) == "string" then
+			-- self["method"] calling style
+			if type(self) ~= "table" then
+				error("Usage: "..RegisterName.."(\"eventname\", \"methodname\"): self was not a table?", 2)
+			elseif self==target then
+				error("Usage: "..RegisterName.."(\"eventname\", \"methodname\"): do not use Library:"..RegisterName.."(), use your own 'self'", 2)
+			elseif type(self[method]) ~= "function" then
+				error("Usage: "..RegisterName.."(\"eventname\", \"methodname\"): 'methodname' - method '"..tostring(method).."' not found on self.", 2)
+			end
+
+			if select("#",...)>=1 then	-- this is not the same as testing for arg==nil!
+				local arg=select(1,...)
+				regfunc = function(...) self[method](self,arg,...) end
+			else
+				regfunc = function(...) self[method](self,...) end
+			end
+		else
+			-- function ref with self=object or self="addonId" or self=thread
+			if type(self)~="table" and type(self)~="string" and type(self)~="thread" then
+				error("Usage: "..RegisterName.."(self or \"addonId\", eventname, method): 'self or addonId': table or string or thread expected.", 2)
+			end
+
+			if select("#",...)>=1 then	-- this is not the same as testing for arg==nil!
+				local arg=select(1,...)
+				regfunc = function(...) method(arg,...) end
+			else
+				regfunc = method
+			end
+		end
+
+
+		if events[eventname][self] or registry.recurse<1 then
+		-- if registry.recurse<1 then
+			-- we're overwriting an existing entry, or not currently recursing. just set it.
+			events[eventname][self] = regfunc
+			-- fire OnUsed callback?
+			if registry.OnUsed and first then
+				registry.OnUsed(registry, target, eventname)
+			end
+		else
+			-- we're currently processing a callback in this registry, so delay the registration of this new entry!
+			-- yes, we're a bit wasteful on garbage, but this is a fringe case, so we're picking low implementation overhead over garbage efficiency
+			registry.insertQueue = registry.insertQueue or setmetatable({},meta)
+			registry.insertQueue[eventname][self] = regfunc
+		end
+	end
+
+	-- Unregister a callback
+	target[UnregisterName] = function(self, eventname)
+		if not self or self==target then
+			error("Usage: "..UnregisterName.."(eventname): bad 'self'", 2)
+		end
+		if type(eventname) ~= "string" then
+			error("Usage: "..UnregisterName.."(eventname): 'eventname' - string expected.", 2)
+		end
+		if rawget(events, eventname) and events[eventname][self] then
+			events[eventname][self] = nil
+			-- Fire OnUnused callback?
+			if registry.OnUnused and not next(events[eventname]) then
+				registry.OnUnused(registry, target, eventname)
+			end
+		end
+		if registry.insertQueue and rawget(registry.insertQueue, eventname) and registry.insertQueue[eventname][self] then
+			registry.insertQueue[eventname][self] = nil
+		end
+	end
+
+	-- OPTIONAL: Unregister all callbacks for given selfs/addonIds
+	if UnregisterAllName then
+		target[UnregisterAllName] = function(...)
+			if select("#",...)<1 then
+				error("Usage: "..UnregisterAllName.."([whatFor]): missing 'self' or \"addonId\" to unregister events for.", 2)
+			end
+			if select("#",...)==1 and ...==target then
+				error("Usage: "..UnregisterAllName.."([whatFor]): supply a meaningful 'self' or \"addonId\"", 2)
+			end
+
+
+			for i=1,select("#",...) do
+				local self = select(i,...)
+				if registry.insertQueue then
+					for eventname, callbacks in pairs(registry.insertQueue) do
+						if callbacks[self] then
+							callbacks[self] = nil
+						end
+					end
+				end
+				for eventname, callbacks in pairs(events) do
+					if callbacks[self] then
+						callbacks[self] = nil
+						-- Fire OnUnused callback?
+						if registry.OnUnused and not next(callbacks) then
+							registry.OnUnused(registry, target, eventname)
+						end
+					end
+				end
+			end
+		end
+	end
+
+	return registry
+end
+
+
+-- CallbackHandler purposefully does NOT do explicit embedding. Nor does it
+-- try to upgrade old implicit embeds since the system is selfcontained and
+-- relies on closures to work.
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Libs/CallbackHandler-1.0/CallbackHandler-1.0.xml	Tue May 20 23:30:59 2014 -0500
@@ -0,0 +1,4 @@
+<Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/
+..\FrameXML\UI.xsd">
+	<Script file="CallbackHandler-1.0.lua"/>
+</Ui>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Libs/LibDBIcon-1.0/LibDBIcon-1.0.lua	Tue May 20 23:30:59 2014 -0500
@@ -0,0 +1,344 @@
+--[[
+Name: DBIcon-1.0
+Revision: $Rev: 25 $
+Author(s): Rabbit (rabbit.magtheridon@gmail.com)
+Description: Allows addons to register to recieve a lightweight minimap icon as an alternative to more heavy LDB displays.
+Dependencies: LibStub
+License: GPL v2 or later.
+]]
+
+--[[
+Copyright (C) 2008-2011 Rabbit
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+]]
+
+-----------------------------------------------------------------------
+-- DBIcon-1.0
+--
+-- Disclaimer: Most of this code was ripped from Barrel but fixed, streamlined
+--             and cleaned up a lot so that it no longer sucks.
+--
+
+local DBICON10 = "LibDBIcon-1.0"
+local DBICON10_MINOR = tonumber(("$Rev: 25 $"):match("(%d+)"))
+if not LibStub then error(DBICON10 .. " requires LibStub.") end
+local ldb = LibStub("LibDataBroker-1.1", true)
+if not ldb then error(DBICON10 .. " requires LibDataBroker-1.1.") end
+local lib = LibStub:NewLibrary(DBICON10, DBICON10_MINOR)
+if not lib then return end
+
+lib.disabled = lib.disabled or nil
+lib.objects = lib.objects or {}
+lib.callbackRegistered = lib.callbackRegistered or nil
+lib.notCreated = lib.notCreated or {}
+
+function lib:IconCallback(event, name, key, value, dataobj)
+	if lib.objects[name] then
+		if key == "icon" then
+			lib.objects[name].icon:SetTexture(value)
+		elseif key == "iconCoords" then
+			lib.objects[name].icon:UpdateCoord()
+		end
+	end
+end
+if not lib.callbackRegistered then
+	ldb.RegisterCallback(lib, "LibDataBroker_AttributeChanged__icon", "IconCallback")
+	ldb.RegisterCallback(lib, "LibDataBroker_AttributeChanged__iconCoords", "IconCallback")
+	lib.callbackRegistered = true
+end
+
+-- Tooltip code ripped from StatBlockCore by Funkydude
+local function getAnchors(frame)
+	local x, y = frame:GetCenter()
+	if not x or not y then return "CENTER" end
+	local hhalf = (x > UIParent:GetWidth()*2/3) and "RIGHT" or (x < UIParent:GetWidth()/3) and "LEFT" or ""
+	local vhalf = (y > UIParent:GetHeight()/2) and "TOP" or "BOTTOM"
+	return vhalf..hhalf, frame, (vhalf == "TOP" and "BOTTOM" or "TOP")..hhalf
+end
+
+local function onEnter(self)
+	if self.isMoving then return end
+	local obj = self.dataObject
+	if obj.OnTooltipShow then
+		GameTooltip:SetOwner(self, "ANCHOR_NONE")
+		GameTooltip:SetPoint(getAnchors(self))
+		obj.OnTooltipShow(GameTooltip)
+		GameTooltip:Show()
+	elseif obj.OnEnter then
+		obj.OnEnter(self)
+	end
+end
+
+local function onLeave(self)
+	local obj = self.dataObject
+	GameTooltip:Hide()
+	if obj.OnLeave then obj.OnLeave(self) end
+end
+
+--------------------------------------------------------------------------------
+
+local onClick, onMouseUp, onMouseDown, onDragStart, onDragEnd, updatePosition
+
+do
+	local minimapShapes = {
+		["ROUND"] = {true, true, true, true},
+		["SQUARE"] = {false, false, false, false},
+		["CORNER-TOPLEFT"] = {false, false, false, true},
+		["CORNER-TOPRIGHT"] = {false, false, true, false},
+		["CORNER-BOTTOMLEFT"] = {false, true, false, false},
+		["CORNER-BOTTOMRIGHT"] = {true, false, false, false},
+		["SIDE-LEFT"] = {false, true, false, true},
+		["SIDE-RIGHT"] = {true, false, true, false},
+		["SIDE-TOP"] = {false, false, true, true},
+		["SIDE-BOTTOM"] = {true, true, false, false},
+		["TRICORNER-TOPLEFT"] = {false, true, true, true},
+		["TRICORNER-TOPRIGHT"] = {true, false, true, true},
+		["TRICORNER-BOTTOMLEFT"] = {true, true, false, true},
+		["TRICORNER-BOTTOMRIGHT"] = {true, true, true, false},
+	}
+
+	function updatePosition(button)
+		local angle = math.rad(button.db and button.db.minimapPos or button.minimapPos or 225)
+		local x, y, q = math.cos(angle), math.sin(angle), 1
+		if x < 0 then q = q + 1 end
+		if y > 0 then q = q + 2 end
+		local minimapShape = GetMinimapShape and GetMinimapShape() or "ROUND"
+		local quadTable = minimapShapes[minimapShape]
+		if quadTable[q] then
+			x, y = x*80, y*80
+		else
+			local diagRadius = 103.13708498985 --math.sqrt(2*(80)^2)-10
+			x = math.max(-80, math.min(x*diagRadius, 80))
+			y = math.max(-80, math.min(y*diagRadius, 80))
+		end
+		button:SetPoint("CENTER", Minimap, "CENTER", x, y)
+	end
+end
+
+function onClick(self, b) if self.dataObject.OnClick then self.dataObject.OnClick(self, b) end end
+function onMouseDown(self) self.isMouseDown = true; self.icon:UpdateCoord() end
+function onMouseUp(self) self.isMouseDown = false; self.icon:UpdateCoord() end
+
+do
+	local function onUpdate(self)
+		local mx, my = Minimap:GetCenter()
+		local px, py = GetCursorPosition()
+		local scale = Minimap:GetEffectiveScale()
+		px, py = px / scale, py / scale
+		if self.db then
+			self.db.minimapPos = math.deg(math.atan2(py - my, px - mx)) % 360
+		else
+			self.minimapPos = math.deg(math.atan2(py - my, px - mx)) % 360
+		end
+		updatePosition(self)
+	end
+
+	function onDragStart(self)
+		self:LockHighlight()
+		self.isMouseDown = true
+		self.icon:UpdateCoord()
+		self:SetScript("OnUpdate", onUpdate)
+		self.isMoving = true
+		GameTooltip:Hide()
+	end
+end
+
+function onDragStop(self)
+	self:SetScript("OnUpdate", nil)
+	self.isMouseDown = false
+	self.icon:UpdateCoord()
+	self:UnlockHighlight()
+	self.isMoving = nil
+end
+
+local defaultCoords = {0, 1, 0, 1}
+local function updateCoord(self)
+	local coords = self:GetParent().dataObject.iconCoords or defaultCoords
+	local deltaX, deltaY = 0, 0
+	if not self:GetParent().isMouseDown then
+		deltaX = (coords[2] - coords[1]) * 0.05
+		deltaY = (coords[4] - coords[3]) * 0.05
+	end
+	self:SetTexCoord(coords[1] + deltaX, coords[2] - deltaX, coords[3] + deltaY, coords[4] - deltaY)
+end
+
+local function createButton(name, object, db)
+	local button = CreateFrame("Button", "LibDBIcon10_"..name, Minimap)
+	button.dataObject = object
+	button.db = db
+	button:SetFrameStrata("MEDIUM")
+	button:SetWidth(31); button:SetHeight(31)
+	button:SetFrameLevel(8)
+	button:RegisterForClicks("anyUp")
+	button:RegisterForDrag("LeftButton")
+	button:SetHighlightTexture("Interface\\Minimap\\UI-Minimap-ZoomButton-Highlight")
+	local overlay = button:CreateTexture(nil, "OVERLAY")
+	overlay:SetWidth(53); overlay:SetHeight(53)
+	overlay:SetTexture("Interface\\Minimap\\MiniMap-TrackingBorder")
+	overlay:SetPoint("TOPLEFT")
+	local background = button:CreateTexture(nil, "BACKGROUND")
+	background:SetWidth(20); background:SetHeight(20)
+	background:SetTexture("Interface\\Minimap\\UI-Minimap-Background")
+	background:SetPoint("TOPLEFT", 7, -5)
+	local icon = button:CreateTexture(nil, "ARTWORK")
+	icon:SetWidth(17); icon:SetHeight(17)
+	icon:SetTexture(object.icon)
+	icon:SetPoint("TOPLEFT", 7, -6)
+	button.icon = icon
+	button.isMouseDown = false
+
+	icon.UpdateCoord = updateCoord
+	icon:UpdateCoord()
+
+	button:SetScript("OnEnter", onEnter)
+	button:SetScript("OnLeave", onLeave)
+	button:SetScript("OnClick", onClick)
+	if not db or not db.lock then
+		button:SetScript("OnDragStart", onDragStart)
+		button:SetScript("OnDragStop", onDragStop)
+	end
+	button:SetScript("OnMouseDown", onMouseDown)
+	button:SetScript("OnMouseUp", onMouseUp)
+
+	lib.objects[name] = button
+
+	if lib.loggedIn then
+		updatePosition(button)
+		if not db or not db.hide then button:Show()
+		else button:Hide() end
+	end
+end
+
+-- We could use a metatable.__index on lib.objects, but then we'd create
+-- the icons when checking things like :IsRegistered, which is not necessary.
+local function check(name)
+	if lib.notCreated[name] then
+		createButton(name, lib.notCreated[name][1], lib.notCreated[name][2])
+		lib.notCreated[name] = nil
+	end
+end
+
+lib.loggedIn = lib.loggedIn or false
+-- Wait a bit with the initial positioning to let any GetMinimapShape addons
+-- load up.
+if not lib.loggedIn then
+	local f = CreateFrame("Frame")
+	f:SetScript("OnEvent", function()
+		for _, object in pairs(lib.objects) do
+			updatePosition(object)
+			if not lib.disabled and (not object.db or not object.db.hide) then object:Show()
+			else object:Hide() end
+		end
+		lib.loggedIn = true
+		f:SetScript("OnEvent", nil)
+		f = nil
+	end)
+	f:RegisterEvent("PLAYER_LOGIN")
+end
+
+local function getDatabase(name)
+	return lib.notCreated[name] and lib.notCreated[name][2] or lib.objects[name].db
+end
+
+function lib:Register(name, object, db)
+	if not object.icon then error("Can't register LDB objects without icons set!") end
+	if lib.objects[name] or lib.notCreated[name] then error("Already registered, nubcake.") end
+	if not lib.disabled and (not db or not db.hide) then
+		createButton(name, object, db)
+	else
+		lib.notCreated[name] = {object, db}
+	end
+end
+
+function lib:Lock(name)
+	if not lib:IsRegistered(name) then return end
+	if lib.objects[name] then
+		lib.objects[name]:SetScript("OnDragStart", nil)
+		lib.objects[name]:SetScript("OnDragStop", nil)
+	end
+	local db = getDatabase(name)
+	if db then db.lock = true end
+end
+
+function lib:Unlock(name)
+	if not lib:IsRegistered(name) then return end
+	if lib.objects[name] then
+		lib.objects[name]:SetScript("OnDragStart", onDragStart)
+		lib.objects[name]:SetScript("OnDragStop", onDragStop)
+	end
+	local db = getDatabase(name)
+	if db then db.lock = nil end
+end
+
+function lib:Hide(name)
+	if not lib.objects[name] then return end
+	lib.objects[name]:Hide()
+end
+function lib:Show(name)
+	if lib.disabled then return end
+	check(name)
+	lib.objects[name]:Show()
+	updatePosition(lib.objects[name])
+end
+function lib:IsRegistered(name)
+	return (lib.objects[name] or lib.notCreated[name]) and true or false
+end
+function lib:Refresh(name, db)
+	if lib.disabled then return end
+	check(name)
+	local button = lib.objects[name]
+	if db then button.db = db end
+	updatePosition(button)
+	if not button.db or not button.db.hide then
+		button:Show()
+	else
+		button:Hide()
+	end
+	if not button.db or not button.db.lock then
+		button:SetScript("OnDragStart", onDragStart)
+		button:SetScript("OnDragStop", onDragStop)
+	else
+		button:SetScript("OnDragStart", nil)
+		button:SetScript("OnDragStop", nil)
+	end
+end
+function lib:GetMinimapButton(name)
+	return lib.objects[name]
+end
+
+function lib:EnableLibrary()
+	lib.disabled = nil
+	for name, object in pairs(lib.objects) do
+		if not object.db or not object.db.hide then
+			object:Show()
+			updatePosition(object)
+		end
+	end
+	for name, data in pairs(lib.notCreated) do
+		if not data.db or not data.db.hide then
+			createButton(name, data[1], data[2])
+			lib.notCreated[name] = nil
+		end
+	end
+end
+
+function lib:DisableLibrary()
+	lib.disabled = true
+	for name, object in pairs(lib.objects) do
+		object:Hide()
+	end
+end
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Libs/LibDataBroker-1.1/LibDataBroker-1.1.lua	Tue May 20 23:30:59 2014 -0500
@@ -0,0 +1,90 @@
+
+assert(LibStub, "LibDataBroker-1.1 requires LibStub")
+assert(LibStub:GetLibrary("CallbackHandler-1.0", true), "LibDataBroker-1.1 requires CallbackHandler-1.0")
+
+local lib, oldminor = LibStub:NewLibrary("LibDataBroker-1.1", 4)
+if not lib then return end
+oldminor = oldminor or 0
+
+
+lib.callbacks = lib.callbacks or LibStub:GetLibrary("CallbackHandler-1.0"):New(lib)
+lib.attributestorage, lib.namestorage, lib.proxystorage = lib.attributestorage or {}, lib.namestorage or {}, lib.proxystorage or {}
+local attributestorage, namestorage, callbacks = lib.attributestorage, lib.namestorage, lib.callbacks
+
+if oldminor < 2 then
+	lib.domt = {
+		__metatable = "access denied",
+		__index = function(self, key) return attributestorage[self] and attributestorage[self][key] end,
+	}
+end
+
+if oldminor < 3 then
+	lib.domt.__newindex = function(self, key, value)
+		if not attributestorage[self] then attributestorage[self] = {} end
+		if attributestorage[self][key] == value then return end
+		attributestorage[self][key] = value
+		local name = namestorage[self]
+		if not name then return end
+		callbacks:Fire("LibDataBroker_AttributeChanged", name, key, value, self)
+		callbacks:Fire("LibDataBroker_AttributeChanged_"..name, name, key, value, self)
+		callbacks:Fire("LibDataBroker_AttributeChanged_"..name.."_"..key, name, key, value, self)
+		callbacks:Fire("LibDataBroker_AttributeChanged__"..key, name, key, value, self)
+	end
+end
+
+if oldminor < 2 then
+	function lib:NewDataObject(name, dataobj)
+		if self.proxystorage[name] then return end
+
+		if dataobj then
+			assert(type(dataobj) == "table", "Invalid dataobj, must be nil or a table")
+			self.attributestorage[dataobj] = {}
+			for i,v in pairs(dataobj) do
+				self.attributestorage[dataobj][i] = v
+				dataobj[i] = nil
+			end
+		end
+		dataobj = setmetatable(dataobj or {}, self.domt)
+		self.proxystorage[name], self.namestorage[dataobj] = dataobj, name
+		self.callbacks:Fire("LibDataBroker_DataObjectCreated", name, dataobj)
+		return dataobj
+	end
+end
+
+if oldminor < 1 then
+	function lib:DataObjectIterator()
+		return pairs(self.proxystorage)
+	end
+
+	function lib:GetDataObjectByName(dataobjectname)
+		return self.proxystorage[dataobjectname]
+	end
+
+	function lib:GetNameByDataObject(dataobject)
+		return self.namestorage[dataobject]
+	end
+end
+
+if oldminor < 4 then
+	local next = pairs(attributestorage)
+	function lib:pairs(dataobject_or_name)
+		local t = type(dataobject_or_name)
+		assert(t == "string" or t == "table", "Usage: ldb:pairs('dataobjectname') or ldb:pairs(dataobject)")
+
+		local dataobj = self.proxystorage[dataobject_or_name] or dataobject_or_name
+		assert(attributestorage[dataobj], "Data object not found")
+
+		return next, attributestorage[dataobj], nil
+	end
+
+	local ipairs_iter = ipairs(attributestorage)
+	function lib:ipairs(dataobject_or_name)
+		local t = type(dataobject_or_name)
+		assert(t == "string" or t == "table", "Usage: ldb:ipairs('dataobjectname') or ldb:ipairs(dataobject)")
+
+		local dataobj = self.proxystorage[dataobject_or_name] or dataobject_or_name
+		assert(attributestorage[dataobj], "Data object not found")
+
+		return ipairs_iter, attributestorage[dataobj], 0
+	end
+end
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Libs/LibDataBroker-1.1/README.textile	Tue May 20 23:30:59 2014 -0500
@@ -0,0 +1,13 @@
+LibDataBroker is a small WoW addon library designed to provide a "MVC":http://en.wikipedia.org/wiki/Model-view-controller interface for use in various addons.
+LDB's primary goal is to "detach" plugins for TitanPanel and FuBar from the display addon.
+Plugins can provide data into a simple table, and display addons can receive callbacks to refresh their display of this data.
+LDB also provides a place for addons to register "quicklaunch" functions, removing the need for authors to embed many large libraries to create minimap buttons.
+Users who do not wish to be "plagued" by these buttons simply do not install an addon to render them.
+
+Due to it's simple generic design, LDB can be used for any design where you wish to have an addon notified of changes to a table.
+
+h2. Links
+
+* "API documentation":http://github.com/tekkub/libdatabroker-1-1/wikis/api
+* "Data specifications":http://github.com/tekkub/libdatabroker-1-1/wikis/data-specifications
+* "Addons using LDB":http://github.com/tekkub/libdatabroker-1-1/wikis/addons-using-ldb
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Libs/LibStub/LibStub.lua	Tue May 20 23:30:59 2014 -0500
@@ -0,0 +1,51 @@
+-- $Id: LibStub.lua 76 2007-09-03 01:50:17Z mikk $
+-- 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]
+
+-- Check to see is this version of the stub is obsolete
+if not LibStub or LibStub.minor < LIBSTUB_MINOR then
+	LibStub = LibStub or {libs = {}, minors = {} }
+	_G[LIBSTUB_MAJOR] = LibStub
+	LibStub.minor = LIBSTUB_MINOR
+	
+	-- LibStub:NewLibrary(major, minor)
+	-- major (string) - the major version of the library
+	-- minor (string or number ) - the minor version of the library
+	-- 
+	-- returns nil if a newer or same version of the lib is already present
+	-- returns empty library object or old library object if upgrade is needed
+	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
+	
+	-- LibStub:GetLibrary(major, [silent])
+	-- major (string) - the major version of the library
+	-- silent (boolean) - if true, library is optional, silently return nil if its not found
+	--
+	-- throws an error if the library can not be found (except silent is set)
+	-- returns the library object if found
+	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
+	
+	-- LibStub:IterateLibraries()
+	-- 
+	-- Returns an iterator for the currently registered libraries
+	function LibStub:IterateLibraries() 
+		return pairs(self.libs) 
+	end
+	
+	setmetatable(LibStub, { __call = LibStub.GetLibrary })
+end
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Libs/LibStub/LibStub.toc	Tue May 20 23:30:59 2014 -0500
@@ -0,0 +1,13 @@
+## Interface: 50001
+## Title: Lib: LibStub
+## Notes: Universal Library Stub
+## Credits: Kaelten, Cladhaire, ckknight, Mikk, Ammo, Nevcairiel
+## X-Website: http://www.wowace.com/addons/libstub/
+## X-Category: Library
+## X-License: Public Domain	
+## X-Curse-Packaged-Version: 1.0.3-50001
+## X-Curse-Project-Name: LibStub
+## X-Curse-Project-ID: libstub
+## X-Curse-Repository-ID: wow/libstub/mainline
+
+LibStub.lua
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Libs/LibStub/tests/test.lua	Tue May 20 23:30:59 2014 -0500
@@ -0,0 +1,41 @@
+debugstack = debug.traceback
+strmatch = string.match
+
+loadfile("../LibStub.lua")()
+
+local lib, oldMinor = LibStub:NewLibrary("Pants", 1) -- make a new thingy
+assert(lib) -- should return the library table
+assert(not oldMinor) -- should not return the old minor, since it didn't exist
+
+-- the following is to create data and then be able to check if the same data exists after the fact
+function lib:MyMethod()
+end
+local MyMethod = lib.MyMethod
+lib.MyTable = {}
+local MyTable = lib.MyTable
+
+local newLib, newOldMinor = LibStub:NewLibrary("Pants", 1) -- try to register a library with the same version, should silently fail
+assert(not newLib) -- should not return since out of date
+
+local newLib, newOldMinor = LibStub:NewLibrary("Pants", 0) -- try to register a library with a previous, should silently fail
+assert(not newLib) -- should not return since out of date
+
+local newLib, newOldMinor = LibStub:NewLibrary("Pants", 2) -- register a new version
+assert(newLib) -- library table
+assert(rawequal(newLib, lib)) -- should be the same reference as the previous
+assert(newOldMinor == 1) -- should return the minor version of the previous version
+
+assert(rawequal(lib.MyMethod, MyMethod)) -- verify that values were saved
+assert(rawequal(lib.MyTable, MyTable)) -- verify that values were saved
+
+local newLib, newOldMinor = LibStub:NewLibrary("Pants", "Blah 3 Blah") -- register a new version with a string minor version (instead of a number)
+assert(newLib) -- library table
+assert(newOldMinor == 2) -- previous version was 2
+
+local newLib, newOldMinor = LibStub:NewLibrary("Pants", "Blah 4 and please ignore 15 Blah") -- register a new version with a string minor version (instead of a number)
+assert(newLib)
+assert(newOldMinor == 3) -- previous version was 3 (even though it gave a string)
+
+local newLib, newOldMinor = LibStub:NewLibrary("Pants", 5) -- register a new library, using a normal number instead of a string
+assert(newLib)
+assert(newOldMinor == 4) -- previous version was 4 (even though it gave a string)
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Libs/LibStub/tests/test2.lua	Tue May 20 23:30:59 2014 -0500
@@ -0,0 +1,27 @@
+debugstack = debug.traceback
+strmatch = string.match
+
+loadfile("../LibStub.lua")()
+
+for major, library in LibStub:IterateLibraries() do
+	-- check that MyLib doesn't exist yet, by iterating through all the libraries
+	assert(major ~= "MyLib")
+end
+
+assert(not LibStub:GetLibrary("MyLib", true)) -- check that MyLib doesn't exist yet by direct checking
+assert(not pcall(LibStub.GetLibrary, LibStub, "MyLib")) -- don't silently fail, thus it should raise an error.
+local lib = LibStub:NewLibrary("MyLib", 1) -- create the lib
+assert(lib) -- check it exists
+assert(rawequal(LibStub:GetLibrary("MyLib"), lib)) -- verify that :GetLibrary("MyLib") properly equals the lib reference
+
+assert(LibStub:NewLibrary("MyLib", 2))	-- create a new version
+
+local count=0
+for major, library in LibStub:IterateLibraries() do
+	-- check that MyLib exists somewhere in the libraries, by iterating through all the libraries
+	if major == "MyLib" then -- we found it!
+		count = count +1
+		assert(rawequal(library, lib)) -- verify that the references are equal
+	end
+end
+assert(count == 1) -- verify that we actually found it, and only once
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Libs/LibStub/tests/test3.lua	Tue May 20 23:30:59 2014 -0500
@@ -0,0 +1,14 @@
+debugstack = debug.traceback
+strmatch = string.match
+
+loadfile("../LibStub.lua")()
+
+local proxy = newproxy() -- non-string
+
+assert(not pcall(LibStub.NewLibrary, LibStub, proxy, 1)) -- should error, proxy is not a string, it's userdata
+local success, ret = pcall(LibStub.GetLibrary, proxy, true)
+assert(not success or not ret) -- either error because proxy is not a string or because it's not actually registered.
+
+assert(not pcall(LibStub.NewLibrary, LibStub, "Something", "No number in here")) -- should error, minor has no string in it.
+
+assert(not LibStub:GetLibrary("Something", true)) -- shouldn't've created it from the above statement
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Libs/LibStub/tests/test4.lua	Tue May 20 23:30:59 2014 -0500
@@ -0,0 +1,41 @@
+debugstack = debug.traceback
+strmatch = string.match
+
+loadfile("../LibStub.lua")()
+
+
+-- Pretend like loaded libstub is old and doesn't have :IterateLibraries
+assert(LibStub.minor)
+LibStub.minor = LibStub.minor - 0.0001
+LibStub.IterateLibraries = nil
+
+loadfile("../LibStub.lua")()
+
+assert(type(LibStub.IterateLibraries)=="function")
+
+
+-- Now pretend that we're the same version -- :IterateLibraries should NOT be re-created
+LibStub.IterateLibraries = 123
+
+loadfile("../LibStub.lua")()
+
+assert(LibStub.IterateLibraries == 123)
+
+
+-- Now pretend that a newer version is loaded -- :IterateLibraries should NOT be re-created
+LibStub.minor = LibStub.minor + 0.0001
+
+loadfile("../LibStub.lua")()
+
+assert(LibStub.IterateLibraries == 123)
+
+
+-- Again with a huge number
+LibStub.minor = LibStub.minor + 1234567890
+
+loadfile("../LibStub.lua")()
+
+assert(LibStub.IterateLibraries == 123)
+
+
+print("OK")
\ No newline at end of file