diff options
author | GartoxFR <[email protected]> | 2024-03-02 01:35:17 +0100 |
---|---|---|
committer | GitHub <[email protected]> | 2024-03-02 00:35:17 +0000 |
commit | b2c34404777ea0850f90f4c38f64484f03599d14 (patch) | |
tree | 60f42773d2d606ae2072884cb537c751a7ab4b0f /src/helpers/AnimatedVariable.hpp | |
parent | f115ba94d2ec6e093c94f425535b027bc570185e (diff) | |
download | Hyprland-b2c34404777ea0850f90f4c38f64484f03599d14.tar.gz Hyprland-b2c34404777ea0850f90f4c38f64484f03599d14.zip |
animations: Refactor AnimatedVariable (#4911)
* animation: Refactor AnimatedVariable
This commit decomposes the AnimatedVariable class into a base class
with the common attribute to all variable types and a templated derived
type containing strongly typed info on the type being animated.
Access to the typed version is perfomed using the visitor pattern. A
utility is provided to build a visitor on the fly using lambdas.
Adding a new type to be animated should just be a matter of adding the
typed in the list defined by the ANIMABLE_TYPES macro
The size of the commit is justified by the API change in the
AnimatedVariable class. No more vec(), fl() or col() method but a unified
value() method.
* animation: Remove visitor pattern
* animation: Fix coding style
* animation: Fix coding style
Diffstat (limited to 'src/helpers/AnimatedVariable.hpp')
-rw-r--r-- | src/helpers/AnimatedVariable.hpp | 313 |
1 files changed, 137 insertions, 176 deletions
diff --git a/src/helpers/AnimatedVariable.hpp b/src/helpers/AnimatedVariable.hpp index d87273b3..6efb394b 100644 --- a/src/helpers/AnimatedVariable.hpp +++ b/src/helpers/AnimatedVariable.hpp @@ -3,6 +3,7 @@ #include <functional> #include <any> #include <chrono> +#include <type_traits> #include "Vector2D.hpp" #include "Color.hpp" #include "../macros.hpp" @@ -15,6 +16,30 @@ enum ANIMATEDVARTYPE { AVARTYPE_COLOR }; +// Utility to bind a type with its corresponding ANIMATEDVARTYPE +template <class T> +struct typeToANIMATEDVARTYPE_t { + static constexpr ANIMATEDVARTYPE value = AVARTYPE_INVALID; +}; + +template <> +struct typeToANIMATEDVARTYPE_t<float> { + static constexpr ANIMATEDVARTYPE value = AVARTYPE_FLOAT; +}; + +template <> +struct typeToANIMATEDVARTYPE_t<Vector2D> { + static constexpr ANIMATEDVARTYPE value = AVARTYPE_VECTOR; +}; + +template <> +struct typeToANIMATEDVARTYPE_t<CColor> { + static constexpr ANIMATEDVARTYPE value = AVARTYPE_COLOR; +}; + +template <class T> +inline constexpr ANIMATEDVARTYPE typeToANIMATEDVARTYPE = typeToANIMATEDVARTYPE_t<T>::value; + enum AVARDAMAGEPOLICY { AVARDAMAGE_NONE = -1, AVARDAMAGE_ENTIRE = 0, @@ -28,174 +53,34 @@ struct SLayerSurface; struct SAnimationPropertyConfig; class CHyprRenderer; -class CAnimatedVariable { - public: - CAnimatedVariable(); // dummy var - - void create(ANIMATEDVARTYPE, SAnimationPropertyConfig*, void* pWindow, AVARDAMAGEPOLICY); - void create(ANIMATEDVARTYPE, std::any val, SAnimationPropertyConfig*, void* pWindow, AVARDAMAGEPOLICY); - - CAnimatedVariable(const CAnimatedVariable&) = delete; - CAnimatedVariable(CAnimatedVariable&&) = delete; - CAnimatedVariable& operator=(const CAnimatedVariable&) = delete; - CAnimatedVariable& operator=(CAnimatedVariable&&) = delete; - - ~CAnimatedVariable(); - - void unregister(); - void registerVar(); - - // gets the current vector value (real time) - const Vector2D& vec() const { - return m_vValue; - } - - // gets the current float value (real time) - const float& fl() const { - return m_fValue; - } - - // gets the current color value (real time) - const CColor& col() const { - return m_cValue; - } - - // gets the goal vector value - const Vector2D& goalv() const { - return m_vGoal; - } - - // gets the goal float value - const float& goalf() const { - return m_fGoal; - } - - // gets the goal color value - const CColor& goalc() const { - return m_cGoal; - } - - CAnimatedVariable& operator=(const Vector2D& v) { - if (v == m_vGoal) - return *this; - - m_vGoal = v; - animationBegin = std::chrono::system_clock::now(); - m_vBegun = m_vValue; - - onAnimationBegin(); - - return *this; - } - - CAnimatedVariable& operator=(const float& v) { - if (v == m_fGoal) - return *this; - - m_fGoal = v; - animationBegin = std::chrono::system_clock::now(); - m_fBegun = m_fValue; - - onAnimationBegin(); - - return *this; - } - - CAnimatedVariable& operator=(const CColor& v) { - if (v == m_cGoal) - return *this; - - m_cGoal = v; - animationBegin = std::chrono::system_clock::now(); - m_cBegun = m_cValue; - - onAnimationBegin(); - - return *this; - } - - // Sets the actual stored value, without affecting the goal, but resets the timer - void setValue(const Vector2D& v) { - if (v == m_vValue) - return; - - m_vValue = v; - animationBegin = std::chrono::system_clock::now(); - m_vBegun = m_vValue; - - onAnimationBegin(); - } - - // Sets the actual stored value, without affecting the goal, but resets the timer - void setValue(const float& v) { - if (v == m_fValue) - return; - - m_fValue = v; - animationBegin = std::chrono::system_clock::now(); - m_vBegun = m_vValue; - - onAnimationBegin(); - } - - // Sets the actual stored value, without affecting the goal, but resets the timer - void setValue(const CColor& v) { - if (v == m_cValue) - return; - - m_cValue = v; - animationBegin = std::chrono::system_clock::now(); - m_vBegun = m_vValue; - - onAnimationBegin(); - } - - // Sets the actual value and goal - void setValueAndWarp(const Vector2D& v) { - m_vGoal = v; - warp(); - } +// Utility to define a concept as a list of possible type +template <class T, class... U> +concept OneOf = (... or std::same_as<T, U>); - // Sets the actual value and goal - void setValueAndWarp(const float& v) { - m_fGoal = v; - warp(); - } +// Concept to describe which type can be placed into CAnimatedVariable +// This is mainly to get better errors if we put a type that's not supported +// Otherwise template errors are ugly +template <class T> +concept Animable = OneOf<T, Vector2D, float, CColor>; - // Sets the actual value and goal - void setValueAndWarp(const CColor& v) { - m_cGoal = v; - warp(); - } +class CBaseAnimatedVariable { + public: + CBaseAnimatedVariable(ANIMATEDVARTYPE type); + void create(SAnimationPropertyConfig* pAnimConfig, void* pWindow, AVARDAMAGEPOLICY policy); - // checks if an animation is in progress - inline bool isBeingAnimated() { - return m_bIsBeingAnimated; - } + CBaseAnimatedVariable(const CBaseAnimatedVariable&) = delete; + CBaseAnimatedVariable(CBaseAnimatedVariable&&) = delete; + CBaseAnimatedVariable& operator=(const CBaseAnimatedVariable&) = delete; + CBaseAnimatedVariable& operator=(CBaseAnimatedVariable&&) = delete; - void warp(bool endCallback = true) { - switch (m_eVarType) { - case AVARTYPE_FLOAT: { - m_fValue = m_fGoal; - break; - } - case AVARTYPE_VECTOR: { - m_vValue = m_vGoal; - break; - } - case AVARTYPE_COLOR: { - m_cValue = m_cGoal; - break; - } - default: UNREACHABLE(); - } + virtual ~CBaseAnimatedVariable(); - m_bIsBeingAnimated = false; + void unregister(); + void registerVar(); - if (endCallback) - onAnimationEnd(); - } + virtual void warp(bool endCallback = true) = 0; + // void setConfig(SAnimationPropertyConfig* pConfig) { m_pConfig = pConfig; } @@ -212,6 +97,11 @@ class CAnimatedVariable { /* returns the current curve value */ float getCurveValue(); + // checks if an animation is in progress + inline bool isBeingAnimated() { + return m_bIsBeingAnimated; + } + /* sets a function to be ran when the animation finishes. if an animation is not running, runs instantly. if "remove" is set to true, will remove the callback when ran. */ @@ -245,20 +135,7 @@ class CAnimatedVariable { m_bRemoveEndAfterRan = false; } - private: - Vector2D m_vValue = Vector2D(0, 0); - float m_fValue = 0; - CColor m_cValue; - - Vector2D m_vGoal = Vector2D(0, 0); - float m_fGoal = 0; - CColor m_cGoal; - - Vector2D m_vBegun = Vector2D(0, 0); - float m_fBegun = 0; - CColor m_cBegun; - - // owners + protected: void* m_pWindow = nullptr; void* m_pWorkspace = nullptr; void* m_pLayer = nullptr; @@ -271,8 +148,8 @@ class CAnimatedVariable { std::chrono::system_clock::time_point animationBegin; - ANIMATEDVARTYPE m_eVarType = AVARTYPE_INVALID; AVARDAMAGEPOLICY m_eDamagePolicy = AVARDAMAGE_NONE; + ANIMATEDVARTYPE m_Type; bool m_bRemoveEndAfterRan = true; bool m_bRemoveBeginAfterRan = true; @@ -281,7 +158,9 @@ class CAnimatedVariable { std::function<void(void* thisptr)> m_fUpdateCallback; bool m_bIsConnectedToActive = false; + void connectToActive(); + void disconnectFromActive(); // methods @@ -314,3 +193,85 @@ class CAnimatedVariable { friend struct SLayerSurface; friend class CHyprRenderer; }; + +template <Animable VarType> +class CAnimatedVariable : public CBaseAnimatedVariable { + public: + CAnimatedVariable() : CBaseAnimatedVariable(typeToANIMATEDVARTYPE<VarType>) {} // dummy var + + void create(const VarType& value, SAnimationPropertyConfig* pAnimConfig, void* pWindow, AVARDAMAGEPOLICY policy) { + create(pAnimConfig, pWindow, policy); + m_Value = value; + } + + using CBaseAnimatedVariable::create; + + CAnimatedVariable(const CAnimatedVariable&) = delete; + CAnimatedVariable(CAnimatedVariable&&) = delete; + CAnimatedVariable& operator=(const CAnimatedVariable&) = delete; + CAnimatedVariable& operator=(CAnimatedVariable&&) = delete; + + ~CAnimatedVariable() = default; + + // gets the current vector value (real time) + const VarType& value() const { + return m_Value; + } + + // gets the goal vector value + const VarType& goal() const { + return m_Goal; + } + + CAnimatedVariable& operator=(const VarType& v) { + if (v == m_Goal) + return *this; + + m_Goal = v; + animationBegin = std::chrono::system_clock::now(); + m_Begun = m_Value; + + onAnimationBegin(); + + return *this; + } + + // Sets the actual stored value, without affecting the goal, but resets the timer + void setValue(const VarType& v) { + if (v == m_Value) + return; + + m_Value = v; + animationBegin = std::chrono::system_clock::now(); + m_Begun = m_Value; + + onAnimationBegin(); + } + + // Sets the actual value and goal + void setValueAndWarp(const VarType& v) { + m_Goal = v; + warp(); + } + + void warp(bool endCallback = true) override { + m_Value = m_Goal; + + m_bIsBeingAnimated = false; + + if (endCallback) + onAnimationEnd(); + } + + private: + VarType m_Value{}; + VarType m_Goal{}; + VarType m_Begun{}; + + // owners + + friend class CAnimationManager; + friend class CWorkspace; + friend struct SLayerSurface; + friend class CHyprRenderer; +}; |