From f926ac5521b6461167fbeb410c3b08523e4a42d9 Mon Sep 17 00:00:00 2001 From: Brues <5278969+brues-code@users.noreply.github.com> Date: Sun, 21 Jun 2026 01:59:49 -0500 Subject: [PATCH] Replace custom/UnitXP timers with ClassicAPI C_Timer - ScheduleTimer now wraps C_Timer.After, removing the dedicated timer frame + per-frame OnUpdate loop + timers queue. - Aura-tracking cleanup -> C_Timer.NewTicker(5) (_auraCleanupTicker); drop the UnitXP arm, the named global CleveRoids_AuraTrackingCleanupTimer, and the inline "not hasUnitXP" fallback in OnAuraCastOther. - Libdebuff cleanup -> C_Timer.NewTicker(30) (_cleanupTicker); drop the UnitXP arm and CleveRoids_LibDebuffCleanupTimer. - Shutdown cancels the tickers instead of UnitXP timer disarm. Cleanup now always runs (was gated on hasUnitXP) and no longer depends on UnitXP threaded timers or named global callbacks. Tickers self-guard on isShuttingDown and are cancelled on shutdown. --- Compatibility/pfUI.lua | 28 ++++++---------------------- Conditionals.lua | 24 ++++++------------------ Core.lua | 14 ++++++-------- Utility.lua | 21 +++++++-------------- 4 files changed, 25 insertions(+), 62 deletions(-) diff --git a/Compatibility/pfUI.lua b/Compatibility/pfUI.lua index a79bb82..1d0d531 100644 --- a/Compatibility/pfUI.lua +++ b/Compatibility/pfUI.lua @@ -786,30 +786,14 @@ function Extension.PLAYER_LOGIN() end end --- Utility: Schedule a delayed function call (if not already defined) +-- Utility: Schedule a delayed function call via ClassicAPI's C_Timer. if not CleveRoids.ScheduleTimer then - local timerFrame = CreateFrame("Frame") - local timers = {} - - timerFrame:SetScript("OnUpdate", function() - -- Prevent SuperWoW API calls during shutdown (crash prevention) - if CleveRoids.isShuttingDown then return end - - local time = GetTime() - for i = table.getn(timers), 1, -1 do - local timer = timers[i] - if time >= timer.time then - timer.func() - table.remove(timers, i) - end - end - end) - CleveRoids.ScheduleTimer = function(func, delay) - table.insert(timers, { - func = func, - time = GetTime() + delay - }) + C_Timer.After(delay, function() + -- Prevent SuperWoW API calls during shutdown (crash prevention) + if CleveRoids.isShuttingDown then return end + func() + end) end end diff --git a/Conditionals.lua b/Conditionals.lua index 781747f..a1ef7eb 100644 --- a/Conditionals.lua +++ b/Conditionals.lua @@ -1364,14 +1364,7 @@ local function OnAuraCastOther(spellId, casterGuid, targetGuid, effect, effectAu entry.timestamp = now end - -- Cleanup moved to CleveRoids.CleanupAuraTracking(), called by UnitXP timer when available - -- Fallback: inline throttled cleanup when UnitXP is not present - if not CleveRoids.hasUnitXP then - if (now - CleveRoids.AuraCapStatus.lastCleanupTime) >= 5 then - CleveRoids.AuraCapStatus.lastCleanupTime = now - CleveRoids.CleanupAuraTracking(now) - end - end + -- Periodic cleanup runs on a C_Timer ticker (see CleanupAuraTracking below). end --- Periodic cleanup of AuraCapStatus and AllCasterAuraTracking tables @@ -1431,16 +1424,11 @@ function CleveRoids.CleanupAuraTracking(now) end end --- UnitXP threaded timer for aura tracking cleanup (5s interval) --- Replaces inline cleanup that ran on every aura event -if CleveRoids.hasUnitXP then - function CleveRoids_AuraTrackingCleanupTimer() - if CleveRoids.isShuttingDown then return end - CleveRoids.CleanupAuraTracking() - end - - CleveRoids._auraCleanupTimerId = UnitXP("timer", "arm", 5000, 5000, "CleveRoids_AuraTrackingCleanupTimer") -end +-- Periodic aura-tracking cleanup via ClassicAPI's C_Timer (every 5s). +CleveRoids._auraCleanupTicker = C_Timer.NewTicker(5, function() + if CleveRoids.isShuttingDown then return end + CleveRoids.CleanupAuraTracking() +end) -- Create frame to listen for Nampower auto-attack and aura events local autoAttackFrame = CreateFrame("Frame", "CleveRoidsAutoAttackFrame") diff --git a/Core.lua b/Core.lua index 0338f68..6a6a7fc 100644 --- a/Core.lua +++ b/Core.lua @@ -5158,14 +5158,12 @@ function CleveRoids.Frame:PLAYER_LOGOUT() this:UnregisterAllEvents() this:SetScript("OnUpdate", nil) this:SetScript("OnEvent", nil) - -- Disarm UnitXP timers (they run in a separate thread and survive /reload) - if CleveRoids.hasUnitXP then - if CleveRoids._cleanupTimerId then - pcall(UnitXP, "timer", "disarm", CleveRoids._cleanupTimerId) - end - if CleveRoids._auraCleanupTimerId then - pcall(UnitXP, "timer", "disarm", CleveRoids._auraCleanupTimerId) - end + -- Cancel periodic C_Timer tickers + if CleveRoids._cleanupTicker then + CleveRoids._cleanupTicker:Cancel() + end + if CleveRoids._auraCleanupTicker then + CleveRoids._auraCleanupTicker:Cancel() end -- Clear spell caches to prevent stale data if CleveRoids.spellIdCache then diff --git a/Utility.lua b/Utility.lua index ccef890..97084b5 100644 --- a/Utility.lua +++ b/Utility.lua @@ -4218,21 +4218,14 @@ delayedTrackingFrame:SetScript("OnUpdate", function() end end) --- UnitXP threaded timer for periodic cleanup (runs in separate thread, fires only when due) --- Replaces piggyback on 20Hz OnUpdate — avoids function call overhead every 50ms -if CleveRoids.hasUnitXP then - -- Global callback (UnitXP timers require global function name as string) - function CleveRoids_LibDebuffCleanupTimer() - if CleveRoids.isShuttingDown then return end - local libRef = CleveRoids.libdebuff - if libRef and libRef.CleanupStaleTrackingData then - libRef:CleanupStaleTrackingData() - end +-- Periodic libdebuff cleanup via ClassicAPI's C_Timer (every 30s). +CleveRoids._cleanupTicker = C_Timer.NewTicker(30, function() + if CleveRoids.isShuttingDown then return end + local libRef = CleveRoids.libdebuff + if libRef and libRef.CleanupStaleTrackingData then + libRef:CleanupStaleTrackingData() end - - -- Arm timer: 30s initial delay, 30s repeat interval - CleveRoids._cleanupTimerId = UnitXP("timer", "arm", 30000, 30000, "CleveRoids_LibDebuffCleanupTimer") -end +end) local ev = CreateFrame("Frame", "CleveRoidsLibDebuffFrame", UIParent) ev:RegisterEvent("PLAYER_TARGET_CHANGED")