Skip to content

Commit

Permalink
animation: forceDisconnect outside of tick() and remove the pointer t…
Browse files Browse the repository at this point in the history
…o the animation manager
  • Loading branch information
PaideiaDilemma committed Jan 26, 2025
1 parent 60dbdc4 commit 1e0392e
Show file tree
Hide file tree
Showing 5 changed files with 58 additions and 56 deletions.
38 changes: 20 additions & 18 deletions include/hyprutils/animation/AnimatedVariable.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ namespace Hyprutils {
; // m_bDummy = true;
};

void create(CAnimationManager*, int, Memory::CSharedPointer<CBaseAnimatedVariable>);
void create(int, Memory::CSharedPointer<CBaseAnimatedVariable>, Memory::CSharedPointer<SAnimVarEvents> events);
void connectToActive();
void disconnectFromActive();

Expand All @@ -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;
Expand All @@ -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 {
Expand Down Expand Up @@ -100,25 +101,21 @@ namespace Hyprutils {

Memory::CWeakPointer<CBaseAnimatedVariable> m_pSelf;

Memory::CWeakPointer<SAnimVarEvents> m_events;

private:
Memory::CWeakPointer<SAnimationPropertyConfig> m_pConfig;

std::chrono::steady_clock::time_point animationBegin;

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<SAnimVarEvents> 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 */
Expand All @@ -140,21 +137,21 @@ namespace Hyprutils {
public:
CGenericAnimatedVariable() = default;

void create(const int typeInfo, CAnimationManager* pAnimationManager, Memory::CSharedPointer<CGenericAnimatedVariable<VarType, AnimationContext>> pSelf,
void create(const int typeInfo, Memory::CSharedPointer<CGenericAnimatedVariable<VarType, AnimationContext>> pSelf, Memory::CSharedPointer<SAnimVarEvents> 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;
CGenericAnimatedVariable(CGenericAnimatedVariable&&) = delete;
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;

Expand All @@ -166,6 +163,11 @@ namespace Hyprutils {

if (endCallback)
onAnimationEnd();

if (forceDisconnect) {
if (const auto PEVENTS = m_events.lock())
PEVENTS->forceDisconnect.emit(static_cast<void*>(this));
}
}

const VarType& value() const {
Expand Down
10 changes: 4 additions & 6 deletions include/hyprutils/animation/AnimationManager.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,26 +33,24 @@ namespace Hyprutils {

const std::unordered_map<std::string, Memory::CSharedPointer<CBezierCurve>>& getAllBeziers();

Memory::CSharedPointer<SAnimVarEvents> getEvents() const;

std::vector<Memory::CWeakPointer<CBaseAnimatedVariable>> m_vActiveAnimatedVariables;
Memory::CSharedPointer<SAnimVarEvents> m_events;

private:
std::unordered_map<std::string, Memory::CSharedPointer<CBezierCurve>> 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<SAnimVarEvents> m_events;

friend class CBaseAnimatedVariable;
};
}
Expand Down
22 changes: 7 additions & 15 deletions src/animation/AnimatedVariable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,11 @@ using namespace Hyprutils::Memory;
#define SP CSharedPointer
#define WP CWeakPointer

void CBaseAnimatedVariable::create(Hyprutils::Animation::CAnimationManager* pAnimationManager, int typeInfo, SP<CBaseAnimatedVariable> pSelf) {
m_pAnimationManager = pAnimationManager;
m_Type = typeInfo;
m_pSelf = pSelf;

m_events = pAnimationManager->m_events;
void CBaseAnimatedVariable::create(int typeInfo, SP<CBaseAnimatedVariable> pSelf, SP<SAnimVarEvents> events) {
m_Type = typeInfo;
m_pSelf = pSelf;

m_events = events;
m_bDummy = false;
}

Expand Down Expand Up @@ -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()) {
Expand All @@ -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;

Expand Down
12 changes: 0 additions & 12 deletions src/animation/AnimationManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -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) {
Expand All @@ -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();

Expand Down Expand Up @@ -95,7 +84,6 @@ void CAnimationManager::rotateActive() {
}

m_vActiveAnimatedVariables = std::move(active);
m_pendingDisconnects = 0;
}

bool CAnimationManager::bezierExists(const std::string& bezier) {
Expand Down
32 changes: 27 additions & 5 deletions tests/animation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand Down Expand Up @@ -93,7 +93,7 @@ class CMyAnimationManager : public CAnimationManager {
constexpr const eAVTypes EAVTYPE = std::is_same_v<VarType, int> ? eAVTypes::INT : eAVTypes::TEST;
const auto PAV = makeShared<CGenericAnimatedVariable<VarType, EmtpyContext>>();

PAV->create(EAVTYPE, static_cast<CAnimationManager*>(this), PAV, v);
PAV->create(EAVTYPE, PAV, m_events, v);
PAV->setConfig(animationTree.getConfig(animationConfigName));
av = std::move(PAV);
}
Expand Down Expand Up @@ -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);
Expand All @@ -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);
}
Expand All @@ -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;
}

0 comments on commit 1e0392e

Please sign in to comment.