don't break API, more robust code

This commit is contained in:
Vaxry 2025-01-26 18:24:41 +00:00
parent 06ec9a2398
commit 21dac77625
5 changed files with 69 additions and 51 deletions

View file

@ -4,18 +4,13 @@
#include "../memory/WeakPtr.hpp"
#include "../memory/SharedPtr.hpp"
#include "../signal/Signal.hpp"
#include "AnimationManager.hpp"
#include <functional>
#include <chrono>
namespace Hyprutils {
namespace Animation {
class CAnimationManager;
struct SAnimVarEvents {
Signal::CSignal connect;
Signal::CSignal disconnect;
};
/* A base class for animated variables. */
class CBaseAnimatedVariable {
@ -26,7 +21,7 @@ namespace Hyprutils {
; // m_bDummy = true;
};
void create(int, Memory::CSharedPointer<CBaseAnimatedVariable>, Memory::CSharedPointer<SAnimVarEvents> events);
void create(CAnimationManager*, int, Memory::CSharedPointer<CBaseAnimatedVariable>);
void connectToActive();
void disconnectFromActive();
@ -42,6 +37,7 @@ namespace Hyprutils {
CBaseAnimatedVariable& operator=(const CBaseAnimatedVariable&) = delete;
CBaseAnimatedVariable& operator=(CBaseAnimatedVariable&&) = delete;
//
void setConfig(Memory::CSharedPointer<SAnimationPropertyConfig> pConfig) {
m_pConfig = pConfig;
}
@ -57,9 +53,8 @@ namespace Hyprutils {
/* returns the spent (completion) % */
float getPercent() 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;
/* returns the current curve value. */
float getCurveValue() const;
/* checks if an animation is in progress */
bool isBeingAnimated() const {
@ -90,17 +85,22 @@ namespace Hyprutils {
void onAnimationEnd();
void onAnimationBegin();
/* returns whether the parent CAnimationManager is dead */
bool isAnimationManagerDead() const;
int m_Type = -1;
protected:
friend class CAnimationManager;
CAnimationManager* m_pAnimationManager = nullptr;
bool m_bIsConnectedToActive = false;
bool m_bIsBeingAnimated = false;
Memory::CWeakPointer<CBaseAnimatedVariable> m_pSelf;
Memory::CWeakPointer<SAnimVarEvents> m_events;
Memory::CWeakPointer<CAnimationManager::SAnimationManagerSignals> m_pSignals;
private:
Memory::CWeakPointer<SAnimationPropertyConfig> m_pConfig;
@ -136,13 +136,13 @@ namespace Hyprutils {
public:
CGenericAnimatedVariable() = default;
void create(const int typeInfo, Memory::CSharedPointer<CGenericAnimatedVariable<VarType, AnimationContext>> pSelf, Memory::CSharedPointer<SAnimVarEvents> events,
void create(const int typeInfo, CAnimationManager* pAnimationManager, Memory::CSharedPointer<CGenericAnimatedVariable<VarType, AnimationContext>> pSelf,
const VarType& initialValue) {
m_Begun = initialValue;
m_Value = initialValue;
m_Goal = initialValue;
CBaseAnimatedVariable::create(typeInfo, pSelf, events);
CBaseAnimatedVariable::create(pAnimationManager, typeInfo, pSelf);
}
CGenericAnimatedVariable(const CGenericAnimatedVariable&) = delete;

View file

@ -1,7 +1,6 @@
#pragma once
#include "./BezierCurve.hpp"
#include "./AnimatedVariable.hpp"
#include "../math/Vector2D.hpp"
#include "../memory/WeakPtr.hpp"
#include "../signal/Signal.hpp"
@ -12,6 +11,8 @@
namespace Hyprutils {
namespace Animation {
class CBaseAnimatedVariable;
/* A class for managing bezier curves and variables that are being animated. */
class CAnimationManager {
public:
@ -33,25 +34,30 @@ namespace Hyprutils {
const std::unordered_map<std::string, Memory::CSharedPointer<CBezierCurve>>& getAllBeziers();
Memory::CSharedPointer<SAnimVarEvents> getEvents() const;
struct SAnimationManagerSignals {
Signal::CSignal connect; // WP<CBaseAnimatedVariable>
Signal::CSignal disconnect; // WP<CBaseAnimatedVariable>
};
Memory::CWeakPointer<SAnimationManagerSignals> getSignals() 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;
void connectListener(std::any data);
void disconnectListener(std::any data);
void onConnect(std::any data);
void onDisconnect(std::any data);
struct {
struct SAnimVarListeners {
Signal::CHyprSignalListener connect;
Signal::CHyprSignalListener disconnect;
} m_sListeners;
};
friend class CBaseAnimatedVariable;
Memory::CUniquePointer<SAnimVarListeners> m_listeners;
Memory::CUniquePointer<SAnimationManagerSignals> m_events;
};
}
}

View file

@ -8,28 +8,28 @@ using namespace Hyprutils::Memory;
#define SP CSharedPointer
#define WP CWeakPointer
void CBaseAnimatedVariable::create(int typeInfo, SP<CBaseAnimatedVariable> pSelf, SP<SAnimVarEvents> events) {
void CBaseAnimatedVariable::create(CAnimationManager* pManager, int typeInfo, SP<CBaseAnimatedVariable> pSelf) {
m_Type = typeInfo;
m_pSelf = pSelf;
m_events = events;
m_pAnimationManager = pManager;
m_pSignals = pManager->getSignals();
m_bDummy = false;
}
void CBaseAnimatedVariable::connectToActive() {
if (m_bDummy || m_bIsConnectedToActive)
if (m_bDummy || m_bIsConnectedToActive || isAnimationManagerDead())
return;
if (const auto PEVENTS = m_events.lock()) {
PEVENTS->connect.emit(m_pSelf.lock());
m_pSignals->connect.emit(m_pSelf);
m_bIsConnectedToActive = true;
}
}
void CBaseAnimatedVariable::disconnectFromActive() {
if (const auto PEVENTS = m_events.lock())
PEVENTS->disconnect.emit(static_cast<void*>(this));
if (isAnimationManagerDead())
return;
m_pSignals->disconnect.emit(m_pSelf);
m_bIsConnectedToActive = false;
}
@ -75,8 +75,8 @@ float CBaseAnimatedVariable::getPercent() const {
return 1.f;
}
float CBaseAnimatedVariable::getCurveValue(CAnimationManager* pAnimationManager) const {
if (!m_bIsBeingAnimated || !pAnimationManager)
float CBaseAnimatedVariable::getCurveValue() const {
if (!m_bIsBeingAnimated || isAnimationManagerDead())
return 1.f;
std::string bezierName = "";
@ -86,7 +86,7 @@ float CBaseAnimatedVariable::getCurveValue(CAnimationManager* pAnimationManager)
bezierName = PVALUES->internalBezier;
}
const auto BEZIER = pAnimationManager->getBezier(bezierName);
const auto BEZIER = m_pAnimationManager->getBezier(bezierName);
if (!BEZIER)
return 1.f;
@ -98,7 +98,7 @@ float CBaseAnimatedVariable::getCurveValue(CAnimationManager* pAnimationManager)
}
bool CBaseAnimatedVariable::ok() const {
return m_pConfig && !m_bDummy && !m_events.expired();
return m_pConfig && !m_bDummy && !isAnimationManagerDead();
}
void CBaseAnimatedVariable::onUpdate() {
@ -155,3 +155,7 @@ void CBaseAnimatedVariable::onAnimationBegin() {
m_fBeginCallback = nullptr; // reset
}
}
bool CBaseAnimatedVariable::isAnimationManagerDead() const {
return m_pSignals.expired();
}

View file

@ -1,4 +1,5 @@
#include <hyprutils/animation/AnimationManager.hpp>
#include <hyprutils/animation/AnimatedVariable.hpp>
using namespace Hyprutils::Animation;
using namespace Hyprutils::Math;
@ -6,6 +7,7 @@ using namespace Hyprutils::Memory;
using namespace Hyprutils::Signal;
#define SP CSharedPointer
#define WP CWeakPointer
const std::array<Vector2D, 2> DEFAULTBEZIERPOINTS = {Vector2D(0.0, 0.75), Vector2D(0.15, 1.0)};
@ -14,18 +16,19 @@ CAnimationManager::CAnimationManager() {
BEZIER->setup(DEFAULTBEZIERPOINTS);
m_mBezierCurves["default"] = BEZIER;
m_events = makeShared<SAnimVarEvents>();
m_events = makeUnique<SAnimationManagerSignals>();
m_listeners = makeUnique<SAnimVarListeners>();
m_sListeners.connect = m_events->connect.registerListener([this](std::any data) { connectListener(data); });
m_sListeners.disconnect = m_events->disconnect.registerListener([this](std::any data) { disconnectListener(data); });
m_listeners->connect = m_events->connect.registerListener([this](std::any data) { onConnect(data); });
m_listeners->disconnect = m_events->disconnect.registerListener([this](std::any data) { onDisconnect(data); });
}
void CAnimationManager::connectListener(std::any data) {
void CAnimationManager::onConnect(std::any data) {
if (!m_bTickScheduled)
scheduleTick();
try {
const auto PAV = std::any_cast<SP<CBaseAnimatedVariable>>(data);
const auto PAV = std::any_cast<WP<CBaseAnimatedVariable>>(data);
if (!PAV)
return;
@ -33,13 +36,13 @@ void CAnimationManager::connectListener(std::any data) {
} catch (const std::bad_any_cast&) { return; }
}
void CAnimationManager::disconnectListener(std::any data) {
void CAnimationManager::onDisconnect(std::any data) {
try {
const auto PAV = std::any_cast<void*>(data);
const auto PAV = std::any_cast<WP<CBaseAnimatedVariable>>(data);
if (!PAV)
return;
std::erase_if(m_vActiveAnimatedVariables, [&](const auto& other) { return other.get() == PAV; });
std::erase_if(m_vActiveAnimatedVariables, [&](const auto& other) { return !other || other == PAV; });
} catch (const std::bad_any_cast&) { return; }
}
@ -104,3 +107,7 @@ SP<CBezierCurve> CAnimationManager::getBezier(const std::string& name) {
const std::unordered_map<std::string, SP<CBezierCurve>>& CAnimationManager::getAllBeziers() {
return m_mBezierCurves;
}
CWeakPointer<CAnimationManager::SAnimationManagerSignals> CAnimationManager::getSignals() const {
return m_events;
}

View file

@ -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, PAV, m_events, v);
PAV->create(EAVTYPE, static_cast<CAnimationManager*>(this), PAV, v);
PAV->setConfig(animationTree.getConfig(animationConfigName));
av = std::move(PAV);
}
@ -339,9 +339,9 @@ int main(int argc, char** argv, char** envp) {
// test getCurveValue
*s.m_iA = 0;
EXPECT(s.m_iA->getCurveValue(pAnimationManager.get()), 0.f);
EXPECT(s.m_iA->getCurveValue(), 0.f);
s.m_iA->warp();
EXPECT(s.m_iA->getCurveValue(pAnimationManager.get()), 1.f);
EXPECT(s.m_iA->getCurveValue(), 1.f);
EXPECT(endCallbackRan, 6);
// Test duplicate active anim vars are not allowed
@ -365,6 +365,7 @@ int main(int argc, char** argv, char** envp) {
pAnimationManager->createAnimation(1, a, "default");
*a = 10;
pAnimationManager.reset();
EXPECT(a->isAnimationManagerDead(), true);
a->setValueAndWarp(11);
EXPECT(a->value(), 11);
*a = 12;