WoWInterface SVN ChatProfiles

Compare Revisions

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

Rev 1 → Rev 2

0.3beta/ChatProfiles.lua New file
0,0 → 1,338
 
local ChatProfiles_Defaults = {
["ChatWindowProfiles"] = {
["default6"] = {
["messages"] = {
},
["channels"] = {
},
},
["default3"] = {
["messages"] = {
},
["channels"] = {
},
},
["default5"] = {
["messages"] = {
},
["channels"] = {
},
},
["default2"] = {
["messages"] = {
"OPENING", -- [1]
"TRADESKILLS", -- [2]
"PET_INFO", -- [3]
"COMBAT_XP_GAIN", -- [4]
"COMBAT_HONOR_GAIN", -- [5]
"COMBAT_MISC_INFO", -- [6]
},
["channels"] = {
},
},
["default4"] = {
["messages"] = {
},
["channels"] = {
},
},
["default7"] = {
["messages"] = {
},
["channels"] = {
},
},
["default1"] = {
["messages"] = {
"SYSTEM", -- [1]
"SYSTEM_NOMENU", -- [2]
"SAY", -- [3]
"EMOTE", -- [4]
"YELL", -- [5]
"WHISPER", -- [6]
"PARTY", -- [7]
"RAID", -- [8]
"RAID_LEADER", -- [9]
"RAID_WARNING", -- [10]
"BATTLEGROUND", -- [11]
"BATTLEGROUND_LEADER", -- [12]
"GUILD", -- [13]
"GUILD_OFFICER", -- [14]
"MONSTER_SAY", -- [15]
"MONSTER_YELL", -- [16]
"MONSTER_EMOTE", -- [17]
"MONSTER_WHISPER", -- [18]
"MONSTER_BOSS_EMOTE", -- [19]
"MONSTER_BOSS_WHISPER", -- [20]
"ERRORS", -- [21]
"AFK", -- [22]
"DND", -- [23]
"IGNORED", -- [24]
"BG_HORDE", -- [25]
"BG_ALLIANCE", -- [26]
"BG_NEUTRAL", -- [27]
"COMBAT_FACTION_CHANGE", -- [28]
"SKILL", -- [29]
"LOOT", -- [30]
"MONEY", -- [31]
"CHANNEL", -- [32]
"ACHIEVEMENT", -- [33]
"GUILD_ACHIEVEMENT", -- [34]
},
["channels"] = {
},
},
},
["auto"] = false,
["currentProfile"]="default",
["GlobalProfiles"] = {
["default"] = {
"default1", -- [1]
"default2", -- [2]
"default3", -- [3]
"default4", -- [4]
"default5", -- [5]
"default6", -- [6]
"default7", -- [7]
},
},
};
 
local ldb = LibStub:GetLibrary("LibDataBroker-1.1")
 
local frame = CreateFrame("FRAME","ChatProfilesFrame")
frame:RegisterEvent("ADDON_LOADED")
frame:RegisterEvent("PARTY_MEMBERS_CHANGED")
 
local UnknownIconPath = "Interface\\Icons\\INV_Misc_QuestionMark"
local OnIconPath ="Interface\\Icons\\INV_Jewelry_Ring_64"
local OffIconPath ="Interface\\Icons\\INV_Jewelry_Ring_65"
 
local ldbstream = ldb:NewDataObject("ChatProfiles",{type = "data source", icon = UnknownIconPath, label="ChatProfiles", text = ""})
 
CHATPROFILES_LOADED = false;
 
--taken from http://www.wowwiki.com/Extracting_info_from_a_slash_command#Parsing_Into_Tables, 2009-04-01
local function MsgToTable( msg )
if not msg then return end
local t = {};
gsub( msg, "%S+", function(w)
tinsert( t, w )
end)
return t;
end
 
 
local function ChatMessage(msg)
DEFAULT_CHAT_FRAME:AddMessage("|cff99BBEEChatProfiles:|r "..msg);
end
 
local function LDBAutoChanged()
if ChatProfiles.auto then
ldbstream.icon = OnIconPath
else
ldbstream.icon = OffIconPath
end
end
 
local function LDBProfileChanged()
ldbstream.text = ChatProfiles.currentProfile
end
 
local function DisableAuto()
ChatProfiles.auto = false;
ChatMessage("Auto is now |cffAA0033off|r")
LDBAutoChanged()
end
 
function LoadChatWindowProfile(chatFrame, profile)
ChatFrame_RemoveAllMessageGroups(chatFrame);
ChatFrame_RemoveAllChannels(chatFrame);
for i=1,#profile["messages"] do
ChatFrame_AddMessageGroup(chatFrame, profile["messages"][i]);
end
for i=1,#profile["channels"] do
ChatFrame_AddChannel(chatFrame, profile["channels"][i]);
end
end
 
