mirror of
https://github.com/hyprwm/hyprutils.git
synced 2025-05-13 05:40:40 +01:00
animation: better cleanup
This commit is contained in:
parent
77ddb222fc
commit
27d35e8d08
4 changed files with 43 additions and 16 deletions
|
@ -96,7 +96,8 @@ namespace Hyprutils {
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
Memory::CWeakPointer<Signal::CSignal> connect;
|
Memory::CWeakPointer<Signal::CSignal> connect;
|
||||||
Memory::CWeakPointer<Signal::CSignal> disconnect;
|
Memory::CWeakPointer<Signal::CSignal> forceDisconnect;
|
||||||
|
Memory::CWeakPointer<Signal::CSignal> lazyDisconnect;
|
||||||
} m_sEvents;
|
} m_sEvents;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
#include "../memory/WeakPtr.hpp"
|
#include "../memory/WeakPtr.hpp"
|
||||||
#include "../signal/Signal.hpp"
|
#include "../signal/Signal.hpp"
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
@ -18,13 +19,15 @@ namespace Hyprutils {
|
||||||
virtual ~CAnimationManager() = default;
|
virtual ~CAnimationManager() = default;
|
||||||
|
|
||||||
void tickDone();
|
void tickDone();
|
||||||
|
void rotateActive();
|
||||||
bool shouldTickForNext();
|
bool shouldTickForNext();
|
||||||
|
|
||||||
virtual void scheduleTick() = 0;
|
virtual void scheduleTick() = 0;
|
||||||
virtual void onTicked() = 0;
|
virtual void onTicked() = 0;
|
||||||
|
|
||||||
void connectVarListener(std::any data);
|
void connectListener(std::any data);
|
||||||
void disconnectVarListener(std::any data);
|
void lazyDisconnectListener(std::any data);
|
||||||
|
void forceDisconnectListener(std::any data);
|
||||||
|
|
||||||
void addBezierWithName(std::string, const Math::Vector2D&, const Math::Vector2D&);
|
void addBezierWithName(std::string, const Math::Vector2D&, const Math::Vector2D&);
|
||||||
void removeAllBeziers();
|
void removeAllBeziers();
|
||||||
|
@ -39,17 +42,20 @@ namespace Hyprutils {
|
||||||
private:
|
private:
|
||||||
std::unordered_map<std::string, Memory::CSharedPointer<CBezierCurve>> m_mBezierCurves;
|
std::unordered_map<std::string, Memory::CSharedPointer<CBezierCurve>> m_mBezierCurves;
|
||||||
|
|
||||||
bool m_bTickScheduled = false;
|
bool m_bTickScheduled = false;
|
||||||
|
uint32_t m_pendingDisconnects = 0;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
Signal::CHyprSignalListener connect;
|
Signal::CHyprSignalListener connect;
|
||||||
Signal::CHyprSignalListener disconnect;
|
Signal::CHyprSignalListener forceDisconnect;
|
||||||
|
Signal::CHyprSignalListener lazyDisconnect;
|
||||||
} m_sListeners;
|
} m_sListeners;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
// Those events are shared between animated vars
|
// Those events are shared between animated vars
|
||||||
Memory::CSharedPointer<Signal::CSignal> connect;
|
Memory::CSharedPointer<Signal::CSignal> connect;
|
||||||
Memory::CSharedPointer<Signal::CSignal> disconnect;
|
Memory::CSharedPointer<Signal::CSignal> forceDisconnect;
|
||||||
|
Memory::CSharedPointer<Signal::CSignal> lazyDisconnect;
|
||||||
} m_sEvents;
|
} m_sEvents;
|
||||||
|
|
||||||
friend class CBaseAnimatedVariable;
|
friend class CBaseAnimatedVariable;
|
||||||
|
|
|
@ -13,8 +13,9 @@ void CBaseAnimatedVariable::create(Hyprutils::Animation::CAnimationManager* pAni
|
||||||
m_Type = typeInfo;
|
m_Type = typeInfo;
|
||||||
m_pSelf = pSelf;
|
m_pSelf = pSelf;
|
||||||
|
|
||||||
m_sEvents.connect = pAnimationManager->m_sEvents.connect;
|
m_sEvents.connect = pAnimationManager->m_sEvents.connect;
|
||||||
m_sEvents.disconnect = pAnimationManager->m_sEvents.disconnect;
|
m_sEvents.forceDisconnect = pAnimationManager->m_sEvents.forceDisconnect;
|
||||||
|
m_sEvents.lazyDisconnect = pAnimationManager->m_sEvents.lazyDisconnect;
|
||||||
|
|
||||||
m_bDummy = false;
|
m_bDummy = false;
|
||||||
}
|
}
|
||||||
|
@ -30,7 +31,7 @@ void CBaseAnimatedVariable::connectToActive() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void CBaseAnimatedVariable::disconnectFromActive() {
|
void CBaseAnimatedVariable::disconnectFromActive() {
|
||||||
if (const auto DISCONNECT = m_sEvents.disconnect.lock())
|
if (const auto DISCONNECT = m_sEvents.forceDisconnect.lock())
|
||||||
DISCONNECT->emit(static_cast<void*>(this));
|
DISCONNECT->emit(static_cast<void*>(this));
|
||||||
|
|
||||||
m_bIsConnectedToActive = false;
|
m_bIsConnectedToActive = false;
|
||||||
|
@ -142,7 +143,9 @@ void CBaseAnimatedVariable::resetAllCallbacks() {
|
||||||
|
|
||||||
void CBaseAnimatedVariable::onAnimationEnd() {
|
void CBaseAnimatedVariable::onAnimationEnd() {
|
||||||
m_bIsBeingAnimated = false;
|
m_bIsBeingAnimated = false;
|
||||||
/* We do not call disconnectFromActive here. The animation manager will remove it on a call to tickDone. */
|
/* lazy disconnect, since this animvar is atill alive */
|
||||||
|
if (const auto DISCONNECT = m_sEvents.lazyDisconnect.lock())
|
||||||
|
DISCONNECT->emit(static_cast<void*>(this));
|
||||||
|
|
||||||
if (m_fEndCallback) {
|
if (m_fEndCallback) {
|
||||||
/* loading m_bRemoveEndAfterRan before calling the callback allows the callback to delete this animation safely if it is false. */
|
/* loading m_bRemoveEndAfterRan before calling the callback allows the callback to delete this animation safely if it is false. */
|
||||||
|
|
|
@ -14,14 +14,16 @@ CAnimationManager::CAnimationManager() {
|
||||||
BEZIER->setup(DEFAULTBEZIERPOINTS);
|
BEZIER->setup(DEFAULTBEZIERPOINTS);
|
||||||
m_mBezierCurves["default"] = BEZIER;
|
m_mBezierCurves["default"] = BEZIER;
|
||||||
|
|
||||||
m_sEvents.connect = makeShared<CSignal>();
|
m_sEvents.connect = makeShared<CSignal>();
|
||||||
m_sEvents.disconnect = makeShared<CSignal>();
|
m_sEvents.forceDisconnect = makeShared<CSignal>();
|
||||||
|
m_sEvents.lazyDisconnect = makeShared<CSignal>();
|
||||||
|
|
||||||
m_sListeners.connect = m_sEvents.connect->registerListener([this](std::any data) { connectVarListener(data); });
|
m_sListeners.connect = m_sEvents.connect->registerListener([this](std::any data) { connectListener(data); });
|
||||||
m_sListeners.disconnect = m_sEvents.disconnect->registerListener([this](std::any data) { disconnectVarListener(data); });
|
m_sListeners.forceDisconnect = m_sEvents.forceDisconnect->registerListener([this](std::any data) { forceDisconnectListener(data); });
|
||||||
|
m_sListeners.lazyDisconnect = m_sEvents.lazyDisconnect->registerListener([this](std::any data) { lazyDisconnectListener(data); });
|
||||||
}
|
}
|
||||||
|
|
||||||
void CAnimationManager::connectVarListener(std::any data) {
|
void CAnimationManager::connectListener(std::any data) {
|
||||||
if (!m_bTickScheduled)
|
if (!m_bTickScheduled)
|
||||||
scheduleTick();
|
scheduleTick();
|
||||||
|
|
||||||
|
@ -32,9 +34,15 @@ void CAnimationManager::connectVarListener(std::any data) {
|
||||||
|
|
||||||
m_vActiveAnimatedVariables.emplace_back(PAV);
|
m_vActiveAnimatedVariables.emplace_back(PAV);
|
||||||
} catch (const std::bad_any_cast&) { return; }
|
} 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::disconnectVarListener(std::any data) {
|
void CAnimationManager::forceDisconnectListener(std::any data) {
|
||||||
try {
|
try {
|
||||||
const auto PAV = std::any_cast<void*>(data);
|
const auto PAV = std::any_cast<void*>(data);
|
||||||
if (!PAV)
|
if (!PAV)
|
||||||
|
@ -44,6 +52,10 @@ void CAnimationManager::disconnectVarListener(std::any data) {
|
||||||
} catch (const std::bad_any_cast&) { return; }
|
} catch (const std::bad_any_cast&) { return; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CAnimationManager::lazyDisconnectListener(std::any data) {
|
||||||
|
m_pendingDisconnects++;
|
||||||
|
}
|
||||||
|
|
||||||
void CAnimationManager::removeAllBeziers() {
|
void CAnimationManager::removeAllBeziers() {
|
||||||
m_mBezierCurves.clear();
|
m_mBezierCurves.clear();
|
||||||
|
|
||||||
|
@ -67,6 +79,10 @@ bool CAnimationManager::shouldTickForNext() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void CAnimationManager::tickDone() {
|
void CAnimationManager::tickDone() {
|
||||||
|
rotateActive();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CAnimationManager::rotateActive() {
|
||||||
std::vector<CWeakPointer<CBaseAnimatedVariable>> active;
|
std::vector<CWeakPointer<CBaseAnimatedVariable>> active;
|
||||||
active.reserve(m_vActiveAnimatedVariables.size()); // avoid reallocations
|
active.reserve(m_vActiveAnimatedVariables.size()); // avoid reallocations
|
||||||
for (auto const& av : m_vActiveAnimatedVariables) {
|
for (auto const& av : m_vActiveAnimatedVariables) {
|
||||||
|
@ -81,6 +97,7 @@ void CAnimationManager::tickDone() {
|
||||||
}
|
}
|
||||||
|
|
||||||
m_vActiveAnimatedVariables = std::move(active);
|
m_vActiveAnimatedVariables = std::move(active);
|
||||||
|
m_pendingDisconnects = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CAnimationManager::bezierExists(const std::string& bezier) {
|
bool CAnimationManager::bezierExists(const std::string& bezier) {
|
||||||
|
|
Loading…
Reference in a new issue