From 2a85b80c389553e96af85fcaac165488bf6df431 Mon Sep 17 00:00:00 2001 From: Tuller Date: Sun, 6 Nov 2011 12:12:25 -0500 Subject: [PATCH] added fixes for timers in WoW 4.3 --- cc.lua | 52 ++++++++++++++++++++++++------------------- compat43.lua | 70 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ config.lua | 4 ++-- tullaCC.toc | 1 + 4 files changed, 102 insertions(+), 25 deletions(-) create mode 100644 compat43.lua diff --git a/cc.lua b/cc.lua index 9696a25..7e1ceaf 100644 --- a/cc.lua +++ b/cc.lua @@ -9,8 +9,12 @@ --hacks! OmniCC = OmniCC or true --hack to work around detection from other addons for OmniCC +local AddonName, Addon = ... +local Timer = {}; Addon.Timer = Timer + + --local bindings! -local C = select(2, ...) --pull in the addon table +local C = Addon.Config --pull in the addon table local UIParent = _G['UIParent'] local GetTime = _G['GetTime'] local floor = math.floor @@ -57,7 +61,7 @@ local function getTimeText(s) end end -local function Timer_SetNextUpdate(self, nextUpdate) +function Timer.SetNextUpdate(self, nextUpdate) self.updater:GetAnimations():SetDuration(nextUpdate) if self.updater:IsPlaying() then self.updater:Stop() @@ -66,7 +70,7 @@ local function Timer_SetNextUpdate(self, nextUpdate) end --stops the timer -local function Timer_Stop(self) +function Timer.Stop(self) self.enabled = nil if self.updater:IsPlaying() then self.updater:Stop() @@ -74,31 +78,31 @@ local function Timer_Stop(self) self:Hide() end -local function Timer_UpdateText(self) +function Timer.UpdateText(self) local remain = self.duration - (GetTime() - self.start) if round(remain) > 0 then if (self.fontScale * self:GetEffectiveScale() / UIParent:GetScale()) < MIN_SCALE then self.text:SetText('') - Timer_SetNextUpdate(self, 1) + Timer.SetNextUpdate(self, 1) else local formatStr, time, nextUpdate = getTimeText(remain) self.text:SetFormattedText(formatStr, time) - Timer_SetNextUpdate(self, nextUpdate) + Timer.SetNextUpdate(self, nextUpdate) end else - Timer_Stop(self) + Timer.Stop(self) end end --forces the given timer to update on the next frame -local function Timer_ForceUpdate(self) - Timer_UpdateText(self) +function Timer.ForceUpdate(self) + Timer.UpdateText(self) self:Show() end --adjust font size whenever the timer's parent size changes --hide if it gets too tiny -local function Timer_OnSizeChanged(self, width, height) +function Timer.OnSizeChanged(self, width, height) local fontScale = round(width) / ICON_SIZE if fontScale == self.fontScale then return @@ -112,13 +116,13 @@ local function Timer_OnSizeChanged(self, width, height) self.text:SetShadowColor(0, 0, 0, 0.8) self.text:SetShadowOffset(1, -1) if self.enabled then - Timer_ForceUpdate(self) + Timer.ForceUpdate(self) end end end --returns a new timer object -local function Timer_Create(cd) +function Timer.Create(cd) --a frame to watch for OnSizeChanged events --needed since OnSizeChanged has funny triggering if the frame with the handler is not shown local scaler = CreateFrame('Frame', nil, cd) @@ -129,7 +133,7 @@ local function Timer_Create(cd) local updater = timer:CreateAnimationGroup() updater:SetLooping('NONE') - updater:SetScript('OnFinished', function(self) Timer_UpdateText(timer) end) + updater:SetScript('OnFinished', function(self) Timer.UpdateText(timer) end) local a = updater:CreateAnimation('Animation'); a:SetOrder(1) timer.updater = updater @@ -139,30 +143,32 @@ local function Timer_Create(cd) text:SetFont(FONT_FACE, FONT_SIZE, 'OUTLINE') timer.text = text - Timer_OnSizeChanged(timer, scaler:GetSize()) - scaler:SetScript('OnSizeChanged', function(self, ...) Timer_OnSizeChanged(timer, ...) end) + Timer.OnSizeChanged(timer, scaler:GetSize()) + scaler:SetScript('OnSizeChanged', function(self, ...) Timer.OnSizeChanged(timer, ...) end) cd.timer = timer return timer end ---hook the SetCooldown method of all cooldown frames ---ActionButton1Cooldown is used here since its likely to always exist ---and I'd rather not create my own cooldown frame to preserve a tiny bit of memory -hooksecurefunc(getmetatable(ActionButton1Cooldown).__index, 'SetCooldown', function(cd, start, duration) +function Timer.Start(cd, start, duration) --start timer if start > 0 and duration > MIN_DURATION and (not cd.noCooldownCount) then - local timer = cd.timer or Timer_Create(cd) + local timer = cd.timer or Timer.Create(cd) timer.start = start timer.duration = duration timer.enabled = true - Timer_UpdateText(timer) + Timer.UpdateText(timer) if timer.fontScale >= MIN_SCALE then timer:Show() end --stop timer else local timer = cd.timer if timer then - Timer_Stop(timer) + Timer.Stop(timer) end end -end) \ No newline at end of file +end + +--hook the SetCooldown method of all cooldown frames +--ActionButton1Cooldown is used here since its likely to always exist +--and I'd rather not create my own cooldown frame to preserve a tiny bit of memory +hooksecurefunc(getmetatable(ActionButton1Cooldown).__index, 'SetCooldown', Timer.Start) \ No newline at end of file diff --git a/compat43.lua b/compat43.lua new file mode 100644 index 0000000..ad92615 --- /dev/null +++ b/compat43.lua @@ -0,0 +1,70 @@ +--[[ + In WoW 4.3 and later, action buttons can completely bypass lua for updating cooldown timers + This set of code is there to check and force tullaCC to update timers on standard action buttons (henceforth defined as anything that reuses's blizzard's ActionButton.lua code +--]] + +local ActionBarButtonEventsFrame = _G['ActionBarButtonEventsFrame'] +if not ActionBarButtonEventsFrame then return end + +local AddonName, Addon = ... +local Timer = Addon.Timer + + +--[[ cooldown timer updating ]]-- + +local active = {} + +local function cooldown_OnShow(self) + active[self] = true +end + +local function cooldown_OnHide(self) + active[self] = nil +end + +--returns true if the cooldown timer should be updated and false otherwise +local function cooldown_ShouldUpdateTimer(self, start, duration) + local timer = self.timer + if not timer then + return true + end + return timer.start ~= start +end + +local function cooldown_Update(self) + local button = self:GetParent() + local start, duration, enable = GetActionCooldown(button.action) + + if cooldown_ShouldUpdateTimer(self, start, duration) then + Timer.Start(self, start, duration) + end +end + +local abEventWatcher = CreateFrame('Frame'); abEventWatcher:Hide() +abEventWatcher:SetScript('OnEvent', function(self, event) + for cooldown in pairs(active) do + cooldown_Update(cooldown) + end +end) +abEventWatcher:RegisterEvent('ACTIONBAR_UPDATE_COOLDOWN') + + +--[[ hook action button registration ]]-- + +local hooked = {} + +local function actionButton_Register(frame) + local cooldown = frame.cooldown + if not hooked[cooldown] then + cooldown:HookScript('OnShow', cooldown_OnShow) + cooldown:HookScript('OnHide', cooldown_OnHide) + hooked[cooldown] = true + end +end + +if ActionBarButtonEventsFrame.frames then + for i, frame in pairs(ActionBarButtonEventsFrame.frames) do + actionButton_Register(frame) + end +end +hooksecurefunc('ActionBarButtonEventsFrame_RegisterFrame', actionButton_Register) \ No newline at end of file diff --git a/config.lua b/config.lua index 47cf6b7..ddbc89a 100644 --- a/config.lua +++ b/config.lua @@ -2,8 +2,8 @@ Curation settings for tullaCC --]] - -local C = select(2, ...) --retrieve addon table +local AddonName, Addon = ... +local C = {}; Addon.Config = C --font settings C.fontFace = STANDARD_TEXT_FONT --what font to use diff --git a/tullaCC.toc b/tullaCC.toc index d4d2cd8..7ff679a 100644 --- a/tullaCC.toc +++ b/tullaCC.toc @@ -5,3 +5,4 @@ ## Version: 4.2.0 config.lua cc.lua +compat43.lua \ No newline at end of file -- 1.7.9.5