Give pfUI its own EventRegistry and move event-only frames onto it

pfUI.events was a bare CallbackRegistry for pfUI's custom events. Build it
from ClassicAPI's EventRegistry instead, so the same object also takes game
events through RegisterFrameEventAndCallback, sharing one frame for all of
them.

Move the frames that existed only to listen for a few events onto it:
libspell, focus, pixelperfect, innervatecall, loothistory, unusable,
equipmentmanager (bank + window refresh), the actionbar grid, updatenotify,
turtle-wow's steady shot, nampower's spell queue, superwow's group tracking
and unitxp's notifications, plus newitem and mapreveal, which used the
global EventRegistry. Handlers take their payload as arguments instead of
the event/arg globals, and the per-frame PLAYER_LOGOUT teardown goes away,
since the registry unregisters its frame on logout.
This commit is contained in:
Brues
2026-10-30 12:37:56 -05:00
parent b0f9b7b993
commit f37ea00226
16 changed files with 101 additions and 166 deletions
+4 -17
View File
@@ -1502,23 +1502,10 @@ pfUI:RegisterModule("actionbar", function ()
_G.ShapeshiftBar_ChangeForm = function(slot) pfActionButton(slot, nil, "ShapeShiftBar") end
-- handle drag-drop grid
local grid = CreateFrame("Frame")
grid:RegisterEvent("ACTIONBAR_SHOWGRID")
grid:RegisterEvent("ACTIONBAR_HIDEGRID")
grid:RegisterEvent("PET_BAR_SHOWGRID")
grid:RegisterEvent("PET_BAR_HIDEGRID")
grid:SetScript("OnEvent", function()
if event == "ACTIONBAR_SHOWGRID" then
pfUI.bars:UpdateGrid(1)
elseif event == "ACTIONBAR_HIDEGRID" then
pfUI.bars:UpdateGrid(0)
elseif event == "PET_BAR_SHOWGRID" then
pfUI.bars:UpdateGrid(1, "PET")
elseif event == "PET_BAR_HIDEGRID" then
pfUI.bars:UpdateGrid(0, "PET")
end
end)
pfUI.events:RegisterFrameEventAndCallback("ACTIONBAR_SHOWGRID", function() pfUI.bars:UpdateGrid(1) end)
pfUI.events:RegisterFrameEventAndCallback("ACTIONBAR_HIDEGRID", function() pfUI.bars:UpdateGrid(0) end)
pfUI.events:RegisterFrameEventAndCallback("PET_BAR_SHOWGRID", function() pfUI.bars:UpdateGrid(1, "PET") end)
pfUI.events:RegisterFrameEventAndCallback("PET_BAR_HIDEGRID", function() pfUI.bars:UpdateGrid(0, "PET") end)
-- reagent counter
if C.bars.reagents == "1" then
+19 -21
View File
@@ -1243,23 +1243,22 @@ pfUI:RegisterModule("equipmentmanager", function()
UpdateBagHighlights()
end)
local bankEvents = CreateFrame("Frame")
bankEvents:RegisterEvent("BANKFRAME_OPENED")
bankEvents:RegisterEvent("BANKFRAME_CLOSED")
bankEvents:RegisterEvent("PLAYERBANKSLOTS_CHANGED")
bankEvents:RegisterEvent("BAG_UPDATE_DELAYED")
bankEvents:RegisterEvent("EQUIPMENT_SETS_CHANGED")
bankEvents:SetScript("OnEvent", function()
if event == "BANKFRAME_OPENED" then
bankOpen = true
elseif event == "BANKFRAME_CLOSED" then
bankOpen = false
return
end
local function RescanBank()
if not bankOpen then return end
ScanBank()
if frame:IsShown() then pfUI.equipmentmanager.Refresh() end
end
pfUI.events:RegisterFrameEventAndCallback("BANKFRAME_OPENED", function()
bankOpen = true
RescanBank()
end)
pfUI.events:RegisterFrameEventAndCallback("BANKFRAME_CLOSED", function()
bankOpen = false
end)
for _, event in ipairs({ "PLAYERBANKSLOTS_CHANGED", "BAG_UPDATE_DELAYED", "EQUIPMENT_SETS_CHANGED" }) do
pfUI.events:RegisterFrameEventAndCallback(event, RescanBank)
end
-- ============================================================
-- Automatic set switching (triggers)
@@ -2084,15 +2083,14 @@ pfUI:RegisterModule("equipmentmanager", function()
-- Events
-- ============================================================
local events = CreateFrame("Frame")
events:RegisterEvent("EQUIPMENT_SETS_CHANGED")
events:RegisterEvent("EQUIPMENT_SWAP_FINISHED")
events:RegisterEvent("EQUIPMENT_SWAP_PENDING")
events:RegisterEvent("BAG_UPDATE_DELAYED")
events:RegisterEvent("PLAYER_EQUIPMENT_CHANGED")
events:SetScript("OnEvent", function()
local function RefreshShown()
if not frame:IsShown() then return end
pfUI.equipmentmanager.Refresh()
end)
end
for _, event in ipairs({ "EQUIPMENT_SETS_CHANGED", "EQUIPMENT_SWAP_FINISHED", "EQUIPMENT_SWAP_PENDING",
"BAG_UPDATE_DELAYED", "PLAYER_EQUIPMENT_CHANGED" }) do
pfUI.events:RegisterFrameEventAndCallback(event, RefreshShown)
end
end)
+1 -3
View File
@@ -18,9 +18,7 @@ pfUI:RegisterModule("focus", function ()
-- Between events, ClassicAPI fires UNIT_* (health/mana/aura/...) with
-- arg1 == "focus" and arg1 == "focustarget", so both frames update
-- event-driven like target and need no polling tick.
local refresher = CreateFrame("Frame")
refresher:RegisterEvent("PLAYER_FOCUS_CHANGED")
refresher:SetScript("OnEvent", function()
pfUI.events:RegisterFrameEventAndCallback("PLAYER_FOCUS_CHANGED", function()
pfUI.uf.focus.instantRefresh = true
pfUI.uf:RefreshUnit(pfUI.uf.focus, "all")
pfUI.uf.focustarget.instantRefresh = true
+7 -12
View File
@@ -46,22 +46,17 @@ pfUI:RegisterModule("innervatecall", function ()
end)
end
local frame = CreateFrame("Frame")
frame:RegisterEvent("COMBAT_LOG_EVENT_UNFILTERED")
frame:RegisterEvent("SPELL_UPDATE_COOLDOWN")
frame:SetScript("OnEvent", function()
if event == "SPELL_UPDATE_COOLDOWN" then
if pending then ScheduleReady() end
return
end
pfUI.events:RegisterFrameEventAndCallback("SPELL_UPDATE_COOLDOWN", function()
if pending then ScheduleReady() end
end)
pfUI.events:RegisterFrameEventAndCallback("COMBAT_LOG_EVENT_UNFILTERED", function()
-- Innervate is instant, so it logs SPELL_CAST_SUCCESS with its target
-- arg2=subevent, arg4=sourceGUID, arg9=destName, arg12=spellId
if arg2 ~= "SPELL_CAST_SUCCESS" or arg12 ~= INNERVATE_SPELLID then return end
local _, subevent, _, sourceGUID, _, _, _, _, destName, _, _, spellId = CombatLogGetCurrentEventInfo()
if subevent ~= "SPELL_CAST_SUCCESS" or spellId ~= INNERVATE_SPELLID then return end
-- Only announce our own casts
if not IsPlayerGuid(arg4) then return end
local destName = arg9
if not IsPlayerGuid(sourceGUID) then return end
-- Determine channel
local channel = GetAnnounceChannel()
+8 -10
View File
@@ -318,20 +318,18 @@ pfUI:RegisterModule("loothistory", function ()
-- ==========================================================================
-- Events
-- ==========================================================================
local events = CreateFrame("Frame")
events:RegisterEvent("LOOT_HISTORY_FULL_UPDATE")
events:RegisterEvent("LOOT_HISTORY_ROLL_CHANGED")
events:RegisterEvent("LOOT_HISTORY_ROLL_COMPLETE")
events:SetScript("OnEvent", function()
-- auto-show on a new roll opening / completing, if enabled
if C.loothistory.autoshow == "1"
and (event == "LOOT_HISTORY_FULL_UPDATE" or event == "LOOT_HISTORY_ROLL_COMPLETE")
and not pfUI.loothistory:IsShown() then
-- auto-show on a new roll opening / completing, if enabled
local function AutoShow()
if C.loothistory.autoshow == "1" and not pfUI.loothistory:IsShown() then
pfUI.loothistory:Show() -- OnShow runs FullUpdate
return
end
FullUpdate() -- no-op while hidden
end)
end
pfUI.events:RegisterFrameEventAndCallback("LOOT_HISTORY_FULL_UPDATE", AutoShow)
pfUI.events:RegisterFrameEventAndCallback("LOOT_HISTORY_ROLL_COMPLETE", AutoShow)
pfUI.events:RegisterFrameEventAndCallback("LOOT_HISTORY_ROLL_CHANGED", FullUpdate)
-- ==========================================================================
-- Slash command
+1 -1
View File
@@ -180,7 +180,7 @@ pfUI:RegisterModule("mapreveal", function ()
-- above, so nothing is redrawn while the map is closed — the next open
-- rebuilds from the current state.
EventRegistry:RegisterFrameEventAndCallback("MAP_EXPLORATION_UPDATED", function()
pfUI.events:RegisterFrameEventAndCallback("MAP_EXPLORATION_UPDATED", function()
if WorldMapFrame and WorldMapFrame:IsShown() then
pfWorldMapFrame_Update()
end
+1 -13
View File
@@ -41,19 +41,7 @@ pfUI:RegisterModule("nampower", function ()
local NON_GCD_QUEUED = 4
local NON_GCD_QUEUE_POPPED = 5
local queue = CreateFrame("Frame")
queue:RegisterEvent("SPELL_QUEUE_EVENT")
queue:RegisterEvent("PLAYER_LOGOUT")
queue:SetScript("OnEvent", function()
-- Handle shutdown to prevent crash 132
if event == "PLAYER_LOGOUT" then
this:UnregisterAllEvents()
this:SetScript("OnEvent", nil)
return
end
local eventCode, spellId = arg1, arg2
pfUI.events:RegisterFrameEventAndCallback("SPELL_QUEUE_EVENT", function(_, eventCode, spellId)
if eventCode == NORMAL_QUEUED or eventCode == NON_GCD_QUEUED or eventCode == ON_SWING_QUEUED then
local texture = C_Spell.GetSpellTexture(spellId)
if texture then
+1 -1
View File
@@ -57,7 +57,7 @@ pfUI:RegisterModule("newitem", function ()
pfUI.newitem:UpdateSlot(bag, slot)
end)
EventRegistry:RegisterFrameEventAndCallback("BAG_NEW_ITEMS_UPDATED", function()
pfUI.events:RegisterFrameEventAndCallback("BAG_NEW_ITEMS_UPDATED", function()
pfUI.newitem:RefreshAll()
end)
+1 -3
View File
@@ -33,9 +33,7 @@ pfUI:RegisterModule("pixelperfect", function ()
-- pixelperfect: native UIScale listener
if tonumber(C.global.pixelperfect) > 0 then
local f = CreateFrame("Frame")
f:RegisterEvent("PLAYER_ENTERING_WORLD")
f:SetScript("OnEvent", pixelperfect)
pfUI.events:RegisterFrameEventAndCallback("PLAYER_ENTERING_WORLD", pixelperfect)
pixelperfect()
end
+6 -15
View File
@@ -95,20 +95,7 @@ pfUI:RegisterModule("superwow", function ()
-- TrackUnit API for adding group members to minimap
-- Tracks friendly units on the minimap for easier group coordination
if TrackUnit and C.unitframes.track_group == "1" then
local trackFrame = CreateFrame("Frame")
trackFrame:RegisterEvent("PARTY_MEMBERS_CHANGED")
trackFrame:RegisterEvent("RAID_ROSTER_UPDATE")
trackFrame:RegisterEvent("PLAYER_ENTERING_WORLD")
trackFrame:RegisterEvent("PLAYER_LOGOUT")
trackFrame:SetScript("OnEvent", function()
-- Handle shutdown to prevent crash 132
if event == "PLAYER_LOGOUT" then
this:UnregisterAllEvents()
this:SetScript("OnEvent", nil)
return
end
local function TrackGroup()
-- Track party members
for i = 1, 4 do
local unit = "party" .. i
@@ -124,7 +111,11 @@ pfUI:RegisterModule("superwow", function ()
pcall(TrackUnit, unit)
end
end
end)
end
pfUI.events:RegisterFrameEventAndCallback("PARTY_MEMBERS_CHANGED", TrackGroup)
pfUI.events:RegisterFrameEventAndCallback("RAID_ROSTER_UPDATE", TrackGroup)
pfUI.events:RegisterFrameEventAndCallback("PLAYER_ENTERING_WORLD", TrackGroup)
end
-- Raid Marker Targeting API
+1 -5
View File
@@ -247,11 +247,7 @@ pfUI:RegisterModule("turtle-wow", function ()
local STEADY_SHOT_DURATION_MS = 1400 -- not haste-scaled; close enough for the visual cue
local ON_SWING_QUEUED, ON_SWING_QUEUE_POPPED = 0, 1
local steadyShot = CreateFrame("Frame")
steadyShot:RegisterEvent("SPELL_QUEUE_EVENT")
steadyShot:SetScript("OnEvent", function()
if event ~= "SPELL_QUEUE_EVENT" then return end
local eventCode, spellId = arg1, arg2
pfUI.events:RegisterFrameEventAndCallback("SPELL_QUEUE_EVENT", function(_, eventCode, spellId)
if eventCode ~= ON_SWING_QUEUED and eventCode ~= ON_SWING_QUEUE_POPPED then return end
if C_Spell.GetSpellName(spellId) ~= steadyShotName then return end
if eventCode == ON_SWING_QUEUED then
+6 -16
View File
@@ -253,24 +253,14 @@ pfUI:RegisterModule("unitxp", function ()
-- OS Notification Support
if C.unitframes.unitxp_notify == "1" then
local notifyFrame = CreateFrame("Frame")
notifyFrame:RegisterEvent("CHAT_MSG_WHISPER")
notifyFrame:RegisterEvent("CHAT_MSG_BN_WHISPER")
notifyFrame:RegisterEvent("READY_CHECK")
notifyFrame:RegisterEvent("RAID_INSTANCE_WELCOME")
notifyFrame:RegisterEvent("PLAYER_LOGOUT")
notifyFrame:SetScript("OnEvent", function()
-- Handle shutdown to prevent crash 132
if event == "PLAYER_LOGOUT" then
this:UnregisterAllEvents()
this:SetScript("OnEvent", nil)
return
end
local function Notify()
pcall(UnitXP, "notify", "taskbarIcon")
pcall(UnitXP, "notify", "systemSound")
end)
end
for _, event in ipairs({ "CHAT_MSG_WHISPER", "CHAT_MSG_BN_WHISPER", "READY_CHECK", "RAID_INSTANCE_WELCOME" }) do
pfUI.events:RegisterFrameEventAndCallback(event, Notify)
end
-- Also notify on BG queue pop
local origBattlefieldPortShow = BattlefieldFrame_Show
+7 -8
View File
@@ -38,13 +38,7 @@ pfUI:RegisterModule("unusable", function ()
-- requirement changes (level, proficiency/skill, required spell, reputation,
-- honor rank) don't touch the bags; queue a full rebag through pfUI.bag's
-- coalesced delay, whose UpdateSlot resets the tint before we reapply it
local refresh = CreateFrame("Frame")
refresh:RegisterEvent("PLAYER_LEVEL_UP")
refresh:RegisterEvent("SKILL_LINES_CHANGED")
refresh:RegisterEvent("SPELLS_CHANGED")
refresh:RegisterEvent("FACTION_STANDING_CHANGED")
refresh:RegisterEvent("PLAYER_PVP_RANK_CHANGED")
refresh:SetScript("OnEvent", function()
local function Refresh()
for _, bag in pairs(pfUI.BACKPACK) do
pfUI.bag.delay.UpdateBag[bag] = true
end
@@ -54,5 +48,10 @@ pfUI:RegisterModule("unusable", function ()
pfUI.bag.delay.UpdateBag[bag] = true
end
end
end)
end
for _, event in ipairs({ "PLAYER_LEVEL_UP", "SKILL_LINES_CHANGED", "SPELLS_CHANGED",
"FACTION_STANDING_CHANGED", "PLAYER_PVP_RANK_CHANGED" }) do
pfUI.events:RegisterFrameEventAndCallback(event, Refresh)
end
end)
+33 -36
View File
@@ -12,44 +12,41 @@ pfUI:RegisterModule("updatenotify", function ()
local localbranch = "main"
local versionmsg = "VERSION:" .. localversion .. ":" .. localbranch
pfUI.updater = CreateFrame("Frame")
pfUI.updater:RegisterEvent("CHAT_MSG_ADDON")
pfUI.updater:RegisterEvent("PLAYER_ENTERING_WORLD")
pfUI.updater:RegisterEvent("PARTY_MEMBERS_CHANGED")
pfUI.updater:SetScript("OnEvent", function()
if event == "CHAT_MSG_ADDON" and arg1 == ADDON_PREFIX then
local v, rv, branch = pfUI.api.strsplit(":", arg2)
rv = tonumber(rv)
-- only process VERSION messages from the same branch
-- messages without a branch tag (old versions) are ignored
if v == "VERSION" and rv and branch == localbranch then
if rv > localversion then
pfUI_init.updateavailable = rv
end
end
end
pfUI.events:RegisterFrameEventAndCallback("CHAT_MSG_ADDON", function(_, prefix, message)
if prefix ~= ADDON_PREFIX then return end
if event == "PARTY_MEMBERS_CHANGED" then
local groupsize = IsInRaid() and GetNumRaidMembers() or IsInGroup() and GetNumPartyMembers() or 0
if ( this.group or 0 ) < groupsize then
for _, chan in pairs(groupchannels) do
SendAddonMessage(ADDON_PREFIX, versionmsg, chan)
end
end
this.group = groupsize
end
if event == "PLAYER_ENTERING_WORLD" then
if not alreadyshown and localversion < remoteversion then
DEFAULT_CHAT_FRAME:AddMessage(string.format(T["|cff33ffccpf|rUI: New version available! Get it at %s"], GetAddOnMetadata(pfUI.name, "X-Website") .. "/releases"))
DEFAULT_CHAT_FRAME:AddMessage(T["|cffddddddIt's always safe to upgrade |cff33ffccpf|rUI. |cffddddddYou won't lose any of your configuration."])
pfUI_init.updateavailable = localversion
alreadyshown = true
end
for _, chan in pairs(loginchannels) do
SendAddonMessage(ADDON_PREFIX, versionmsg, chan)
local v, rv, branch = pfUI.api.strsplit(":", message)
rv = tonumber(rv)
-- only process VERSION messages from the same branch
-- messages without a branch tag (old versions) are ignored
if v == "VERSION" and rv and branch == localbranch then
if rv > localversion then
pfUI_init.updateavailable = rv
end
end
end)
local group = 0
pfUI.events:RegisterFrameEventAndCallback("PARTY_MEMBERS_CHANGED", function()
local groupsize = IsInRaid() and GetNumRaidMembers() or IsInGroup() and GetNumPartyMembers() or 0
if group < groupsize then
for _, chan in pairs(groupchannels) do
SendAddonMessage(ADDON_PREFIX, versionmsg, chan)
end
end
group = groupsize
end)
pfUI.events:RegisterFrameEventAndCallback("PLAYER_ENTERING_WORLD", function()
if not alreadyshown and localversion < remoteversion then
DEFAULT_CHAT_FRAME:AddMessage(string.format(T["|cff33ffccpf|rUI: New version available! Get it at %s"], GetAddOnMetadata(pfUI.name, "X-Website") .. "/releases"))
DEFAULT_CHAT_FRAME:AddMessage(T["|cffddddddIt's always safe to upgrade |cff33ffccpf|rUI. |cffddddddYou won't lose any of your configuration."])
pfUI_init.updateavailable = localversion
alreadyshown = true
end
for _, chan in pairs(loginchannels) do
SendAddonMessage(ADDON_PREFIX, versionmsg, chan)
end
end)
end)