Quantcast

added fixes for timers in WoW 4.3

Tuller [11-06-11 - 17:12]
added fixes for timers in WoW 4.3
Filename
cc.lua
compat43.lua
config.lua
tullaCC.toc
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