local function CreateGlobalProfile(profileName)
ChatProfiles.GlobalProfiles[profileName]={};
for i=1,7 do
local messages = { GetChatWindowMessages(i)};
local channels = { GetChatWindowChannels(i)};
local channels2={};
for i=1,#channels do
if i%2==1 then
local value = floor(i/2)+1;
channels2[value] = channels[i];
end
end
ChatProfiles.ChatWindowProfiles[profileName..i]={["messages"]=messages,["channels"]=channels2};
ChatProfiles.GlobalProfiles[profileName][i] = profileName..i;
end
if profileName ~= "lastprofile" then ChatMessage("A profile named '"..profileName.."' has been created") end
end
 
local function LoadGlobalProfile(profileName)
if ChatProfiles.GlobalProfiles[profileName]==nil then
ChatMessage("No profile named '"..profileName.."' loading 'default' instead");
LoadGlobalProfile("default");
DisableAuto();
else
if profileName ~= "lastprofile" then CreateGlobalProfile("lastprofile") end
for i in pairs(ChatProfiles.GlobalProfiles[profileName]) do
LoadChatWindowProfile(getglobal("ChatFrame"..i),ChatProfiles.ChatWindowProfiles[ChatProfiles.GlobalProfiles[profileName][i]]);
end
if profileName ~= "lastprofile" then ChatMessage("Profile '"..profileName.."' has been loaded, get last profile with /cp last")
else ChatMessage("Last profile has been loaded") end
ChatProfiles.currentProfile=profileName;
end
end
 
local function UpdateGlobalProfile()
if ChatProfiles.auto then
if GetNumRaidMembers()>0 then
if ChatProfiles.currentProfile ~="raid" then
LoadGlobalProfile("raid");
end
elseif GetNumPartyMembers()>0 then
if ChatProfiles.currentProfile ~="party" then
LoadGlobalProfile("party");
end
else
if ChatProfiles.currentProfile ~="solo" then
LoadGlobalProfile("solo");
end
end
end
LDBAutoChanged()
LDBProfileChanged()
end
 
-- local function DeleteGlobalProfile(profileName)
-- if (profileName == "default" or profileName == "lastprofile") then
-- ChatMessage("You can't delete profile '"..profileName.."'");
-- else
-- tremove(ChatProfiles.GlobalProfiles,profileName);
-- for i=1,7 do
-- tremove(ChatProfiles.ChatWindowProfiles,profileName..i);
-- end
-- ChatMessage("Profile '"..profileName.."' has been deleted");
-- end
-- end
 
local function SetAuto(state)
ChatProfiles.auto = state;
ChatMessage("Auto is now "..(state and "|cff339911on|r" or "|cffAA0033off|r"));
UpdateGlobalProfile();
end
 
local function ToggleAuto()
if ChatProfiles.auto then SetAuto(false) else SetAuto(true) end
end
 
local function ChatProfiles_SlashCommandHandler(msg)
if msg == "auto" then
ChatMessage("Auto is "..(ChatProfiles.auto and "|cff339911on|r" or "|cffAA0033off|r"))
elseif msg == "auto on" then
SetAuto(true);
elseif msg == "auto off" then
SetAuto(false);
elseif msg == "auto toggle" then
ToggleAuto();
 
elseif msg == "last" then
LoadGlobalProfile("lastprofile");
SetAuto(false);
 
elseif msg == "profiles" then
local text="Profiles\n";
for v in pairs(ChatProfiles.GlobalProfiles) do
if v == ChatProfiles.currentProfile then
text=text.."|cff77BBEE"..v.."|r\n"
else
text=text..v.."\n"
end
end
ChatMessage(text);
elseif msg == "current" then
ChatMessage("Current profile is '"..ChatProfiles.currentProfile.."'");
 
elseif msg == "frames" then
local text ="Frame Name : #\n";
for i=1,7 do text=text..GetChatWindowInfo(i)..": "..i.."\n" end
ChatMessage(text);
elseif msg == "store" then
ChatMessage("/cp store profileName");
elseif msg == "load" then
ChatMessage("/cp load profileName");
else
msg = MsgToTable(msg);
if #msg==2 then
if msg[1] == "store" then
CreateGlobalProfile(msg[2]);
elseif msg[1] == "load" then
LoadGlobalProfile(msg[2]);
SetAuto(false);
-- elseif msg[1] == "delete" then
-- DeleteGlobalProfile(msg[2]);
end
else
--No match found, return standard phrase
ChatMessage("/cp <command>\n<command>: auto [/on/off/toggle], last, current, profiles, frames, store, load");
end
end
end
 
