mirror of
https://github.com/hyprwm/hyprutils.git
synced 2025-05-12 21:30:36 +01:00
animation: forceDisconnect outside of tick() and remove the pointer to the animation manager
This commit is contained in:
parent
60dbdc46cc
commit
1e0392e711
5 changed files with 58 additions and 56 deletions
|
@ -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();
|
||||
|
||||
|
@ -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<CBaseAnimatedVariable> m_pSelf;
|
||||
|
||||
Memory::CWeakPointer<SAnimVarEvents> m_events;
|
||||
|
||||
private:
|
||||
Memory::CWeakPointer<SAnimationPropertyConfig> 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;
|
||||
bool m_bRemoveEndAfterRan = true;
|
||||
bool m_bRemoveBeginAfterRan = true;
|
||||
|
||||
Memory::CWeakPointer<SAnimVarEvents> m_events;
|
||||
|
||||
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<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;
|
||||
|
@ -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<void*>(this));
|
||||
}
|
||||
}
|
||||
|
||||
const VarType& value() const {
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -77,16 +75,10 @@ float CBaseAnimatedVariable::getPercent() const {
|
|||
return 1.f;
|
||||
}
|
||||
|
||||
float CBaseAnimatedVariable::getCurveValue() const {
|
||||
if (!m_bIsBeingAnimated || !m_pAnimationManager)
|
||||
float CBaseAnimatedVariable::getCurveValue(CAnimationManager* pAnimationManager) const {
|
||||
if (!m_bIsBeingAnimated || !pAnimationManager)
|
||||
return 1.f;
|
||||
|
||||
// Guard against m_pAnimationManager being deleted
|
||||
// TODO: Remove this and m_pAnimationManager
|
||||
if (m_events.expired()) {
|
||||
return 1.f;
|
||||
}
|
||||
|
||||
std::string bezierName = "";
|
||||
if (const auto PCONFIG = m_pConfig.lock()) {
|
||||
const auto PVALUES = PCONFIG->pValues.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;
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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<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);
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue