From 1e0392e711192e2c1c2785f87a34ce0123b91b96 Mon Sep 17 00:00:00 2001 From: Maximilian Seidler Date: Sun, 26 Jan 2025 13:29:42 +0100 Subject: [PATCH] animation: forceDisconnect outside of tick() and remove the pointer to the animation manager --- .../hyprutils/animation/AnimatedVariable.hpp | 38 ++++++++++--------- .../hyprutils/animation/AnimationManager.hpp | 10 ++--- src/animation/AnimatedVariable.cpp | 22 ++++------- src/animation/AnimationManager.cpp | 12 ------ tests/animation.cpp | 32 +++++++++++++--- 5 files changed, 58 insertions(+), 56 deletions(-) diff --git a/include/hyprutils/animation/AnimatedVariable.hpp b/include/hyprutils/animation/AnimatedVariable.hpp index 81ffab4..af0c341 100644 --- a/include/hyprutils/animation/AnimatedVariable.hpp +++ b/include/hyprutils/animation/AnimatedVariable.hpp @@ -27,7 +27,7 @@ namespace Hyprutils { ; // m_bDummy = true; }; - void create(CAnimationManager*, int, Memory::CSharedPointer); + void create(int, Memory::CSharedPointer, Memory::CSharedPointer events); void connectToActive(); void disconnectFromActive(); @@ -36,7 +36,7 @@ namespace Hyprutils { disconnectFromActive(); }; - virtual void warp(bool endCallback = true) = 0; + virtual void warp(bool endCallback = true, bool forceDisconnect = true) = 0; CBaseAnimatedVariable(const CBaseAnimatedVariable&) = delete; CBaseAnimatedVariable(CBaseAnimatedVariable&&) = delete; @@ -58,8 +58,9 @@ namespace Hyprutils { /* returns the spent (completion) % */ float getPercent() const; - /* returns the current curve value */ - float getCurveValue() const; + /* returns the current curve value. + needs a reference to the animationmgr to get the bezier curve with the configured name from it */ + float getCurveValue(CAnimationManager*) const; /* checks if an animation is in progress */ bool isBeingAnimated() const { @@ -100,6 +101,8 @@ namespace Hyprutils { Memory::CWeakPointer m_pSelf; + Memory::CWeakPointer m_events; + private: Memory::CWeakPointer m_pConfig; @@ -107,18 +110,12 @@ namespace Hyprutils { bool m_bDummy = true; - // TODO: remove this pointer. We still need it for getBezier in getCurveValue. - // getCurveValue is only used once in Hyprland. So either remove it or just pass pAnimationManager as a param. - CAnimationManager* m_pAnimationManager = nullptr; - - Memory::CWeakPointer m_events; + bool m_bRemoveEndAfterRan = true; + bool m_bRemoveBeginAfterRan = true; - bool m_bRemoveEndAfterRan = true; - bool m_bRemoveBeginAfterRan = true; - - CallbackFun m_fEndCallback; - CallbackFun m_fBeginCallback; - CallbackFun m_fUpdateCallback; + CallbackFun m_fEndCallback; + CallbackFun m_fBeginCallback; + CallbackFun m_fUpdateCallback; }; /* This concept represents the minimum requirement for a type to be used with CGenericAnimatedVariable */ @@ -140,13 +137,13 @@ namespace Hyprutils { public: CGenericAnimatedVariable() = default; - void create(const int typeInfo, CAnimationManager* pAnimationManager, Memory::CSharedPointer> pSelf, + void create(const int typeInfo, Memory::CSharedPointer> pSelf, Memory::CSharedPointer events, const VarType& initialValue) { m_Begun = initialValue; m_Value = initialValue; m_Goal = initialValue; - CBaseAnimatedVariable::create(pAnimationManager, typeInfo, pSelf); + CBaseAnimatedVariable::create(typeInfo, pSelf, events); } CGenericAnimatedVariable(const CGenericAnimatedVariable&) = delete; @@ -154,7 +151,7 @@ namespace Hyprutils { CGenericAnimatedVariable& operator=(const CGenericAnimatedVariable&) = delete; CGenericAnimatedVariable& operator=(CGenericAnimatedVariable&&) = delete; - virtual void warp(bool endCallback = true) { + virtual void warp(bool endCallback = true, bool forceDisconnect = true) { if (!m_bIsBeingAnimated) return; @@ -166,6 +163,11 @@ namespace Hyprutils { if (endCallback) onAnimationEnd(); + + if (forceDisconnect) { + if (const auto PEVENTS = m_events.lock()) + PEVENTS->forceDisconnect.emit(static_cast(this)); + } } const VarType& value() const { diff --git a/include/hyprutils/animation/AnimationManager.hpp b/include/hyprutils/animation/AnimationManager.hpp index 3fdc798..b89b4d7 100644 --- a/include/hyprutils/animation/AnimationManager.hpp +++ b/include/hyprutils/animation/AnimationManager.hpp @@ -33,26 +33,24 @@ namespace Hyprutils { const std::unordered_map>& getAllBeziers(); + Memory::CSharedPointer getEvents() const; + std::vector> m_vActiveAnimatedVariables; + Memory::CSharedPointer m_events; private: std::unordered_map> m_mBezierCurves; - bool m_bTickScheduled = false; - uint32_t m_pendingDisconnects = 0; + bool m_bTickScheduled = false; void connectListener(std::any data); - void lazyDisconnectListener(std::any data); void forceDisconnectListener(std::any data); struct { Signal::CHyprSignalListener connect; Signal::CHyprSignalListener forceDisconnect; - Signal::CHyprSignalListener lazyDisconnect; } m_sListeners; - Memory::CSharedPointer m_events; - friend class CBaseAnimatedVariable; }; } diff --git a/src/animation/AnimatedVariable.cpp b/src/animation/AnimatedVariable.cpp index fb6b934..0aefd45 100644 --- a/src/animation/AnimatedVariable.cpp +++ b/src/animation/AnimatedVariable.cpp @@ -8,13 +8,11 @@ using namespace Hyprutils::Memory; #define SP CSharedPointer #define WP CWeakPointer -void CBaseAnimatedVariable::create(Hyprutils::Animation::CAnimationManager* pAnimationManager, int typeInfo, SP pSelf) { - m_pAnimationManager = pAnimationManager; - m_Type = typeInfo; - m_pSelf = pSelf; - - m_events = pAnimationManager->m_events; +void CBaseAnimatedVariable::create(int typeInfo, SP pSelf, SP events) { + m_Type = typeInfo; + m_pSelf = pSelf; + m_events = events; m_bDummy = false; } @@ -77,15 +75,9 @@ float CBaseAnimatedVariable::getPercent() const { return 1.f; } -float CBaseAnimatedVariable::getCurveValue() const { - if (!m_bIsBeingAnimated || !m_pAnimationManager) - return 1.f; - - // Guard against m_pAnimationManager being deleted - // TODO: Remove this and m_pAnimationManager - if (m_events.expired()) { +float CBaseAnimatedVariable::getCurveValue(CAnimationManager* pAnimationManager) const { + if (!m_bIsBeingAnimated || !pAnimationManager) return 1.f; - } std::string bezierName = ""; if (const auto PCONFIG = m_pConfig.lock()) { @@ -94,7 +86,7 @@ float CBaseAnimatedVariable::getCurveValue() const { bezierName = PVALUES->internalBezier; } - const auto BEZIER = m_pAnimationManager->getBezier(bezierName); + const auto BEZIER = pAnimationManager->getBezier(bezierName); if (!BEZIER) return 1.f; diff --git a/src/animation/AnimationManager.cpp b/src/animation/AnimationManager.cpp index e3c2c29..7e2fb44 100644 --- a/src/animation/AnimationManager.cpp +++ b/src/animation/AnimationManager.cpp @@ -18,7 +18,6 @@ CAnimationManager::CAnimationManager() { m_sListeners.connect = m_events->connect.registerListener([this](std::any data) { connectListener(data); }); m_sListeners.forceDisconnect = m_events->forceDisconnect.registerListener([this](std::any data) { forceDisconnectListener(data); }); - m_sListeners.lazyDisconnect = m_events->lazyDisconnect.registerListener([this](std::any data) { lazyDisconnectListener(data); }); } void CAnimationManager::connectListener(std::any data) { @@ -32,12 +31,6 @@ void CAnimationManager::connectListener(std::any data) { m_vActiveAnimatedVariables.emplace_back(PAV); } catch (const std::bad_any_cast&) { return; } - - // When the animation manager ticks, it will cleanup the active list. - // If for some reason we don't tick for a while, but vars get warped a lot, we could end up with a lot of pending disconnects. - // So we rorate here, since we don't want the vector to grow too big for no reason. - if (m_pendingDisconnects > 100) - rotateActive(); } void CAnimationManager::forceDisconnectListener(std::any data) { @@ -50,10 +43,6 @@ void CAnimationManager::forceDisconnectListener(std::any data) { } catch (const std::bad_any_cast&) { return; } } -void CAnimationManager::lazyDisconnectListener(std::any data) { - m_pendingDisconnects++; -} - void CAnimationManager::removeAllBeziers() { m_mBezierCurves.clear(); @@ -95,7 +84,6 @@ void CAnimationManager::rotateActive() { } m_vActiveAnimatedVariables = std::move(active); - m_pendingDisconnects = 0; } bool CAnimationManager::bezierExists(const std::string& bezier) { diff --git a/tests/animation.cpp b/tests/animation.cpp index e329024..bec7c47 100644 --- a/tests/animation.cpp +++ b/tests/animation.cpp @@ -54,7 +54,7 @@ class CMyAnimationManager : public CAnimationManager { const auto PBEZIER = getBezier(PAV->getBezierName()); if (SPENT >= 1.f || !PAV->enabled()) { - PAV->warp(); + PAV->warp(true, false); continue; } @@ -93,7 +93,7 @@ class CMyAnimationManager : public CAnimationManager { constexpr const eAVTypes EAVTYPE = std::is_same_v ? eAVTypes::INT : eAVTypes::TEST; const auto PAV = makeShared>(); - PAV->create(EAVTYPE, static_cast(this), PAV, v); + PAV->create(EAVTYPE, PAV, m_events, v); PAV->setConfig(animationTree.getConfig(animationConfigName)); av = std::move(PAV); } @@ -326,6 +326,24 @@ int main(int argc, char** argv, char** envp) { EXPECT(endCallbackRan, 4); EXPECT(s.m_iA->value(), 10); + // test warp + *s.m_iA = 3; + s.m_iA->setCallbackOnEnd([&endCallbackRan](auto) { endCallbackRan++; }, false); + + s.m_iA->warp(false); + EXPECT(endCallbackRan, 4); + + *s.m_iA = 4; + s.m_iA->warp(true); + EXPECT(endCallbackRan, 5); + + // test getCurveValue + *s.m_iA = 0; + EXPECT(s.m_iA->getCurveValue(pAnimationManager.get()), 0.f); + s.m_iA->warp(); + EXPECT(s.m_iA->getCurveValue(pAnimationManager.get()), 1.f); + EXPECT(endCallbackRan, 6); + // Test duplicate active anim vars are not allowed { EXPECT(pAnimationManager->m_vActiveAnimatedVariables.size(), 0); @@ -337,7 +355,6 @@ int main(int argc, char** argv, char** envp) { *a = 20; EXPECT(pAnimationManager->m_vActiveAnimatedVariables.size(), 1); a->warp(); - pAnimationManager->tick(); // trigger cleanup EXPECT(pAnimationManager->m_vActiveAnimatedVariables.size(), 0); EXPECT(a->value(), 20); } @@ -348,10 +365,15 @@ int main(int argc, char** argv, char** envp) { pAnimationManager->createAnimation(1, a, "default"); *a = 10; pAnimationManager.reset(); - } + a->setValueAndWarp(11); + EXPECT(a->value(), 11); + *a = 12; + a->warp(); + EXPECT(a->value(), 12); + *a = 13; + } // a gets destroyed EXPECT(pAnimationManager.get(), nullptr); - *s.m_iA = 10; return ret; }