diff --git a/WeakAuras/Init.lua b/WeakAuras/Init.lua index e4668af..53d240c 100644 --- a/WeakAuras/Init.lua +++ b/WeakAuras/Init.lua @@ -28,12 +28,8 @@ WeakAuras.prettyPrint = function(msg) print(WeakAuras.printPrefix .. msg) 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 - C_Timer.After(1, WeakAuras.versionMismatchPrint) + WeakAuras.prettyPrint("You need to restart your game client to complete the WeakAuras update!") end WeakAuras.PowerAurasPath = "Interface\\Addons\\WeakAuras\\PowerAurasMedia\\Auras\\" diff --git a/WeakAuras/Libs/AceTimer-3.0/AceTimer-3.0.lua b/WeakAuras/Libs/AceTimer-3.0/AceTimer-3.0.lua index 33b4da4..929f458 100644 --- a/WeakAuras/Libs/AceTimer-3.0/AceTimer-3.0.lua +++ b/WeakAuras/Libs/AceTimer-3.0/AceTimer-3.0.lua @@ -2,8 +2,7 @@ -- 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 -- 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 --- restricts us to. +-- AceTimer is currently limited to firing timers at a frequency of 0.01s. -- -- 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. @@ -15,23 +14,69 @@ -- make into AceTimer. -- @class file -- @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) 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 local activeTimers = AceTimer.activeTimers -- Upvalue our private data -- Lua APIs +local assert, loadstring, rawset, tconcat = assert, loadstring, rawset, table.concat local type, unpack, next, error, select = type, unpack, next, error, select -- 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, ...) 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 local timer = { @@ -40,39 +85,13 @@ local function new(self, loop, func, delay, ...) looping = loop, argsCount = select("#", ...), delay = delay, + timeleft = delay, ends = GetTime() + delay, ... } 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 end @@ -211,7 +230,6 @@ if oldminor and oldminor < 10 then elseif oldminor and oldminor < 17 then -- Upgrade from old animation based timers to C_Timer.After timers. AceTimer.inactiveTimers = nil - AceTimer.frame = nil local oldTimers = AceTimer.activeTimers -- Clear old timer table and update upvalue AceTimer.activeTimers = {} @@ -276,3 +294,41 @@ end for addon in next, AceTimer.embeds do AceTimer:Embed(addon) 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) \ No newline at end of file diff --git a/WeakAuras/Libs/LibGetFrame-1.0/LibGetFrame-1.0.lua b/WeakAuras/Libs/LibGetFrame-1.0/LibGetFrame-1.0.lua index d301811..7bd2674 100644 --- a/WeakAuras/Libs/LibGetFrame-1.0/LibGetFrame-1.0.lua +++ b/WeakAuras/Libs/LibGetFrame-1.0/LibGetFrame-1.0.lua @@ -7,7 +7,7 @@ if not lib then return end lib.callbacks = lib.callbacks or LibStub("CallbackHandler-1.0"):New(lib) 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 maxDepth = 50 @@ -118,14 +118,23 @@ local function doScanForUnitFrames() 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) if noDelay then doScanForUnitFrames() elseif not wait then wait = true - C_Timer.After(1, function() - doScanForUnitFrames() - end) + waitFrame:SetScript("OnUpdate", waitFrame_OnUpdate) end end diff --git a/WeakAuras/compat.lua b/WeakAuras/compat.lua index f7ac9be..5c621da 100644 --- a/WeakAuras/compat.lua +++ b/WeakAuras/compat.lua @@ -30,32 +30,6 @@ function CreateFromMixins(...) return Mixin({}, ...) 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) if value < 0 then return ceil(value - .5); @@ -71,69 +45,6 @@ function tIndexOf(tbl, item) 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 function GetInstanceDifficulty() local diff = oldGetInstanceDifficulty() @@ -162,102 +73,6 @@ function GetNumGroupMembers() return GetNumRaidMembers() 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.WARLOCK.colorStr = "ff8788ee" RAID_CLASS_COLORS.PRIEST.colorStr = "ffffffff" diff --git a/WeakAurasOptions/WeakAurasOptions.lua b/WeakAurasOptions/WeakAurasOptions.lua index 9684b99..88a3939 100644 --- a/WeakAurasOptions/WeakAurasOptions.lua +++ b/WeakAurasOptions/WeakAurasOptions.lua @@ -2785,9 +2785,9 @@ end -- Thus Reload the options after a very small delay. function WeakAuras.ScheduleReloadOptions(data) if (type(data.id) ~= "table") then - C_Timer.After(0.1, function() + WeakAuras.timer:ScheduleTimer(function() WeakAuras.ReloadOptions(data.id) - end ); + end, 0.1); end end