Refactor progress handling

probably some regressions
This commit is contained in:
NoM0Re
2025-01-22 03:37:10 +01:00
parent a643b275ba
commit 23c7da5ea6
29 changed files with 2037 additions and 1263 deletions
+174 -160
View File
@@ -11,10 +11,175 @@ local function noopErrorHandler() end
local frame = Private.frames["WeakAuras Main Frame"]
local function RunAnimation(key, anim, elapsed, time)
Private.StartProfileUID(anim.auraUID)
local finished = false
if(anim.duration_type == "seconds") then
if anim.duration > 0 then
anim.progress = anim.progress + (elapsed / anim.duration)
else
anim.progress = anim.progress + (elapsed / 1)
end
if(anim.progress >= 1) then
anim.progress = 1
finished = true
end
elseif(anim.duration_type == "relative") then
local region = anim.region
if ((region.progressType == "timed" and region.duration < 0.01)
or (region.progressType == "static" and region.value < 0.01))
then
anim.progress = 0
if(anim.type == "start" or anim.type == "finish") then
finished = true
end
else
local relativeProgress = 0
if(region.progressType == "static") then
relativeProgress = region.value / region.total
elseif (region.progressType == "timed") then
relativeProgress = 1 - ((region.expirationTime - time) / region.duration)
end
relativeProgress = region.inverse and (1 - relativeProgress) or relativeProgress
anim.progress = anim.duration > 0 and relativeProgress / anim.duration or 0
local iteration = math.floor(anim.progress)
--anim.progress = anim.progress - iteration
if not(anim.iteration) then
anim.iteration = iteration
elseif(anim.iteration ~= iteration) then
anim.iteration = nil
finished = true
end
end
else
anim.progress = 1
end
local progress = anim.inverse and (1 - anim.progress) or anim.progress
progress = anim.easeFunc(progress, anim.easeStrength or 3)
Private.ActivateAuraEnvironmentForRegion(anim.region)
if(anim.translateFunc) then
local errorHandler = WeakAuras.IsOptionsOpen() and noopErrorHandler or Private.GetErrorHandlerUid(anim.auraUID, L["Slide Animation"])
if (anim.region.SetOffsetAnim) then
local ok, x, y = pcall(anim.translateFunc, progress, 0, 0, anim.dX, anim.dY)
if not ok then
errorHandler()
else
anim.region:SetOffsetAnim(x, y)
end
else
anim.region:ClearAllPoints()
local ok, x, y = pcall(anim.translateFunc, progress, anim.startX, anim.startY, anim.dX, anim.dY)
if not ok then
errorHandler()
else
anim.region:SetPoint(anim.selfPoint, anim.anchor, anim.anchorPoint, x, y)
end
end
end
if(anim.alphaFunc) then
local errorHandler = WeakAuras.IsOptionsOpen() and noopErrorHandler or Private.GetErrorHandlerUid(anim.auraUID, L["Fade Animation"])
local ok, alpha = pcall(anim.alphaFunc, progress, anim.startAlpha, anim.dAlpha)
if not ok then
errorHandler()
else
if (anim.region.SetAnimAlpha) then
anim.region:SetAnimAlpha(alpha)
else
anim.region:SetAlpha(alpha)
end
end
end
if(anim.scaleFunc) then
local errorHandler = WeakAuras.IsOptionsOpen() and noopErrorHandler
or Private.GetErrorHandlerUid(anim.auraUID, L["Zoom Animation"])
local ok, scaleX, scaleY = pcall(anim.scaleFunc, progress, 1, 1, anim.scaleX, anim.scaleY)
if not ok then
errorHandler()
else
if(anim.region.Scale) then
anim.region:Scale(scaleX, scaleY)
else
anim.region:SetWidth(anim.startWidth * scaleX)
anim.region:SetHeight(anim.startHeight * scaleY)
end
end
end
if(anim.rotateFunc and anim.region.Rotate) then
local errorHandler = WeakAuras.IsOptionsOpen() and noopErrorHandler
or Private.GetErrorHandlerUid(anim.auraUID, L["Rotate Animation"])
local ok, rotate = pcall(anim.rotateFunc, anim.rotateFunc, progress, anim.startRotation, anim.rotate)
if not ok then
errorHandler()
else
anim.region:Rotate(rotate)
end
end
if(anim.colorFunc and anim.region.ColorAnim) then
local errorHandler = WeakAuras.IsOptionsOpen() and noopErrorHandler
or Private.GetErrorHandlerUid(anim.auraUID, L["Color Animation"])
local startR, startG, startB, startA = anim.region:GetColor()
startR, startG, startB, startA = startR or 1, startG or 1, startB or 1, startA or 1
local ok, r, g, b, a = pcall(anim.colorFunc, progress, startR, startG, startB, startA,
anim.colorR, anim.colorG, anim.colorB, anim.colorA)
if not ok then
errorHandler()
else
local errorHandler = Private.GetErrorHandlerId(anim.region.id, "Custom Color")
local success = pcall(anim.region.ColorAnim, anim.region, r, g, b, a)
if not success then
errorHandler()
end
end
end
Private.ActivateAuraEnvironment(nil)
if(finished) then
if not(anim.loop) then
if (anim.region.SetOffsetAnim) then
anim.region:SetOffsetAnim(0, 0)
else
if(anim.startX) then
anim.region:SetPoint(anim.selfPoint, anim.anchor, anim.anchorPoint, anim.startX, anim.startY)
end
end
if (anim.region.SetAnimAlpha) then
anim.region:SetAnimAlpha(nil)
elseif(anim.startAlpha) then
anim.region:SetAlpha(anim.startAlpha)
end
if(anim.startWidth) then
if(anim.region.Scale) then
anim.region:Scale(1, 1)
else
anim.region:SetWidth(anim.startWidth)
anim.region:SetHeight(anim.startHeight)
end
end
if(anim.startRotation) then
if(anim.region.Rotate) then
anim.region:Rotate(anim.startRotation);
end
end
if(anim.region.ColorAnim) then
anim.region:ColorAnim(nil)
end
animations[key] = nil
end
if(anim.loop) then
Private.Animate(anim.namespace, anim.auraUID, anim.type, anim.anim, anim.region, anim.inverse, anim.onFinished,
anim.loop, anim.region.cloneId)
elseif(anim.onFinished) then
anim.onFinished()
end
end
Private.StopProfileUID(anim.auraUID)
end
local updatingAnimations;
local last_update = GetTime();
local function UpdateAnimations()
Private.StartProfileSystem("animations");
for groupUid, groupRegion in pairs(pending_controls) do
pending_controls[groupUid] = nil;
groupRegion:DoPositionChildren();
@@ -23,164 +188,9 @@ local function UpdateAnimations()
local time = GetTime();
local elapsed = time - last_update;
last_update = time;
local num = 0;
for key, anim in pairs(animations) do
Private.StartProfileUID(anim.auraUID);
num = num + 1;
local finished = false;
if(anim.duration_type == "seconds") then
if anim.duration > 0 then
anim.progress = anim.progress + (elapsed / anim.duration);
else
anim.progress = anim.progress + (elapsed / 1);
end
if(anim.progress >= 1) then
anim.progress = 1;
finished = true;
end
elseif(anim.duration_type == "relative") then
local state = anim.region.state;
if (not state
or (state.progressType == "timed" and state.duration < 0.01)
or (state.progressType == "static" and state.value < 0.01)) then
anim.progress = 0;
if(anim.type == "start" or anim.type == "finish") then
finished = true;
end
else
local relativeProgress = 0;
if(state.progressType == "static") then
relativeProgress = state.value / state.total;
elseif (state.progressType == "timed") then
relativeProgress = 1 - ((state.expirationTime - time) / state.duration);
end
relativeProgress = state.inverse and (1 - relativeProgress) or relativeProgress;
anim.progress = anim.duration > 0 and relativeProgress / anim.duration or 0
local iteration = math.floor(anim.progress);
--anim.progress = anim.progress - iteration;
if not(anim.iteration) then
anim.iteration = iteration;
elseif(anim.iteration ~= iteration) then
anim.iteration = nil;
finished = true;
end
end
else
anim.progress = 1;
end
local progress = anim.inverse and (1 - anim.progress) or anim.progress;
progress = anim.easeFunc(progress, anim.easeStrength or 3)
Private.ActivateAuraEnvironmentForRegion(anim.region)
if(anim.translateFunc) then
local errorHandler = WeakAuras.IsOptionsOpen() and noopErrorHandler or Private.GetErrorHandlerUid(anim.auraUID, L["Slide Animation"])
if (anim.region.SetOffsetAnim) then
local ok, x, y = pcall(anim.translateFunc, progress, 0, 0, anim.dX, anim.dY);
if not ok then
errorHandler(x)
else
anim.region:SetOffsetAnim(x, y);
end
else
anim.region:ClearAllPoints();
local ok, x, y = pcall(anim.translateFunc, progress, anim.startX, anim.startY, anim.dX, anim.dY);
if not ok then
errorHandler(x)
else
anim.region:SetPoint(anim.selfPoint, anim.anchor, anim.anchorPoint, x, y);
end
end
end
if(anim.alphaFunc) then
local errorHandler = WeakAuras.IsOptionsOpen() and noopErrorHandler or Private.GetErrorHandlerUid(anim.auraUID, L["Fade Animation"])
local ok, alpha = pcall(anim.alphaFunc, progress, anim.startAlpha, anim.dAlpha);
if not ok then
errorHandler(alpha)
else
if (anim.region.SetAnimAlpha) then
anim.region:SetAnimAlpha(alpha);
else
anim.region:SetAlpha(alpha);
end
end
end
if(anim.scaleFunc) then
local errorHandler = WeakAuras.IsOptionsOpen() and noopErrorHandler or Private.GetErrorHandlerUid(anim.auraUID, L["Zoom Animation"])
local ok, scaleX, scaleY = pcall(anim.scaleFunc, progress, 1, 1, anim.scaleX, anim.scaleY);
if not ok then
errorHandler(scaleX)
else
if(anim.region.Scale) then
anim.region:Scale(scaleX, scaleY);
else
anim.region:SetWidth(anim.startWidth * scaleX);
anim.region:SetHeight(anim.startHeight * scaleY);
end
end
end
if(anim.rotateFunc and anim.region.Rotate) then
local errorHandler = WeakAuras.IsOptionsOpen() and noopErrorHandler or Private.GetErrorHandlerUid(anim.auraUID, L["Rotate Animation"])
local ok, rotate = pcall(anim.rotateFunc, progress, anim.startRotation, anim.rotate);
if not ok then
errorHandler(rotate)
else
anim.region:Rotate(rotate);
end
end
if(anim.colorFunc and anim.region.ColorAnim) then
local errorHandler = WeakAuras.IsOptionsOpen() and noopErrorHandler or Private.GetErrorHandlerUid(anim.auraUID, L["Color Animation"])
local startR, startG, startB, startA = anim.region:GetColor();
startR, startG, startB, startA = startR or 1, startG or 1, startB or 1, startA or 1;
local ok, r, g, b, a = pcall(anim.colorFunc, progress, startR, startG, startB, startA, anim.colorR, anim.colorG, anim.colorB, anim.colorA);
if not ok then
errorHandler(r)
else
local success = pcall(anim.region.ColorAnim, errorHandler, anim.region, r, g, b, a)
if not success then
Private.GetErrorHandlerId(anim.region.id, "Custom Color")
end
end
end
Private.ActivateAuraEnvironment(nil);
if(finished) then
if not(anim.loop) then
if (anim.region.SetOffsetAnim) then
anim.region:SetOffsetAnim(0, 0);
else
if(anim.startX) then
anim.region:SetPoint(anim.selfPoint, anim.anchor, anim.anchorPoint, anim.startX, anim.startY);
end
end
if (anim.region.SetAnimAlpha) then
anim.region:SetAnimAlpha(nil);
elseif(anim.startAlpha) then
anim.region:SetAlpha(anim.startAlpha);
end
if(anim.startWidth) then
if(anim.region.Scale) then
anim.region:Scale(1, 1);
else
anim.region:SetWidth(anim.startWidth);
anim.region:SetHeight(anim.startHeight);
end
end
if(anim.startRotation) then
if(anim.region.Rotate) then
anim.region:Rotate(anim.startRotation);
end
end
if(anim.region.ColorAnim) then
anim.region:ColorAnim(nil);
end
animations[key] = nil;
end
if(anim.loop) then
Private.Animate(anim.namespace, anim.auraUID, anim.type, anim.anim, anim.region, anim.inverse, anim.onFinished, anim.loop, anim.region.cloneId);
elseif(anim.onFinished) then
anim.onFinished();
end
end
Private.StopProfileUID(anim.auraUID);
for key, anim in pairs(animations) do
RunAnimation(key, anim, elapsed, time)
end
Private.StopProfileSystem("animations");
@@ -188,12 +198,14 @@ end
function Private.RegisterGroupForPositioning(uid, region)
pending_controls[uid] = region
updatingAnimations = true
frame:SetScript("OnUpdate", UpdateAnimations)
if not updatingAnimations then
updatingAnimations = true
last_update = GetTime()
frame:SetScript("OnUpdate", UpdateAnimations)
end
end
function Private.Animate(namespace, uid, type, anim, region, inverse, onFinished, loop, cloneId)
local auraDisplayName = Private.UIDtoID(uid)
local key = tostring(region);
local valid;
if(anim and anim.type == "custom" and (anim.use_translate or anim.use_alpha or (anim.use_scale and region.Scale) or (anim.use_rotate and region.Rotate) or (anim.use_color and region.Color))) then
@@ -388,8 +400,10 @@ function Private.Animate(namespace, uid, type, anim, region, inverse, onFinished
if not(updatingAnimations) then
frame:SetScript("OnUpdate", UpdateAnimations);
last_update = GetTime()
updatingAnimations = true;
end
RunAnimation(key, animation, 0, GetTime())
return true;
else
if(animations[key]) then