aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/helpers/AnimatedVariable.hpp
diff options
context:
space:
mode:
authorGartoxFR <[email protected]>2024-03-02 01:35:17 +0100
committerGitHub <[email protected]>2024-03-02 00:35:17 +0000
commitb2c34404777ea0850f90f4c38f64484f03599d14 (patch)
tree60f42773d2d606ae2072884cb537c751a7ab4b0f /src/helpers/AnimatedVariable.hpp
parentf115ba94d2ec6e093c94f425535b027bc570185e (diff)
downloadHyprland-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.hpp313
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;
+};