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 {
|
||||
Memory::CWeakPointer<Signal::CSignal> connect;
|
||||
Memory::CWeakPointer<Signal::CSignal> disconnect;
|
||||
Memory::CWeakPointer<Signal::CSignal> forceDisconnect;
|
||||
Memory::CWeakPointer<Signal::CSignal> lazyDisconnect;
|
||||
} m_sEvents;
|
||||
|
||||
private:
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#include "../memory/WeakPtr.hpp"
|
||||
#include "../signal/Signal.hpp"
|
||||
|
||||
#include <cstdint>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
|
@ -18,13 +19,15 @@ namespace Hyprutils {
|
|||
virtual ~CAnimationManager() = default;
|
||||
|
||||
void tickDone();
|
||||
void rotateActive();
|
||||
bool shouldTickForNext();
|
||||
|
||||
virtual void scheduleTick() = 0;
|
||||
virtual void onTicked() = 0;
|
||||
|
||||
void connectVarListener(std::any data);
|
||||
void disconnectVarListener(std::any data);
|
||||
void connectListener(std::any data);
|
||||
void lazyDisconnectListener(std::any data);
|
||||
void forceDisconnectListener(std::any data);
|
||||
|
||||
void addBezierWithName(std::string, const Math::Vector2D&, const Math::Vector2D&);
|
||||
void removeAllBeziers();
|
||||
|
@ -39,17 +42,20 @@ namespace Hyprutils {
|
|||
private:
|
||||
std::unordered_map<std::string, Memory::CSharedPointer<CBezierCurve>> m_mBezierCurves;
|
||||
|
||||
bool m_bTickScheduled = false;
|
||||
bool m_bTickScheduled = false;
|
||||
uint32_t m_pendingDisconnects = 0;
|
||||
|
||||
struct {
|
||||
Signal::CHyprSignalListener connect;
|
||||
Signal::CHyprSignalListener disconnect;
|
||||
Signal::CHyprSignalListener forceDisconnect;
|
||||
Signal::CHyprSignalListener lazyDisconnect;
|
||||
} m_sListeners;
|
||||
|
||||
struct {
|
||||
// Those events are shared between animated vars
|
||||
Memory::CSharedPointer<Signal::CSignal> connect;
|
||||
Memory::CSharedPointer<Signal::CSignal> disconnect;
|
||||
Memory::CSharedPointer<Signal::CSignal> forceDisconnect;
|
||||
Memory::CSharedPointer<Signal::CSignal> lazyDisconnect;
|
||||
} m_sEvents;
|
||||
|
||||
friend class CBaseAnimatedVariable;
|
||||
|
|
|
@ -13,8 +13,9 @@ void CBaseAnimatedVariable::create(Hyprutils::Animation::CAnimationManager* pAni
|
|||
m_Type = typeInfo;
|
||||
m_pSelf = pSelf;
|
||||
|
||||
m_sEvents.connect = pAnimationManager->m_sEvents.connect;
|
||||
m_sEvents.disconnect = pAnimationManager->m_sEvents.disconnect;
|
||||
m_sEvents.connect = pAnimationManager->m_sEvents.connect;
|
||||
m_sEvents.forceDisconnect = pAnimationManager->m_sEvents.forceDisconnect;
|
||||
m_sEvents.lazyDisconnect = pAnimationManager->m_sEvents.lazyDisconnect;
|
||||
|
||||
m_bDummy = false;
|
||||
}
|
||||
|
@ -30,7 +31,7 @@ void CBaseAnimatedVariable::connectToActive() {
|
|||
}
|
||||
|
||||
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));
|
||||
|
||||
m_bIsConnectedToActive = false;
|
||||
|
@ -142,7 +143,9 @@ void CBaseAnimatedVariable::resetAllCallbacks() {
|
|||
|
||||
void CBaseAnimatedVariable::onAnimationEnd() {
|
||||
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) {
|
||||
/* 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);
|
||||
m_mBezierCurves["default"] = BEZIER;
|
||||
|
||||
m_sEvents.connect = makeShared<CSignal>();
|
||||
m_sEvents.disconnect = makeShared<CSignal>();
|
||||
m_sEvents.connect = 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.disconnect = m_sEvents.disconnect->registerListener([this](std::any data) { disconnectVarListener(data); });
|
||||
m_sListeners.connect = m_sEvents.connect->registerListener([this](std::any data) { connectListener(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)
|
||||
scheduleTick();
|
||||
|
||||
|
@ -32,9 +34,15 @@ void CAnimationManager::connectVarListener(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::disconnectVarListener(std::any data) {
|
||||
void CAnimationManager::forceDisconnectListener(std::any data) {
|
||||
try {
|
||||
const auto PAV = std::any_cast<void*>(data);
|
||||
if (!PAV)
|
||||
|
@ -44,6 +52,10 @@ void CAnimationManager::disconnectVarListener(std::any data) {
|
|||
} catch (const std::bad_any_cast&) { return; }
|
||||
}
|
||||
|
||||
void CAnimationManager::lazyDisconnectListener(std::any data) {
|
||||
m_pendingDisconnects++;
|
||||
}
|
||||
|
||||
void CAnimationManager::removeAllBeziers() {
|
||||
m_mBezierCurves.clear();
|
||||
|
||||
|
@ -67,6 +79,10 @@ bool CAnimationManager::shouldTickForNext() {
|
|||
}
|
||||
|
||||
void CAnimationManager::tickDone() {
|
||||
rotateActive();
|
||||
}
|
||||
|
||||
void CAnimationManager::rotateActive() {
|
||||
std::vector<CWeakPointer<CBaseAnimatedVariable>> active;
|
||||
active.reserve(m_vActiveAnimatedVariables.size()); // avoid reallocations
|
||||
for (auto const& av : m_vActiveAnimatedVariables) {
|
||||
|
@ -81,6 +97,7 @@ void CAnimationManager::tickDone() {
|
|||
}
|
||||
|
||||
m_vActiveAnimatedVariables = std::move(active);
|
||||
m_pendingDisconnects = 0;
|
||||
}
|
||||
|
||||
bool CAnimationManager::bezierExists(const std::string& bezier) {
|
||||
|
|
Loading…
Reference in a new issue