diff --git a/include/hyprutils/animation/AnimatedVariable.hpp b/include/hyprutils/animation/AnimatedVariable.hpp index cc56434..113793f 100644 --- a/include/hyprutils/animation/AnimatedVariable.hpp +++ b/include/hyprutils/animation/AnimatedVariable.hpp @@ -160,11 +160,11 @@ namespace Hyprutils { m_bIsBeingAnimated = false; - if (endCallback) - onAnimationEnd(); - if (forceDisconnect) disconnectFromActive(); + + if (endCallback) + onAnimationEnd(); } const VarType& value() const { diff --git a/src/animation/AnimatedVariable.cpp b/src/animation/AnimatedVariable.cpp index 69c66af..ad63a8b 100644 --- a/src/animation/AnimatedVariable.cpp +++ b/src/animation/AnimatedVariable.cpp @@ -13,8 +13,8 @@ void CBaseAnimatedVariable::create(CAnimationManager* pManager, int typeInfo, SP m_pSelf = pSelf; m_pAnimationManager = pManager; - m_pSignals = pManager->getSignals(); - m_bDummy = false; + m_pSignals = pManager->getSignals(); + m_bDummy = false; } void CBaseAnimatedVariable::connectToActive() { @@ -136,11 +136,12 @@ void CBaseAnimatedVariable::onAnimationEnd() { /* We do not call disconnectFromActive here. The animation manager will remove it on a call to tickDone. */ if (m_fEndCallback) { - /* loading m_bRemoveEndAfterRan before calling the callback allows the callback to delete this animation safely if it is false. */ - auto removeEndCallback = m_bRemoveEndAfterRan; - m_fEndCallback(m_pSelf); - if (removeEndCallback) - m_fEndCallback = nullptr; // reset + CallbackFun cb = nullptr; + m_fEndCallback.swap(cb); + + cb(m_pSelf); + if (!m_bRemoveEndAfterRan && /* callback did not set a new one by itself */ !m_fEndCallback) + m_fEndCallback = cb; // restore } } diff --git a/tests/animation.cpp b/tests/animation.cpp index 971afac..112f379 100644 --- a/tests/animation.cpp +++ b/tests/animation.cpp @@ -344,6 +344,23 @@ int main(int argc, char** argv, char** envp) { EXPECT(s.m_iA->getCurveValue(), 1.f); EXPECT(endCallbackRan, 6); + // test end callback readding the var + *s.m_iA = 5; + s.m_iA->setCallbackOnEnd([&endCallbackRan](WP v) { + endCallbackRan++; + const auto PAV = dynamic_cast*>(v.lock().get()); + + *PAV = 10; + PAV->setCallbackOnEnd([&endCallbackRan](WP v) { endCallbackRan++; }); + }); + + while (pAnimationManager->shouldTickForNext()) { + pAnimationManager->tick(); + } + + EXPECT(endCallbackRan, 8); + EXPECT(s.m_iA->value(), 10); + // Test duplicate active anim vars are not allowed { EXPECT(pAnimationManager->m_vActiveAnimatedVariables.size(), 0);