Last active
July 2, 2020 16:30
-
-
Save sylvanaar/aea7516e23ad0706cf1f7c19f4d34515 to your computer and use it in GitHub Desktop.
Idea for a library to handle addon output in a cleaner way
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
local lib, oldminor = LibStub:NewLibrary("LibChatTypes-1.0", 1) | |
if not lib then return end | |
local registry = {} | |
local emitterproto = {} | |
local function dbg(...) | |
--Prat:PrintLiteral(...) | |
end | |
local function createTypeEmitter(t, type) | |
return function(self, text) self:Output(text) end | |
end | |
function emitterproto:Output(type, text, ...) | |
local chattype = "ADDON_" .. self.key .. (type ~= nil and ("_" .. type) or "") | |
local event = "CHAT_MSG_" .. chattype | |
local i = 1 | |
local frame = _G['ChatFrame' .. i] | |
while frame do | |
if tContains(frame.messageTypeList, chattype) then | |
ChatFrame_MessageEventHandler(frame, event, text, '', '', '', '', '') | |
end | |
i = i + 1 | |
frame = _G['ChatFrame' .. i] | |
end | |
end | |
-- We allow for 2 sources of names, GetAddonName(), and LibStub()'s list of libraries | |
-- register basically tells this library that it should set up the chat types and create the pring | |
-- handler for the given soure | |
-- Call with :Register("Prat-3.0") | |
function lib:Register(name, ...) | |
if select(2, GetAddOnInfo(name)) == nil and LibStub:GetLibrary(name, true) == nil then | |
-- Trying to register invalid name should be and addon name or library name | |
end | |
local key = name:upper() | |
if registry[key] then | |
return registry[key] | |
end | |
local emitter = { key = key } | |
registry[key] = emitter | |
local baseEvent = "CHAT_MSG_ADDON_" .. key | |
local baseType = "ADDON_" .. key | |
-- Configure default formatting | |
_G["CHAT_" .. baseType .. "_GET"] = "" | |
ChatTypeInfo[baseType] = CopyTable(ChatTypeInfo["SAY"]) | |
local types = { ... } | |
local group = { baseEvent } | |
-- Add the chat type | |
ChatTypeGroup[baseType] = group | |
for i, v in ipairs(types) do | |
group[#group + 1] = baseEvent .. "_" .. v | |
end | |
-- Add a category for all addon messages | |
local category = CHAT_CATEGORY_LIST["ADDON"] or {} | |
tinsert(category, baseType) | |
CHAT_CATEGORY_LIST["ADDON"] = category | |
-- Add an option to control the output of the message | |
CHAT_CONFIG_CHAT_LEFT[#CHAT_CONFIG_CHAT_LEFT + 1] = { | |
type = baseType, | |
text = "Addon: " .. name, | |
checked = function() return IsListeningForMessageType(baseType); end; | |
func = function(self, checked) ToggleChatMessageGroup(checked, baseType); end; | |
} | |
ChatFrame_AddMessageGroup(ChatFrame1, baseType) | |
ChatConfig_CreateCheckboxes(ChatConfigChatSettingsLeft, CHAT_CONFIG_CHAT_LEFT, "ChatConfigWideCheckBoxWithSwatchTemplate", PLAYER_MESSAGES); | |
ChatConfig_UpdateCheckboxes(ChatConfigChatSettingsLeft); | |
emitter.types = types | |
setmetatable(emitter, { | |
__index = function(t, k) | |
if emitterproto[k] then return emitterproto[k] end | |
if type(t.types) == "table" then | |
return createTypeEmitter(t, k) | |
end | |
end, | |
__call = function(t, ...) | |
t:Output(nil, ...) | |
end | |
}) | |
return emitter | |
end | |
function lib:ReplaceChatFrameFunctions() | |
function ChatFrame_RegisterForMessages(self, ...) | |
local messageGroup; | |
local index = 1; | |
for i = 1, select("#", ...) do | |
messageGroup = ChatTypeGroup[select(i, ...)]; | |
if (messageGroup) then | |
self.messageTypeList[index] = select(i, ...); | |
for index, value in pairs(messageGroup) do | |
if not value:match("CHAT_MSG_ADDON_.+") then | |
self:RegisterEvent(value); | |
end | |
end | |
index = index + 1; | |
end | |
end | |
end | |
function ChatFrame_AddMessageGroup(chatFrame, group) | |
local info = ChatTypeGroup[group]; | |
if (info) then | |
tinsert(chatFrame.messageTypeList, group); | |
for index, value in pairs(info) do | |
if not value:match("CHAT_MSG_ADDON_.+") then | |
chatFrame:RegisterEvent(value); | |
end | |
end | |
AddChatWindowMessages(chatFrame:GetID(), group); | |
end | |
end | |
function ChatFrame_AddSingleMessageType(chatFrame, messageType) | |
local group = ChatTypeGroupInverted[messageType]; | |
local info = ChatTypeGroup[group]; | |
if (info) then | |
if (not tContains(chatFrame.messageTypeList, group)) then | |
tinsert(chatFrame.messageTypeList, group); | |
end | |
for index, value in pairs(info) do | |
if (value == messageType) and not value:match("CHAT_MSG_ADDON_.+") then | |
chatFrame:RegisterEvent(value); | |
end | |
end | |
end | |
end | |
function ChatFrame_RemoveMessageGroup(chatFrame, group) | |
local info = ChatTypeGroup[group]; | |
if (info) then | |
for index, value in pairs(chatFrame.messageTypeList) do | |
if (strupper(value) == strupper(group)) then | |
chatFrame.messageTypeList[index] = nil; | |
end | |
end | |
for index, value in pairs(info) do | |
if not value:match("CHAT_MSG_ADDON_.+") then | |
chatFrame:UnregisterEvent(value); | |
end | |
end | |
RemoveChatWindowMessages(chatFrame:GetID(), group); | |
end | |
end | |
function ChatFrame_RemoveAllMessageGroups(chatFrame) | |
for index, value in pairs(chatFrame.messageTypeList) do | |
for eventIndex, eventValue in pairs(ChatTypeGroup[value]) do | |
if not eventValue:match("CHAT_MSG_ADDON_.+") then | |
chatFrame:UnregisterEvent(eventValue); | |
end | |
end | |
RemoveChatWindowMessages(chatFrame:GetID(), value); | |
end | |
chatFrame.messageTypeList = {}; | |
end | |
end | |
lib:ReplaceChatFrameFunctions() | |
Two thoughts:
-
I don't know if it's possible, but organizationally, it would make sense to have a category in the left hand column called Addons, and then list all addons under that with just their name.
-
This would be most useful for addons that have a lot of chat output. The big one that comes to mind is DBM, but perhaps some of the roleplay-type addons could also benefit.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
So if I run it with Prat's module that shows the event type for each message i get:
Also it has set up
and