abandon C_Timer

This commit is contained in:
Bunny67
2020-06-29 18:45:14 +03:00
parent 9a42c57421
commit 7e15296d21
5 changed files with 106 additions and 230 deletions
+1 -5
View File
@@ -28,12 +28,8 @@ WeakAuras.prettyPrint = function(msg)
print(WeakAuras.printPrefix .. msg) print(WeakAuras.printPrefix .. msg)
end end
WeakAuras.versionMismatchPrint = function()
WeakAuras.prettyPrint("You need to restart your game client to complete the WeakAuras update!")
end
if versionString ~= versionStringFromToc and versionStringFromToc ~= "Dev" then if versionString ~= versionStringFromToc and versionStringFromToc ~= "Dev" then
C_Timer.After(1, WeakAuras.versionMismatchPrint) WeakAuras.prettyPrint("You need to restart your game client to complete the WeakAuras update!")
end end
WeakAuras.PowerAurasPath = "Interface\\Addons\\WeakAuras\\PowerAurasMedia\\Auras\\" WeakAuras.PowerAurasPath = "Interface\\Addons\\WeakAuras\\PowerAurasMedia\\Auras\\"
+90 -34
View File
@@ -2,8 +2,7 @@
-- AceTimer supports one-shot timers and repeating timers. All timers are stored in an efficient -- AceTimer supports one-shot timers and repeating timers. All timers are stored in an efficient
-- data structure that allows easy dispatching and fast rescheduling. Timers can be registered -- data structure that allows easy dispatching and fast rescheduling. Timers can be registered
-- or canceled at any time, even from within a running timer, without conflict or large overhead.\\ -- or canceled at any time, even from within a running timer, without conflict or large overhead.\\
-- AceTimer is currently limited to firing timers at a frequency of 0.01s as this is what the WoW timer API -- AceTimer is currently limited to firing timers at a frequency of 0.01s.
-- restricts us to.
-- --
-- All `:Schedule` functions will return a handle to the current timer, which you will need to store if you -- All `:Schedule` functions will return a handle to the current timer, which you will need to store if you
-- need to cancel the timer you just registered. -- need to cancel the timer you just registered.
@@ -15,23 +14,69 @@
-- make into AceTimer. -- make into AceTimer.
-- @class file -- @class file
-- @name AceTimer-3.0 -- @name AceTimer-3.0
-- @release $Id: AceTimer-3.0.lua 1202 2019-05-15 23:11:22Z nevcairiel $ -- @release $Id$
local MAJOR, MINOR = "AceTimer-3.0", 17 -- Bump minor on changes local MAJOR, MINOR = "AceTimer-3.0", 117 -- Bump minor on changes
local AceTimer, oldminor = LibStub:NewLibrary(MAJOR, MINOR) local AceTimer, oldminor = LibStub:NewLibrary(MAJOR, MINOR)
if not AceTimer then return end -- No upgrade needed if not AceTimer then return end -- No upgrade needed
AceTimer.frame = AceTimer.frame or CreateFrame("Frame", "AceTimer30Frame")
AceTimer.activeTimers = AceTimer.activeTimers or {} -- Active timer list AceTimer.activeTimers = AceTimer.activeTimers or {} -- Active timer list
local activeTimers = AceTimer.activeTimers -- Upvalue our private data local activeTimers = AceTimer.activeTimers -- Upvalue our private data
-- Lua APIs -- Lua APIs
local assert, loadstring, rawset, tconcat = assert, loadstring, rawset, table.concat
local type, unpack, next, error, select = type, unpack, next, error, select local type, unpack, next, error, select = type, unpack, next, error, select
-- WoW APIs -- WoW APIs
local GetTime, C_TimerAfter = GetTime, C_Timer.After local GetTime = GetTime
--[[
xpcall safecall implementation
]]
local xpcall = xpcall
local function errorhandler(err)
return geterrorhandler()(err)
end
local function CreateDispatcher(argCount)
local code = [[
local xpcall, eh = ...
local method, ARGS
local function call() return method(ARGS) end
local function dispatch(func, ...)
method = func
if not method then return end
ARGS = ...
return xpcall(call, eh)
end
return dispatch
]]
local ARGS = {}
for i = 1, argCount do ARGS[i] = "arg"..i end
code = code:gsub("ARGS", tconcat(ARGS, ", "))
return assert(loadstring(code, "safecall Dispatcher["..argCount.."]"))(xpcall, errorhandler)
end
local Dispatchers = setmetatable({}, {__index=function(self, argCount)
local dispatcher = CreateDispatcher(argCount)
rawset(self, argCount, dispatcher)
return dispatcher
end})
Dispatchers[0] = function(func)
return xpcall(func, errorhandler)
end
local function safecall(func, ...)
return Dispatchers[select("#", ...)](func, ...)
end
local function new(self, loop, func, delay, ...) local function new(self, loop, func, delay, ...)
if delay < 0.01 then if delay < 0.01 then
delay = 0.01 -- Restrict to the lowest time that the C_Timer API allows us delay = 0.01 -- Restrict to the lowest time
end end
local timer = { local timer = {
@@ -40,39 +85,13 @@ local function new(self, loop, func, delay, ...)
looping = loop, looping = loop,
argsCount = select("#", ...), argsCount = select("#", ...),
delay = delay, delay = delay,
timeleft = delay,
ends = GetTime() + delay, ends = GetTime() + delay,
... ...
} }
activeTimers[timer] = timer activeTimers[timer] = timer
-- Create new timer closure to wrap the "timer" object
timer.callback = function()
if not timer.cancelled then
if type(timer.func) == "string" then
-- We manually set the unpack count to prevent issues with an arg set that contains nil and ends with nil
-- e.g. local t = {1, 2, nil, 3, nil} print(#t) will result in 2, instead of 5. This fixes said issue.
timer.object[timer.func](timer.object, unpack(timer, 1, timer.argsCount))
else
timer.func(unpack(timer, 1, timer.argsCount))
end
if timer.looping and not timer.cancelled then
-- Compensate delay to get a perfect average delay, even if individual times don't match up perfectly
-- due to fps differences
local time = GetTime()
local delay = timer.delay - (time - timer.ends)
-- Ensure the delay doesn't go below the threshold
if delay < 0.01 then delay = 0.01 end
C_TimerAfter(delay, timer.callback)
timer.ends = time + delay
else
activeTimers[timer.handle or timer] = nil
end
end
end
C_TimerAfter(delay, timer.callback)
return timer return timer
end end
@@ -211,7 +230,6 @@ if oldminor and oldminor < 10 then
elseif oldminor and oldminor < 17 then elseif oldminor and oldminor < 17 then
-- Upgrade from old animation based timers to C_Timer.After timers. -- Upgrade from old animation based timers to C_Timer.After timers.
AceTimer.inactiveTimers = nil AceTimer.inactiveTimers = nil
AceTimer.frame = nil
local oldTimers = AceTimer.activeTimers local oldTimers = AceTimer.activeTimers
-- Clear old timer table and update upvalue -- Clear old timer table and update upvalue
AceTimer.activeTimers = {} AceTimer.activeTimers = {}
@@ -276,3 +294,41 @@ end
for addon in next, AceTimer.embeds do for addon in next, AceTimer.embeds do
AceTimer:Embed(addon) AceTimer:Embed(addon)
end end
AceTimer.frame:SetScript("OnUpdate", function(self, elapsed)
-- local total = 0
for _, timer in next, activeTimers do
-- print(timer.timeleft, timer.object.name)
if not timer.cancelled then
if timer.timeleft > elapsed then
timer.timeleft = timer.timeleft - elapsed
else
if type(timer.func) == "string" then
-- We manually set the unpack count to prevent issues with an arg set that contains nil and ends with nil
-- e.g. local t = {1, 2, nil, 3, nil} print(#t) will result in 2, instead of 5. This fixes said issue.
safecall(timer.object[timer.func], timer.object, unpack(timer, 1, timer.argsCount))
else
safecall(timer.func, unpack(timer, 1, timer.argsCount))
end
if timer.looping and not timer.cancelled then
-- Compensate delay to get a perfect average delay, even if individual times don't match up perfectly
-- due to fps differences
local time = GetTime()
local delay = timer.delay - (time - timer.ends)
-- Ensure the delay doesn't go below the threshold
if delay < 0.01 then delay = 0.01 end
timer.ends = time + delay
timer.timeleft = timer.delay
else
activeTimers[timer.handle or timer] = nil
end
end
end
end
-- if total == 0 then
-- self:Hide()
-- end
end)
@@ -7,7 +7,7 @@ if not lib then return end
lib.callbacks = lib.callbacks or LibStub("CallbackHandler-1.0"):New(lib) lib.callbacks = lib.callbacks or LibStub("CallbackHandler-1.0"):New(lib)
local callbacks = lib.callbacks local callbacks = lib.callbacks
local GetPlayerInfoByGUID, UnitExists, IsAddOnLoaded, C_Timer, UnitIsUnit, SecureButton_GetUnit = GetPlayerInfoByGUID, UnitExists, IsAddOnLoaded, C_Timer, UnitIsUnit, SecureButton_GetUnit local GetPlayerInfoByGUID, UnitExists, IsAddOnLoaded, UnitIsUnit, SecureButton_GetUnit = GetPlayerInfoByGUID, UnitExists, IsAddOnLoaded, UnitIsUnit, SecureButton_GetUnit
local tinsert, CopyTable, wipe = tinsert, CopyTable, wipe local tinsert, CopyTable, wipe = tinsert, CopyTable, wipe
local maxDepth = 50 local maxDepth = 50
@@ -118,14 +118,23 @@ local function doScanForUnitFrames()
end end
end end
end end
local waitFrame = CreateFrame("Frame")
local function waitFrame_OnUpdate(self, elapsed)
self.delay = (self.delay or 1) - elapsed
if self.delay < elapsed then
doScanForUnitFrames()
self:SetScript("OnUpdate", nil)
self.delay = nil
end
end
local function ScanForUnitFrames(noDelay) local function ScanForUnitFrames(noDelay)
if noDelay then if noDelay then
doScanForUnitFrames() doScanForUnitFrames()
elseif not wait then elseif not wait then
wait = true wait = true
C_Timer.After(1, function() waitFrame:SetScript("OnUpdate", waitFrame_OnUpdate)
doScanForUnitFrames()
end)
end end
end end
-185
View File
@@ -30,32 +30,6 @@ function CreateFromMixins(...)
return Mixin({}, ...) return Mixin({}, ...)
end end
function Lerp(startValue, endValue, amount)
return (1 - amount) * startValue + amount * endValue
end
function Clamp(value, min, max)
if value > max then
return max
elseif value < min then
return min
end
return value
end
function Saturate(value)
return Clamp(value, 0.0, 1.0)
end
local TARGET_FRAME_PER_SEC = 60.0;
function DeltaLerp(startValue, endValue, amount, timeSec)
return Lerp(startValue, endValue, Saturate(amount * timeSec * TARGET_FRAME_PER_SEC));
end
function FrameDeltaLerp(startValue, endValue, amount, tickTime)
return DeltaLerp(startValue, endValue, amount, tickTime)
end
function Round(value) function Round(value)
if value < 0 then if value < 0 then
return ceil(value - .5); return ceil(value - .5);
@@ -71,69 +45,6 @@ function tIndexOf(tbl, item)
end end
end end
local g_updatingBars = {};
local function IsCloseEnough(bar, newValue, targetValue)
local min, max = bar:GetMinMaxValues();
local range = max - min
if range > 0.0 then
return math.abs((newValue - targetValue) / range) < .00001
end
return true;
end
do
local f = CreateFrame("Frame")
f:Show()
f:SetScript("OnUpdate", function(_, elapsed)
for bar, targetValue in pairs(g_updatingBars) do
local effectiveTargetValue = Clamp(targetValue, bar:GetMinMaxValues())
local newValue = FrameDeltaLerp(bar:GetValue(), effectiveTargetValue, .25, elapsed)
if IsCloseEnough(bar, newValue, effectiveTargetValue) then
g_updatingBars[bar] = nil
bar:SetValue(effectiveTargetValue)
else
bar:SetValue(newValue)
end
end
end)
end
SmoothStatusBarMixin = {}
function SmoothStatusBarMixin:ResetSmoothedValue(value)
local targetValue = g_updatingBars[self]
if targetValue then
g_updatingBars[self] = nil
self:SetValue(value or targetValue)
elseif value then
self:SetValue(value)
end
end
function SmoothStatusBarMixin:SetSmoothedValue(value)
g_updatingBars[self] = value
end
function SmoothStatusBarMixin:SetMinMaxSmoothedValue(min, max)
self:SetMinMaxValues(min, max)
local targetValue = g_updatingBars[self]
if targetValue then
local ratio = 1
if max ~= 0 and self.lastSmoothedMax and self.lastSmoothedMax ~= 0 then
ratio = max / self.lastSmoothedMax
end
g_updatingBars[self] = targetValue * ratio
end
self.lastSmoothedMin = min
self.lastSmoothedMax = max
end
local oldGetInstanceDifficulty = GetInstanceDifficulty local oldGetInstanceDifficulty = GetInstanceDifficulty
function GetInstanceDifficulty() function GetInstanceDifficulty()
local diff = oldGetInstanceDifficulty() local diff = oldGetInstanceDifficulty()
@@ -162,102 +73,6 @@ function GetNumGroupMembers()
return GetNumRaidMembers() return GetNumRaidMembers()
end end
if not C_Timer or C_Timer._version ~= 2 then
local setmetatable = setmetatable
local type = type
local tinsert = table.insert
local tremove = table.remove
C_Timer = C_Timer or {}
C_Timer._version = 2
local TickerPrototype = {}
local TickerMetatable = {
__index = TickerPrototype,
__metatable = true
}
local waitTable = {}
local waitFrame = TimerFrame or CreateFrame("Frame", "TimerFrame", UIParent)
waitFrame:SetScript("OnUpdate", function(self, elapsed)
local total = #waitTable
local i = 1
while i <= total do
local ticker = waitTable[i]
if ticker._cancelled then
tremove(waitTable, i)
total = total - 1
elseif ticker._delay > elapsed then
ticker._delay = ticker._delay - elapsed
i = i + 1
else
ticker._callback(ticker)
if ticker._remainingIterations == -1 then
ticker._delay = ticker._duration
i = i + 1
elseif ticker._remainingIterations > 1 then
ticker._remainingIterations = ticker._remainingIterations - 1
ticker._delay = ticker._duration
i = i + 1
elseif ticker._remainingIterations == 1 then
tremove(waitTable, i)
total = total - 1
end
end
end
if #waitTable == 0 then
self:Hide()
end
end)
local function AddDelayedCall(ticker, oldTicker)
if oldTicker and type(oldTicker) == "table" then
ticker = oldTicker
end
tinsert(waitTable, ticker)
waitFrame:Show()
end
_G.AddDelayedCall = AddDelayedCall
local function CreateTicker(duration, callback, iterations)
local ticker = setmetatable({}, TickerMetatable)
ticker._remainingIterations = iterations or -1
ticker._duration = duration
ticker._delay = duration
ticker._callback = callback
AddDelayedCall(ticker)
return ticker
end
function C_Timer.After(duration, callback)
AddDelayedCall({
_remainingIterations = 1,
_delay = duration,
_callback = callback
})
end
function C_Timer.NewTimer(duration, callback)
return CreateTicker(duration, callback, 1)
end
function C_Timer.NewTicker(duration, callback, iterations)
return CreateTicker(duration, callback, iterations)
end
function TickerPrototype:Cancel()
self._cancelled = true
end
end
RAID_CLASS_COLORS.HUNTER.colorStr = "ffabd473" RAID_CLASS_COLORS.HUNTER.colorStr = "ffabd473"
RAID_CLASS_COLORS.WARLOCK.colorStr = "ff8788ee" RAID_CLASS_COLORS.WARLOCK.colorStr = "ff8788ee"
RAID_CLASS_COLORS.PRIEST.colorStr = "ffffffff" RAID_CLASS_COLORS.PRIEST.colorStr = "ffffffff"
+2 -2
View File
@@ -2785,9 +2785,9 @@ end
-- Thus Reload the options after a very small delay. -- Thus Reload the options after a very small delay.
function WeakAuras.ScheduleReloadOptions(data) function WeakAuras.ScheduleReloadOptions(data)
if (type(data.id) ~= "table") then if (type(data.id) ~= "table") then
C_Timer.After(0.1, function() WeakAuras.timer:ScheduleTimer(function()
WeakAuras.ReloadOptions(data.id) WeakAuras.ReloadOptions(data.id)
end ); end, 0.1);
end end
end end