function ldbstream:OnTooltipShow()
self:AddLine("Profiles:")
local text="";
for v in pairs(ChatProfiles.GlobalProfiles) do
if v == ChatProfiles.currentProfile then
text=text.."|cff77BBEE"..v.."|r\n"
else
text=text.."|cffffffff"..v.."|r\n"
end
end
self:AddLine(text)
self:AddLine("Auto: "..(ChatProfiles.auto and "|cff339911on|r" or "|cffAA0033off|r"));
end
 
function ldbstream:OnEnter()
GameTooltip:SetOwner(self, "ANCHOR_NONE")
GameTooltip:SetPoint("TOPLEFT", self, "BOTTOMLEFT")
GameTooltip:ClearLines()
ldbstream.OnTooltipShow(GameTooltip)
GameTooltip:Show()
end
 
function ldbstream:OnLeave()
GameTooltip:Hide()
end
 
function ldbstream:OnClick(self, button)
ToggleAuto()
end
 
 
local function OnEvent(self, event, ...)
if event=="ADDON_LOADED" and arg1 == "ChatProfiles" then
if ChatProfiles == nil then
ChatProfiles = ChatProfiles_Defaults;
end
CHATPROFILES_LOADED = true;
DEFAULT_CHAT_FRAME:AddMessage("|cff99BBEEChatProfiles|r loaded successfully! Auto is "..(ChatProfiles.auto and "|cff339911on|r" or "|cffAA0033off|r"));
UpdateGlobalProfile();
elseif event=="PARTY_MEMBERS_CHANGED" and CHATPROFILES_LOADED then
--ChatMessage("Party!");
UpdateGlobalProfile();
end
end
 
frame:SetScript("OnEvent", OnEvent);
 
SLASH_CHATPROFILES1 = "/chatprofiles";
SLASH_CHATPROFILES2 = "/cp";
SlashCmdList["CHATPROFILES"] = function (msg) ChatProfiles_SlashCommandHandler(msg) end;
\ No newline at end of file
0.3beta/ChatProfiles.toc New file
0,0 → 1,16
## Interface: 30000
## Title: ChatProfiles
## Notes: Changes chat profiles based on events.
## Author: Nitra - Nagrand (EU)
## X-eMail: niteniten58@gmail.com
## X-Embeds: CallbackHandler-1.0, LibStub
## Version: 0.2beta
## DefaultState: Enabled
## LoadOnDemand: 0
## SavedVariablesPerCharacter: ChatProfiles
 
libs\LibStub\LibStub.lua
libs\CallbackHandler-1.0\CallbackHandler-1.0.lua
libs\LibDataBroker-1.1\LibDataBroker-1.1.lua
 
ChatProfiles.lua
\ No newline at end of file
0.3beta/libs/LibDataBroker-1.1/LibDataBroker-1.1.lua New file
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
0.3beta/libs/LibDataBroker-1.1/README.textile New file
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
0.3beta/libs/LibStub/Changelog-LibStub-1.0.txt New file
0,0 → 1,10
------------------------------------------------------------------------
r90 | nevcairiel | 2008-09-30 06:01:35 +0000 (Tue, 30 Sep 2008) | 1 line
Changed paths:
A /tags/1.0
A /tags/1.0/.pkgmeta
A /tags/1.0/LibStub.lua
A /tags/1.0/LibStub.toc
 
Add 1.0 tag
------------------------------------------------------------------------
0.3beta/libs/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
0.3beta/libs/LibStub/LibStub.toc New file
0,0 → 1,9
## Interface: 20400
## Title: Lib: LibStub
## Notes: Universal Library Stub
## Credits: Kaelten, Cladhaire, ckknight, Mikk, Ammo, Nevcairiel
## X-Website: http://jira.wowace.com/browse/LS
## X-Category: Library
## X-License: Public Domain
 
LibStub.lua
0.3beta/libs/CallbackHandler-1.0/CallbackHandler-1.0.lua New file
0,0 → 1,239
--[[ $Id: CallbackHandler-1.0.lua 3 2008-09-29 16:54:20Z nevcairiel $ ]]
local MAJOR, MINOR = "CallbackHandler-1.0", 3
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}
 
local type = type
local pcall = pcall
local pairs = pairs
local assert = assert
local concat = table.concat
local loadstring = loadstring
local next = next
local select = select
local type = type
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", concat(OLD_ARGS, ", ")):gsub("ARGS", concat(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"
if type(self)~="table" and type(self)~="string" then
error("Usage: "..RegisterName.."(self or \"addonId\", eventname, method): 'self or addonId': table or string 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.
 
0.3beta/libs/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