WoWInterface SVN Broker_WoDCurrency

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /trunk
    from Rev 1 to Rev 2
    Reverse comparison

Rev 1 → Rev 2

Broker_WoDCurrency/LibStub/LibStub.lua New file
0,0 → 1,30
-- 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
Broker_WoDCurrency/CallbackHandler-1.0/CallbackHandler-1.0.xml New file
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
Broker_WoDCurrency/CallbackHandler-1.0/CallbackHandler-1.0.lua New file
0,0 → 1,240
--[[ $Id: CallbackHandler-1.0.lua 965 2010-08-09 00:47:52Z 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.
 
Broker_WoDCurrency/Broker_WoDCurrency.lua New file
0,0 → 1,214
local f = CreateFrame("Frame")
local strformat = string.format
local tinsert = table.insert
local tremove = table.remove
local tlbsort = table.sort
local db, _
local labelString = "|T%s:0|t %s"
local separatedBankString = "%d (%d | %d)"
 
local ids = {
{id = 823, type = "currency"}, --apexis crystal
{id = 824, type = "currency"}, --garrison resources
{id = 944, type = "currency"}, --artifact fragment
{id = 980, type = "currency"}, --dingy iron coins
{id = 994, type = "currency"}, --seal of tempered fate
{id = 116053, type = "item"}, --draenic seeds
{id = 116415, type = "item"}, --pet charm
{id = 120945, type = "item"}, --primal spirit
{id = 118700, type = "item"}, --secret of draenor alchemy
{id = 118720, type = "item"}, --secret of draenor blacksmithing
{id = 119293, type = "item"}, --secret of draenor enchanting
{id = 119299, type = "item"}, --secret of draenor engineering
{id = 119297, type = "item"}, --secret of draenor inscription
{id = 118723, type = "item"}, --secret of draenor jewelcrafting
{id = 118721, type = "item"}, --secret of draenor leatherworking
{id = 118722, type = "item"}, --secret of draenor tailoring
}
 
f.buttons = {}
local i = 1
local function AddCheckbox(setting, name)
f.buttons[i] = CreateFrame("CheckButton", nil, f, "UICheckButtonTemplate")
local box = f.buttons[i]
if i == 1 then
box:SetPoint("TOPLEFT", 20, -85)
elseif i == 2 then
box:SetPoint("TOPLEFT", f.buttons[1], "TOPLEFT", 0, -80)
elseif i == 13 then
box:SetPoint("TOPLEFT", f.buttons[2], "TOPRIGHT", 250, 0)
else
box:SetPoint("TOPLEFT", f.buttons[i-1], "TOPLEFT", 0, -30)
end
box:SetChecked(WoDCurrencyDBPC[setting])
box:SetScript("OnClick", function(self)
self:SetChecked(not WoDCurrencyDBPC[setting])
WoDCurrencyDBPC[setting] = not WoDCurrencyDBPC[setting]
end)
--labels
box.text = box:CreateFontString(nil, "ARTWORK", "GameFontHighlight")
box.text:SetPoint("LEFT", box, "RIGHT", 5, 0)
box.text:SetText(name)
 
i = i+1
 
return box
end
 
local function BuildOptions()
--[[local OnEnter = function(self, title, text)
GameTooltip:SetOwner(self, "ANCHOR_TOPRIGHT")
GameTooltip:SetText(title)
GameTooltip:AddLine(text,1,1,1,true)
GameTooltip:Show()
end]]
 
local header = f:CreateFontString(nil, "ARTWORK", "GameFontNormalLarge")
header:SetParent(f)
header:SetPoint("TOPLEFT", 20, -15)
header:SetText("Broker_WoDCurrency")
 
local subheader = f:CreateFontString(nil, "ARTWORK", "GameFontHighlight")
subheader:SetParent(f)
subheader:SetPoint("TOPLEFT", 20, -32)
subheader:SetPoint("RIGHT", -20, -32)
subheader:SetHeight(30)
subheader:SetNonSpaceWrap(true)
subheader:SetJustifyH("LEFT")
subheader:SetText("An LDB plugin to display currencies for WoD.")
 
local box = AddCheckbox("separateBank", "Separate items in bank from total count: "..TOTAL.." ("..BAGSLOT.." | "..BANK..")")
 
local selectToTrack = f:CreateFontString(nil, "ARTWORK", "GameFontHighlight")
selectToTrack:SetParent(f)
selectToTrack:SetPoint("TOPLEFT", box, "BOTTOMLEFT", 0, -15)
selectToTrack:SetHeight(30)
selectToTrack:SetNonSpaceWrap(true)
selectToTrack:SetJustifyH("LEFT")
selectToTrack:SetText("Select which currencies and items to track.")
end
 
local itemsFound = 0
local checkAgain = {}
local function ReQuery()
for k, currency in pairs(checkAgain) do
if currency.type == "currency" then
currency.name, _, currency.texture = GetCurrencyInfo(currency.id)
else
currency.name, _, _, _, _, _, _, _, _, currency.texture = GetItemInfo(currency.id)
end
if currency.name then
tremove(checkAgain, k)
itemsFound = itemsFound + 1
end
end
 
if itemsFound == #ids then --if all of our items have been found by the client...
f:UnregisterEvent("GET_ITEM_INFO_RECEIVED")
--then, alphabetize based on locale
tlbsort(ids, function(a, b) return a.name < b.name end)
--now let's add our checkboxes in alphabetical order
for _, currency in pairs(ids) do
AddCheckbox(currency.id, currency.name)
end
end
end
 
local function Initialize()
WoDCurrencyDBPC = WoDCurrencyDBPC or {}
db = WoDCurrencyDBPC
db.separateBank = db.separateBank or false
 
for i = 1, #ids do
local currency = ids[i]
 
--first, store localized name (and texture, while we're at it)
if currency.type == "currency" then
currency.name, _, currency.texture = GetCurrencyInfo(currency.id)
else
currency.name, _, _, _, _, _, _, _, _, currency.texture = GetItemInfo(currency.id)
end
if not currency.name then --if this item isn't in the client's cache, try again when it's found
currency.idsKey = i
tinsert(checkAgain, currency)
f:RegisterEvent("GET_ITEM_INFO_RECEIVED")
else
itemsFound = itemsFound + 1
end
 
--also, while we're looping through, let's double-check our db
if db[currency.id] == nil then
db[currency.id] = true
end
end
 
 
f.name = "Broker_WoDCurrency"
InterfaceOptions_AddCategory(f)
BuildOptions()
 
if itemsFound == #ids then --if all of our items have been found by the client...
f:UnregisterEvent("GET_ITEM_INFO_RECEIVED")
--then, alphabetize based on locale
tlbsort(ids, function(a, b) return a.name < b.name end)
--now let's add our checkboxes in alphabetical order
for _, currency in pairs(ids) do
AddCheckbox(currency.id, currency.name)
end
end
end
 
local function PollCurrencyData(tt)
for _, currency in pairs(ids) do
if db[currency.id] then
if currency.type == "currency" then
local name, amount, texture = GetCurrencyInfo(currency.id)
tt:AddDoubleLine(strformat(labelString, texture, name), amount)
else
local amount = GetItemCount(currency.id, true)
if db.separateBank then
local justBags = GetItemCount(currency.id)
local justBank = amount - justBags
tt:AddDoubleLine(strformat(labelString, currency.texture, currency.name), strformat(separatedBankString, amount, justBags, justBank))
else
tt:AddDoubleLine(strformat(labelString, currency.texture, currency.name), amount)
end
end
end
end
end
 
local BWC = LibStub:GetLibrary("LibDataBroker-1.1"):NewDataObject("Broker_WoDCurrency", {
type = "launcher",
label = "WoD Currency",
icon = "Interface\\Icons\\INV_Garrison_Resource",
OnClick = function(self, btn)
if btn == "RightButton" then
InterfaceOptionsFrame_OpenToCategory("Broker_WoDCurrency")
InterfaceOptionsFrame_OpenToCategory("Broker_WoDCurrency")
else
ToggleCharacter("TokenFrame")
end
end,
})
 
function BWC.OnTooltipShow(self)
self:AddLine("Broker_WoDCurrency",1,1,1)
self:AddLine(" ")
PollCurrencyData(self)
self:AddLine(" ")
self:AddLine("Left-click to toggle the Currency frame.")
self:AddLine("Right-click to open the WoDCurrency options.")
end
 
f:RegisterEvent("PLAYER_ENTERING_WORLD")
f:SetScript("OnEvent", function(self, event)
if event == "GET_ITEM_INFO_RECEIVED" then
ReQuery()
else
C_Timer.After(5, Initialize)
--Initialize()
f:UnregisterEvent("PLAYER_ENTERING_WORLD")
end
end)
 
Broker_WoDCurrency/Broker_WoDCurrency.toc New file
0,0 → 1,11
## Interface: 60000
## Name: Broker_WoDCurrency
## Notes: An LDB plugin to display currencies for WoD.
## Author: Seerah
## Version: 1.0
## SavedVariablesPerCharacter: WoDCurrencyDBPC
 
LibStub\LibStub.lua
CallBackHandler-1.0\CallbackHandler-1.0.xml
LibDataBroker-1.1.lua
Broker_WoDCurrency.lua
\ No newline at end of file
Broker_WoDCurrency/LibDataBroker-1.1.lua New file
0,0 → 1,66
 
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", 3)
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